C# 實現全局熱鍵 – 注册热键
續上篇 鍵盤消息鉤子
有時候微軟幫我們做了很多,也想到了很多,那就不要浪費別人一番苦心,好好利用。
先上管理熱鍵的類,示例代碼的註釋是必須的。
class HotKey { #region API [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, Keys vk); [DllImport("user32.dll")] static extern bool UnregisterHotKey(IntPtr hWnd, int id); #endregion /// <summary> /// 組合按鍵 /// </summary> public enum HotkeyModifiers { MOD_ALT = 0x1, MOD_CONTROL = 0x2, MOD_SHIFT = 0x4, MOD_WIN = 0x8 } const int WM_HOTKEY = 0x312; /// <summary> /// 起始值 /// </summary> static int keyid = 1; static Dictionary<int, KeyInfo> keymap = new Dictionary<int, KeyInfo>(); /// <summary> /// 存放熱鍵回調函數和窗口句柄 /// </summary> private struct KeyInfo { public KeyInfo(HotKeyCallBackHanlder callBack, IntPtr Hwnd) { this.CallBack = callBack; this.hWnd = Hwnd; } public HotKeyCallBackHanlder CallBack; public IntPtr hWnd; } public delegate void HotKeyCallBackHanlder(); /// <summary> /// 注册快捷键 /// </summary> /// <param name="hWnd">持有快捷键窗口的句柄</param> /// <param name="fsModifiers">组合键</param> /// <param name="vk">快捷键的虚拟键码</param> /// <param name="callBack">回调函数</param> public static bool Regist(IntPtr hWnd, HotkeyModifiers fsModifiers, Keys vk, HotKeyCallBackHanlder callBack) { int id = keyid; if (!RegisterHotKey(hWnd, id, fsModifiers, vk)) { return false; } keymap[id] = new KeyInfo(callBack, hWnd); Debug.Print("註冊热键:{0}", keyid.ToString()); keyid++; return true; } /// <summary> /// 注销快捷键 /// </summary> /// <param name="hWnd">持有快捷键窗口的句柄</param> /// <param name="callBack">回调函数</param> public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack) { int i = -1; foreach (KeyValuePair<int, KeyInfo> var in keymap) { if (var.Value.hWnd == hWnd && var.Value.CallBack == callBack) UnregisterHotKey(hWnd, var.Key); i = var.Key; break; } Debug.Print("注销热键:{0}", i.ToString()); if (i > -1) { keymap.Remove(i); if (i < keyid) { keyid = i; } } } /// <summary> /// 快捷键消息处理 /// </summary> public static void ProcessHotKey(System.Windows.Forms.Message m) { if (m.Msg == WM_HOTKEY) { int id = m.WParam.ToInt32(); KeyInfo ki; if (keymap.TryGetValue(id, out ki)) { ki.CallBack(); } } } /// <summary> /// 註銷所有熱鍵 /// </summary> public static void UnRegistAll() { foreach (KeyValuePair<int, KeyInfo> var in keymap) { UnregisterHotKey(var.Value.hWnd, var.Key); } } }
裡邊維護熱鍵ID的keyid隨意就好,強迫症的我必須要排好,不能中間缺一個。
對於需要註冊多個熱鍵,必須要有專門的類進行維護,註冊的時候直接調用Regist,註銷單一熱鍵就調用UnRegist。
為了保證程序關閉時註銷所有熱鍵,所以還有個註銷所有熱鍵的功能,以防萬一。
循例也要上調用代碼
//Ctrl+Alt+S bool result = HotKey.Regist(this.Handle, HotKey.HotkeyModifiers.MOD_CONTROL | HotKey.HotkeyModifiers.MOD_ALT, Keys.S, Save); if (result == false) { this.Text = "註冊熱鍵失敗"; } //Ctrl+S result = HotKey.Regist(this.Handle, HotKey.HotkeyModifiers.MOD_CONTROL,Keys.S, Save); if (result == false) { this.Text = "註冊熱鍵失敗"; }
Save就是當用戶按下你所設定按鍵後觸發的回調函數,至於裡面是什麼代碼,自己加個信息框什麼的。
//清除指定窗口句柄下的指定熱鍵,只需要傳入對應的回調函數即可 HotKey.UnRegist(this.Handle, Save); //清除所有熱鍵 HotKey.UnRegistAll();
註冊+管理全局熱鍵就OK了,下一篇文章就說程序內的熱鍵,不是全局。