检测两条WM_LBUTTONUP消息之间经过的时间,以确定WM_LBUtterDBLCLK



我正在尝试编写一个LL MouseHook,它可以拦截应用程序的点击,研究我在其他网站上看到的WM_LBUTTONDBLCLK消息似乎无法正常处理,我不知道为什么,但MSDN文档也没有将此消息列为使用这种钩子处理的可用消息之一,正如您在下面的引用中看到的那样:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx

类型:WPARAM

鼠标消息的标识符。

此参数可以是以下消息之一:

WM_LBUTTONDOWN、WM_LBUTTEUP、WM_MOUSEMOVE、WM_MOUSEWHEEL、WM_MOOSEWHEEL、WM_RBUTTONDOWN或WM_RBUTTEUP。

无论如何,我不确定列表是否非常可靠,因为中间按钮没有列出,CAN也会被处理。

出于这个原因,我不确定我是否试图以更好的方式做到这一点,但我正在努力遵循本文建议的解决方案中给出的说明:http://social.msdn.microsoft.com/Forums/vstudio/en-US/d7149a9a-b366-4983-98ff-5bf8875f67ec/wmlbuttondblclk-capturing-global-doubleclick

截获WM_LBUTTONDOWN时,通过GetMessageTime保存其时间或GetTickCount函数。当您收到下一条信息时,请进行比较当前时间与保存的时间。如果差异小于值,则这是一次双击。

问题是,有时双击没有被捕捉到,我在某种程度上做了错误的评估。

有人可以帮我知道我做错了什么,以及如何解决这个问题?

以下是相关代码:

Private Function LowLevelMouseProc(ByVal nCode As Integer,
                                   ByVal wParam As MouseMessages,
                                   ByRef lParam As NativeMethods.MSLLHOOKSTRUCT) As Integer
    Static LeftClickTime As Long = 0L
    If nCode = 0I Then
        Select Case wParam
            Case MouseMessages.WM_LBUTTONDOWN
                RaiseEvent MouseLeftDown(Me, lParam.pt)
            Case MouseMessages.WM_LBUTTONUP
                LeftClickTime = GetMessageTime() - LeftClickTime
                If LeftClickTime < GetDoubleClickTime() Then
                    LeftClickTime = 0
                    RaiseEvent MouseLeftDoubleClick(Me, lParam.pt)
                Else
                    RaiseEvent MouseLeftUp(Me, lParam.pt)
                End If
                Debug.WriteLine(LeftClickTime)
            Case Else
                Exit Select ' Do Nothing
        End Select
        Return 0
    ElseIf nCode < 0I Then
        ' Initialize unmanged memory to hold the 'MSLLHOOKSTRUCT' structure.
        Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lParam))
        Try ' MSDN Documentation: http://msdn.microsoft.com/en-us/library/vstudio/4ca6d5z7%28v=vs.100%29.aspx
            ' Copy the struct to unmanaged memory.
            Marshal.StructureToPtr(lParam, pnt, False)
            ' Return 
            Return NativeMethods.CallNextHookEx(MouseHook, nCode, wParam, pnt)
        Finally
            ' Free the unmanaged memory.
            Marshal.FreeHGlobal(pnt)
        End Try
    Else ' nCode > 0
        Return -1I
    End If
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
Private Shared Function GetMessageTime() As Long
End Function
<DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
Private Shared Function GetDoubleClickTime() As Long
End Function

然后,如果在运行钩子后,我首先单击(LeftDown+LeftUp),然后双击(LeftDown+LeftUp+LeftDown+left Up),则双击不会被解释为双击,而是触发MouseLeftUp事件三次,但另一方面,如果在运行Hook之后,我首先进行了一次双击,则它被正确地检测到,因此MouseLeftDoubleClick事件被触发。

PS:如果有人知道一个更好的解决方案来处理应用程序中的WM_LBUTTONDBLCLK,我真的很感兴趣。

最后我找到了要执行的正确检查:

Case MouseMessages.WM_LBUTTONUP
If LeftClickTime <> 0 Then
    LeftClickTime = (Environment.TickCount() - LeftClickTime)
End If
If (LeftClickTime <> 0) AndAlso (LeftClickTime < GetDoubleClickTime()) Then
    LeftClickTime = 0
    RaiseEvent MouseLeftDoubleClick(Me, lParam.pt)
Else
    LeftClickTime = Environment.TickCount()
    RaiseEvent MouseLeftUp(Me, lParam.pt)
End If

通过这种方式,我在验证双击时没有问题,至少在我测试的情况下是这样,并且我在问题末尾描述的问题消失了。

最新更新