我已经设法让这个 C# 代码(不是我自己的!)在 VB.NET 中工作,以在控制台应用程序中实现鼠标挂钩。这是 VB.NET 代码:
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Module Module1
Class InterceptMouse
Private Shared _proc As LowLevelMouseProc = AddressOf HookCallback
Private Shared _hookID As IntPtr = IntPtr.Zero
Public Shared Sub Main()
_hookID = SetHook(_proc)
Application.Run()
UnhookWindowsHookEx(_hookID)
End Sub
Private Shared Function SetHook(proc As LowLevelMouseProc) As IntPtr
Using curProcess As Process = Process.GetCurrentProcess()
Using curModule As ProcessModule = curProcess.MainModule
Return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0)
End Using
End Using
End Function
Private Delegate Function LowLevelMouseProc(nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
Private Shared Function HookCallback(nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
Dim MouseSetting As Integer = MouseMessages.WM_LBUTTONDOWN
Dim hookStruct As MSLLHOOKSTRUCT
If nCode >= 0 AndAlso MouseSetting = CType(wParam, MouseMessages) Then
hookStruct = CType(Marshal.PtrToStructure(lParam, GetType(MSLLHOOKSTRUCT)), MSLLHOOKSTRUCT)
Console.WriteLine(hookStruct.pt.x & ", " & hookStruct.pt.y)
End If
Dim pt As New POINT
pt.x = hookStruct.pt.x
pt.y = hookStruct.pt.y
MouseCoordinates.Add(pt)
Return CallNextHookEx(_hookID, nCode, wParam, lParam)
End Function
Private Const WH_MOUSE_LL As Integer = 14
Private Enum MouseMessages
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_MOUSEMOVE = &H200
WM_MOUSEWHEEL = &H20A
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
End Enum
<StructLayout(LayoutKind.Sequential)> _
Public Structure POINT
Public x As Integer
Public y As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure MSLLHOOKSTRUCT
Public pt As POINT
Public mouseData As UInteger
Public flags As UInteger
Public time As UInteger
Public dwExtraInfo As IntPtr
End Structure
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function SetWindowsHookEx(idHook As Integer, lpfn As LowLevelMouseProc, hMod As IntPtr, dwThreadId As UInteger) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function UnhookWindowsHookEx(hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function CallNextHookEx(hhk As IntPtr, nCode As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function GetModuleHandle(lpModuleName As String) As IntPtr
End Function
End Class
然后我从 Sub Main 调用它:
Sub Main()
InterceptMouse.Main()
End Sub
但是,当我调试它时,它转到 Application.Run() 行并且它没有前进到下一行,所以我看不到它在幕后做了什么。然后它等待用户输入并在控制台上返回整数坐标。这不是我想要它做的。我想让这段代码在另一个函数或后台工作人员中运行,每当它收到鼠标点击时将坐标传递给主线程,以便它可以处理其余的。问题是,这段代码对于我的理解水平来说太复杂了,我真的不知道它是如何工作的。如果我至少可以设法让控制台在用户单击时返回鼠标坐标,我应该能够忽略它并从那里处理其余代码。