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

发布于 2024-08-11 06:38:32 字数 1839 浏览 7 评论 0原文

我有一个表单,其作用类似于下拉菜单,我显示非模式。我将鼠标挂钩附加到表单上,以确定何时从其中单击鼠标,以便我知道通过设置 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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

贩梦商人 2024-08-18 06:38:32

为什么不直接处理焦点事件呢? Form_LostFocus 会告诉您他们何时聚焦于另一个控件/表单。那时您可以隐藏您的表单。

鼠标钩子对于检测您的表单是否具有焦点似乎有点过分了。

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.

寒江雪… 2024-08-18 06:38:32

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

您不应该需要任何本机来处理 WinForms。此外,整个代码都会被垃圾收集,因此您do不必担心删除挂钩,

您可能需要查看form.deactivate 事件

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文