我不知疲倦地在网上搜索,并尝试了我遇到的所有可能的解决方案;但无法找到有效的解决方案。
我有一个鼠标挂钩,我已经用了很长时间了,除了当我试图区分向前/向后的鼠标滚轮消息时,它的效果很好。
我看过
mouseData
的成员
MSLLHOOKSTRUCT
结构声明为
Integer
和
UInteger
。不管怎样申报,我都无法获得
HIWORD
对于
WM_MOUSEWHEEL
消息来区分向前和向后,因为当我向前或向后滚动时,值总是相同的。
测试输出
:
车轮向前:
鼠标数据:23074474
HIWORD:352
车轮后部:
鼠标数据:23074474
HIWORD:352
密码
:
<Extension>
Public Function HIWORD(value As Integer) As Integer
Return BitConverter.ToInt16(BitConverter.GetBytes(value), 2)
End Function
Private Shared MouseHookProcedure As HookProcHandler
Private Shared PreviousCallback As Object()
Private Shared ProcPtrSet As Boolean
Private Shared HookHandle As IntPtr
Public Shared Function Start() As Boolean
If HookHandle <> IntPtr.Zero Then Return True
If Not ProcPtrSet Then
ProcPtrSet = True
MouseHookProcedure = New HookProcHandler(AddressOf HookProc)
End If
Using p As Process = Process.GetCurrentProcess()
Using m As ProcessModule = p.MainModule
SetWindowsHookEx(HOOKTYPE.WH_MOUSE, MouseHookProcedure, Pinvoke.Kernel32.Functions.GetModuleHandle(m.ModuleName), Pinvoke.Kernel32.Functions.GetCurrentThreadId)
End Using
End Using
If HookHandle = 0 Then Return False Else Return True
End Function
Public Shared Function [Stop]() As Boolean
Return UnhookWindowsHookEx(HookHandle)
End Function
Private Shared Function HookProc(nCode As Integer, wParam As IntPtr, lParam As IntPtr) As Integer
Dim MSLLHS As MSLLHOOKSTRUCT = Marshal.PtrToStructure(lParam, GetType(MSLLHOOKSTRUCT))
If nCode < 0 Then
Return CallNextHookEx(HookHandle, nCode, wParam, lParam)
Else
' Catch duplicate messages caused by the default behavior of the MouseProc function.
Dim Msg As MouseMessages = CType(wParam, MouseMessages)
If PreviousCallback IsNot Nothing Then
If CType(PreviousCallback(0), MouseMessages) = Msg AndAlso CompairMSLLHOOKSRUCT(PreviousCallback(1), MSLLHS) AndAlso CType(PreviousCallback(2), Date) = Now Then
GoTo NextCallback
End If
End If
' Raise Event
Select Case Msg
Case MouseMessages.MouseWheel
Msg = If(CType(MSLLHS.mouseData, Integer).HIWORD > 0, MouseMessages.MouseWheelForward, MouseMessages.MouseWheelBack)
RaiseEvent Message(Msg MSLLHS)
Case Else
RaiseEvent Message(Msg, MSLLHS)
End Select
PreviousCallback = New Object(2) {CType(wParam, MouseMessages), MSLLHS, Now}
NextCallback:
Try
Return CallNextHookEx(HookHandle, nCode, wParam, lParam)
Catch ex As Exception
Return [Stop]()
End Try
End If
End Function
Private Shared Function CompairMSLLHOOKSRUCT(left As MSLLHOOKSTRUCT, right As MSLLHOOKSTRUCT) As Boolean
Return left.pt.X = right.pt.X AndAlso left.pt.Y = right.pt.Y AndAlso left.mouseData = right.mouseData AndAlso left.flags = right.flags AndAlso left.time = right.time AndAlso left.dwExtraInfo = right.dwExtraInfo
End Function
Pinvoke
:
Public Delegate Function HookProcHandler(nCode As System.Int32, wParam As System.IntPtr, lParam As System.IntPtr) As System.Int32
<DllImport(User32, CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)>
Public Shared Function UnhookWindowsHookEx(idHook As System.IntPtr) As System.Boolean
End Function
<DllImport(User32, CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)>
Public Shared Function SetWindowsHookEx(idHook As System.Int32, lpfn As HookProcHandler, hInstance As System.IntPtr, threadId As System.Int32) As System.IntPtr
End Function
<DllImport(User32, CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall, SetLastError:=True)>
Public Shared Function CallNextHookEx(hhk As System.IntPtr, nCode As System.Int32, wParam As System.IntPtr, lParam As System.IntPtr) As System.IntPtr
End Function
<DllImport(Kernel32, CharSet:=CharSet.Auto, SetLastError:=True)>
Public Shared Function GetModuleHandle(lpModuleName As System.String) As System.IntPtr
End Function
<StructLayout(LayoutKind.Sequential)>
Public Structure MSLLHOOKSTRUCT
Public pt As POINT
Public mouseData As System.UInt32
Public flags As System.UInt32
Public time As System.UInt32
Public dwExtraInfo As System.IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure POINT
Public X As System.Int32
Public Y As System.Int32
Public Sub New(ByVal X As System.Int32, ByVal Y As System.Int32)
Me.X = X
Me.Y = Y
End Sub
End Structure
Public Enum MouseMessages As System.UInt32
MouseWheel = WindowsMessages.WM_MOUSEWHEEL ' &H20E
' Etc...
End Enum
编辑
这不是原问题的延续,也不是附加问题,而是对
solution
由提供
Remy Lebeau
.
对于任何可能需要它的人,
MOUSEHOOKSTRUCTEX
定义如下:
<StructLayout(LayoutKind.Sequential)>
Public Structure MOUSEHOOKSTRUCTEX
Public mouseHookStruct As MOUSEHOOKSTRUCT
Public mouseData As System.Int32
End Structure
非常感谢你们的帮助!