确定鼠标挂钩何时处理了最后一条消息

时间:2009-11-16 14:39:58

标签: .net vb.net winforms mouse-hook

我有一个表单,就像一个下拉菜单,我显示非模态。我在表单上附加一个鼠标钩子,以确定何时单击鼠标,以便我知道关闭它 - 通过设置Visible = False

因为我希望HookProc处理最后一次点击,所以在我确定我的事件处理程序已经返回到HookProc之前,我无法处理Hook或我的Dropdown。

这有点难以解释,但我希望下面的代码能让它更清晰: -

//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

2 个答案:

答案 0 :(得分:0)

为什么不处理焦点事件? Form_LostFocus将告诉您何时关注另一个控件/表单。此时,您可以隐藏表单。

鼠标钩子似乎有点过分,无法检测你的表格是否有焦点。

答案 1 :(得分:0)

您正在绕过.NET机制来处理Windows事件

你不应该需要任何原生的东西来处理WinForms。整个代码也是垃圾收集所以你不应该担心删除钩子

您可能希望查看form.deactivate事件