C#全局鼠标钩子完整源码
时间: 2023-07-05 21:05:28 浏览: 169
以下是C#全局鼠标钩子的完整源码:
首先,创建一个名为MouseHook的类,实现IMouseHook接口:
```csharp
using System;
using System.Runtime.InteropServices;
namespace MouseHookExample
{
public class MouseHook : IMouseHook
{
private const int WH_MOUSE_LL = 14;
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_RBUTTONDOWN = 0x0204;
private LowLevelMouseProc _proc;
private IntPtr _hookId = IntPtr.Zero;
public event EventHandler<MouseEventArgs> LeftButtonDown;
public event EventHandler<MouseEventArgs> RightButtonDown;
public void Start()
{
_proc = HookCallback;
_hookId = SetHook(_proc);
}
public void Stop()
{
UnhookWindowsHookEx(_hookId);
_hookId = IntPtr.Zero;
}
private IntPtr SetHook(LowLevelMouseProc proc)
{
using (var curProcess = System.Diagnostics.Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && (wParam == (IntPtr)WM_LBUTTONDOWN || wParam == (IntPtr)WM_RBUTTONDOWN))
{
var hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
var args = new MouseEventArgs(hookStruct.pt.x, hookStruct.pt.y);
if (wParam == (IntPtr)WM_LBUTTONDOWN)
{
LeftButtonDown?.Invoke(this, args);
}
else if (wParam == (IntPtr)WM_RBUTTONDOWN)
{
RightButtonDown?.Invoke(this, args);
}
}
return CallNextHookEx(_hookId, nCode, wParam, lParam);
}
private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
}
}
```
接下来,定义一个名为MouseEventArgs的类,用于传递鼠标事件的参数:
```csharp
using System;
namespace MouseHookExample
{
public class MouseEventArgs : EventArgs
{
public int X { get; }
public int Y { get; }
public MouseEventArgs(int x, int y)
{
X = x;
Y = y;
}
}
}
```
最后,定义一个名为IMouseHook的接口,用于规范MouseHook类的实现:
```csharp
using System;
namespace MouseHookExample
{
public interface IMouseHook
{
event EventHandler<MouseEventArgs> LeftButtonDown;
event EventHandler<MouseEventArgs> RightButtonDown;
void Start();
void Stop();
}
}
```
现在,我们可以在其他类中使用该鼠标钩子:
```csharp
using System;
namespace MouseHookExample
{
class Program
{
static void Main(string[] args)
{
var mouseHook = new MouseHook();
mouseHook.LeftButtonDown += (sender, e) => Console.WriteLine($"Left button down at ({e.X}, {e.Y})");
mouseHook.RightButtonDown += (sender, e) => Console.WriteLine($"Right button down at ({e.X}, {e.Y})");
mouseHook.Start();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
mouseHook.Stop();
}
}
}
```
现在,当用户按下鼠标左键或右键时,程序将在控制台中输出相应的信息。
阅读全文