在WPF中实现全局快捷键功能

在WPF中实现全局快捷键功能

今天写一个小程序中使用到了全局快捷键,找到了我之前写的文章在c#中使用全局快捷键翻了一下,发现它是WinForm版本的,而我现在大部分写WPF程序了,便将其翻译了为WPF版本的了。

static class Hotkey { #region 系统api [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, uint vk); [DllImport("user32.dll")] static extern bool UnregisterHotKey(IntPtr hWnd, int id); #endregion /// <summary> /// 注册快捷键 /// </summary> /// <param name="window">持有快捷键窗口</param> /// <param name="fsModifiers">组合键</param> /// <param name="key">快捷键</param> /// <param name="callBack">回调函数</param> public static void Regist(Window window, HotkeyModifiers fsModifiers, Key key, HotKeyCallBackHanlder callBack) { var hwnd = new WindowInteropHelper(window).Handle; var _hwndSource = HwndSource.FromHwnd(hwnd); _hwndSource.AddHook(WndProc); int id = keyid++; var vk = KeyInterop.VirtualKeyFromKey(key); if (!RegisterHotKey(hwnd, id, fsModifiers, (uint)vk)) throw new Exception("regist hotkey fail."); keymap[id] = callBack; } /// <summary> /// 快捷键消息处理 /// </summary> static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_HOTKEY) { int id = wParam.ToInt32(); if (keymap.TryGetValue(id, out var callback)) { callback(); } } return IntPtr.Zero; } /// <summary> /// 注销快捷键 /// </summary> /// <param name="hWnd">持有快捷键窗口的句柄</param> /// <param name="callBack">回调函数</param> public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack) { foreach (KeyValuePair<int, HotKeyCallBackHanlder> var in keymap) { if (var.Value == callBack) UnregisterHotKey(hWnd, var.Key); } } const int WM_HOTKEY = 0x312; static int keyid = 10; static Dictionary<int, HotKeyCallBackHanlder> keymap = new Dictionary<int, HotKeyCallBackHanlder>(); public delegate void HotKeyCallBackHanlder(); } enum HotkeyModifiers { MOD_ALT = 0x1, MOD_CONTROL = 0x2, MOD_SHIFT = 0x4, MOD_WIN = 0x8 }

代码仍然差不多,使用的方式更加简单一点:

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函数中进行。

到此这篇关于在WPF中实现全局快捷键功能的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持易知道(ezd.cc)。

推荐阅读