今天写一个小程序中使用到了全局快捷键,找到了我之前写的文章翻了一下,发现它是WinForm版本的,而我现在大部分写WPF程序了,便将其翻译了为WPF版本的了。
1 static class Hotkey 2 { 3 #region 系统api 4 [DllImport("user32.dll")] 5 [return: MarshalAs(UnmanagedType.Bool)] 6 static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, uint vk); 7 8 [DllImport("user32.dll")] 9 static extern bool UnregisterHotKey(IntPtr hWnd, int id);10 #endregion11 12 ///13 /// 注册快捷键14 /// 15 /// 持有快捷键窗口16 /// 组合键17 /// 快捷键18 /// 回调函数19 public static void Regist(Window window, HotkeyModifiers fsModifiers, Key key, HotKeyCallBackHanlder callBack)20 {21 var hwnd = new WindowInteropHelper(window).Handle;22 var _hwndSource = HwndSource.FromHwnd(hwnd);23 _hwndSource.AddHook(WndProc);24 25 int id = keyid++;26 27 var vk = KeyInterop.VirtualKeyFromKey(key);28 if (!RegisterHotKey(hwnd, id, fsModifiers, (uint)vk))29 throw new Exception("regist hotkey fail.");30 keymap[id] = callBack;31 }32 33 ///34 /// 快捷键消息处理 35 /// 36 static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)37 {38 if (msg == WM_HOTKEY)39 {40 int id = wParam.ToInt32();41 if (keymap.TryGetValue(id, out var callback))42 {43 callback();44 }45 }46 return IntPtr.Zero;47 }48 49 ///50 /// 注销快捷键 51 /// 52 /// 持有快捷键窗口的句柄 53 /// 回调函数 54 public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack)55 {56 foreach (KeyValuePairvar in keymap)57 {58 if (var.Value == callBack)59 UnregisterHotKey(hWnd, var.Key);60 }61 }62 63 64 const int WM_HOTKEY = 0x312;65 static int keyid = 10;66 static Dictionary keymap = new Dictionary ();67 68 public delegate void HotKeyCallBackHanlder();69 }70 71 enum HotkeyModifiers72 {73 MOD_ALT = 0x1,74 MOD_CONTROL = 0x2,75 MOD_SHIFT = 0x4,76 MOD_WIN = 0x877 }
代码仍然差不多,使用的方式更加简单一点:
protected override void OnSourceInitialized(EventArgs e){ Hotkey.Regist(this, HotkeyModifiers.MOD_ALT, Key.T, () => { MessageBox.Show("hello"); }); _context = new MainContext(); this.DataContext = _context; _context.Process();}
需要注意的是,调用Hotkey.Regist函数时,需要窗口是分配了句柄的,因此建议在OnLoad事件或OnSourceInitialized函数中进行。