WPF应用如何注册多个全局热键实现模拟鼠标点击功能
实现方案
核心逻辑如下:
- 每个全局热键需要分配唯一的ID值,不可重复
- 多次调用
RegisterHotKey方法分别注册不同的热键组合 - 在消息回调中通过ID区分触发的热键,执行对应逻辑
- 窗口关闭时需要主动注销所有已注册的热键,避免资源残留
完整实现代码
首先添加必要的命名空间引用:
using System.Runtime.InteropServices; using System.Windows.Interop;
在窗口类中添加以下代码:
// 热键唯一标识,每个热键ID不可重复 private const int HOTKEY_ID_CTRL_F1 = 1; private const int HOTKEY_ID_CTRL_F2 = 2; // 修饰键常量:CTRL键 private const uint MOD_CTRL = 0x0002; // 虚拟键码常量 private const uint VK_F1 = 0x70; private const uint VK_F2 = 0x71; // 鼠标事件常量 private const int MOUSEEVENTF_LEFTDOWN = 0x0002; private const int MOUSEEVENTF_LEFTUP = 0x0004; private const int MOUSEEVENTF_RIGHTDOWN = 0x0008; private const int MOUSEEVENTF_RIGHTUP = 0x0010; [DllImport("user32.dll")] public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo); [DllImport("user32.dll")] private static extern bool RegisterHotKey(IntPtr hwnd, int id, uint fsModifiers, uint vk); [DllImport("user32.dll")] private static extern bool UnregisterHotKey(IntPtr hwnd, int id); private HwndSource _source; private IntPtr _windowHandle; protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); var helper = new WindowInteropHelper(this); _windowHandle = helper.Handle; _source = HwndSource.FromHwnd(_windowHandle); _source.AddHook(HwndHook); // 分别注册两个热键 RegisterHotKey(_windowHandle, HOTKEY_ID_CTRL_F1, MOD_CTRL, VK_F1); RegisterHotKey(_windowHandle, HOTKEY_ID_CTRL_F2, MOD_CTRL, VK_F2); } private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { const int WM_HOTKEY = 0x0312; if (msg == WM_HOTKEY) { switch (wParam.ToInt32()) { case HOTKEY_ID_CTRL_F1: // 触发鼠标右键点击 mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); handled = true; break; case HOTKEY_ID_CTRL_F2: // 触发鼠标左键点击 mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); handled = true; break; } } return IntPtr.Zero; } protected override void OnClosed(EventArgs e) { _source.RemoveHook(HwndHook); // 注销所有已注册的热键 UnregisterHotKey(_windowHandle, HOTKEY_ID_CTRL_F1); UnregisterHotKey(_windowHandle, HOTKEY_ID_CTRL_F2); base.OnClosed(e); }
注意事项
- 如果
RegisterHotKey返回false,说明对应热键已被其他程序占用,可自行添加失败处理逻辑 - 如需在指定坐标触发点击,可修改
mouse_event的dx和dy参数传入对应坐标值
内容的提问来源于stack exchange,提问作者zahl
相关产品推荐
相关产品推荐

