开发者

Determine when a mouse hook has handled the last message

I have a form, that acts like a drop-down, that I display non-modal. I attach a mouse hook to the form to determine when the mouse is clicked out of it, so that I know to close it - by setting Visible = False.

Because I want the HookProc to handle the last click, I can't dispose the Hook or my Dropdown until I'm sure that my event handler has returned to the HookProc.

It's a bit hard to explain, but I hope the code below makes it a little clearer:-

//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 开发者_如何学PythonObject, 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


Why not just handle the focus events? Form_LostFocus will tell you when they focus on another control/form. At that point you can hide your form.

A mouse hook seems like overkill for detecting if your form has focus or not.


You are bypassing .NET mechanisms to handle windows events

You should not need anything native to deal with WinForms. Also the whole code is garbage collected so you do SHOULD not have to worry about deleting hooks

You might want to look at the form.deactivate event

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜