J'ai un formulaire, qui agit comme une liste déroulante, que je montre non-modal. J'attache un crochet de la souris au formulaire pour déterminer quand la souris est cliquée hors de lui, de sorte que je sais de le fermer - en définissant Visible = False
. Parce que je veux que le HookProc
gère le dernier clic, je ne peux pas disposer du crochet ou de ma liste déroulante jusqu'à ce que je suis sûr que mon gestionnaire d'événements est revenu à HookProc.Déterminez quand un crochet de la souris a traité le dernier message
Il est un peu difficile à expliquer, mais j'espère que le code ci-dessous fait un peu plus clair: -
//Loop to display the dropdown.
Dim dd as New DropDown
dd.Visible = True
Do While dd.Visible
Application.DoEvents()
NativeMethods.MsgWaitForMultipleObjectsEx(0, IntPtr.Zero, 250, &HFF, 4)
Loop
// I want to dispose dd now, but how can I be sure that e.Handled (See below)
// has been returned to HookProc?
//A handler within dropdown to determine what to do with the mouse click.
Private Sub DropDown_MouseHookClick(ByVal sender As Object, ByVal e As MouseClickEventArgs)
If IWantToCloseTheDropDown Then
e.Handled = True
MyHook.UnHook
Me.Visible = False
End If
// All done, e.Handled is returned to HookProc.
// But which happens first? Will e.Handled arrive at HookProc first, or will
// the form display loop, above, notice that Visible is now False?
End Sub
//The main part of the hooking class.
Public Function MouseHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Dim MyMouseHookStruct As MouseHookStruct = DirectCast(Marshal.PtrToStructure(lParam, GetType(MouseHookStruct)), MouseHookStruct)
If nCode < 0 Then
Return CallNextHookEx(hHook, nCode, wParam, lParam)
Else
Dim handle As Integer = MyMouseHookStruct.hwnd
Dim c As Control = Control.FromHandle(New IntPtr(handle))
If MouseUpOrDown Then
Dim e As MouseHookClickEventArgs
OnMouseClick(e)
If e.Handled Then
Return 1
EndIf
End If
Return CallNextHookEx(hHook, nCode, wParam, lParam)
End If
End Function
J'utilise un crochet de la souris, car il y a deux façons dans le menu déroulant peut être la gauche. L'un est en cliquant dessus (auquel cas je veux qu'il se ferme). Un autre est si la grille des propriétés, qu'elle héberge et sur laquelle j'ai un contrôle limité, ouvre une autre forme - c'est-à-dire un TypeEditor. Dans ce cas, je ne veux pas fermer ma liste déroulante. – Jules
Vous pouvez gérer l'événement PropertyValueChanged sur votre PropertyGrid et rouvrir le menu déroulant lorsque cette valeur particulière change (celle avec TypeEditor). Si l'événement se déclenche, la boîte de dialogue a été fermée et vous pouvez à nouveau ouvrir la liste déroulante. –