標籤:ext 檔案 www. 定義 應用 類庫 註冊系統 id重複 ndk
原文:C# 註冊 Windows 熱鍵
閑扯:
前幾日,一個朋友問我如何?按 F1 鍵實現粘貼(Ctrl+V)功能,百度了一個方法,發給他,他看不懂(已經是 Boss 的曾經的碼農),我就做了個Demo給他參考。今日得空,將 Demo 整理一下,做為收集,也給大家一個參考。
Begin:
註冊系統熱鍵,.net 類庫好像沒有提供現成的方法,需要使用系統提供的 DLL。
微軟將許多常用的系統函數都封裝在 user32.dll 中,註冊系統熱鍵使用到的 RegisterHotKey 函數和 UnregisterHotKey 函數也在該 DLL 檔案中,所以我們需要將這兩個方法映射到 C# 類中。下面代碼封裝了這兩個方法,並做一些簡單的封裝,如下:
1 using System; 2 using System.Text; 3 using System.Runtime.InteropServices; 4 using System.Windows.Forms; 5 6 public class SystemHotKey 7 { 8 /// <summary> 9 /// 如果函數執行成功,傳回值不為0。10 /// 如果函數執行失敗,傳回值為0。要得到擴充錯誤資訊,調用GetLastError。11 /// </summary>12 /// <param name="hWnd">要定義熱鍵的視窗的控制代碼</param>13 /// <param name="id">定義熱鍵ID(不能與其它ID重複)</param>14 /// <param name="fsModifiers">標識熱鍵是否在按Alt、Ctrl、Shift、Windows等鍵時才會生效</param>15 /// <param name="vk">定義熱鍵的內容</param>16 /// <returns></returns>17 [DllImport("user32.dll", SetLastError = true)]18 public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);19 20 /// <summary>21 /// 登出熱鍵22 /// </summary>23 /// <param name="hWnd">要取消熱鍵的視窗的控制代碼</param>24 /// <param name="id">要取消熱鍵的ID</param>25 /// <returns></returns>26 [DllImport("user32.dll", SetLastError = true)]27 public static extern bool UnregisterHotKey(IntPtr hWnd, int id);28 29 /// <summary>30 /// 輔助鍵名稱。31 /// Alt, Ctrl, Shift, WindowsKey32 /// </summary>33 [Flags()]34 public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 }35 36 /// <summary>37 /// 註冊熱鍵38 /// </summary>39 /// <param name="hwnd">視窗控制代碼</param>40 /// <param name="hotKey_id">熱鍵ID</param>41 /// <param name="keyModifiers">按鍵組合</param>42 /// <param name="key">熱鍵</param>43 public static void RegHotKey(IntPtr hwnd, int hotKeyId, KeyModifiers keyModifiers, Keys key)44 {45 if (!RegisterHotKey(hwnd, hotKeyId, keyModifiers, key))46 {47 int errorCode = Marshal.GetLastWin32Error();48 if (errorCode == 1409)49 {50 MessageBox.Show("熱鍵被佔用 !");51 }52 else53 {54 MessageBox.Show("註冊熱鍵失敗!錯誤碼:" + errorCode);55 }56 }57 }58 59 /// <summary>60 /// 登出熱鍵61 /// </summary>62 /// <param name="hwnd">視窗控制代碼</param>63 /// <param name="hotKey_id">熱鍵ID</param>64 public static void UnRegHotKey(IntPtr hwnd, int hotKeyId)65 {66 //登出指定的熱鍵67 UnregisterHotKey(hwnd, hotKeyId);68 }69 70 }
(這個類是網上搜到的,這裡借用一下。。。在此對原作者表示感謝!)
上面這個類中,只需要使用兩個靜態方法 RegHotKey 和 UnRegHotKey 來註冊和登出熱鍵即可。
這裡有一點需要注意一下:這兩個方法需要一個視窗的控制代碼來繫結系統熱鍵訊息,也就是說,當使用者按下註冊過的熱鍵以後,系統會將按鍵訊息發送給指定視窗。
RegHotKey 方法有四個參數,第一個是視窗控制代碼,第二個是自訂的熱鍵ID,第三個是按鍵組合,比如Ctrl、Alt、Shift等,如果沒有,就是None,第四個就是指定的熱鍵了。
UnRegHotKey 方法只需要視窗控制代碼和熱鍵ID,就可以將該熱鍵登出。
然後,建立一個表單,在程式碼檢視中添加如下代碼:
private const int WM_HOTKEY = 0x312; //視窗訊息:熱鍵 private const int WM_CREATE = 0x1; //視窗訊息:建立 private const int WM_DESTROY = 0x2; //視窗訊息:銷毀 private const int HotKeyID = 1; //熱鍵ID(自訂) protected override void WndProc(ref Message msg) { base.WndProc(ref msg); switch (msg.Msg) { case WM_HOTKEY: //視窗訊息:熱鍵 int tmpWParam = msg.WParam.ToInt32(); if (tmpWParam == HotKeyID) { System.Windows.Forms.SendKeys.Send("^v"); } break; case WM_CREATE: //視窗訊息:建立 SystemHotKey.RegHotKey(this.Handle, HotKeyID, SystemHotKey.KeyModifiers.None, Keys.F1); break; case WM_DESTROY: //視窗訊息:銷毀 SystemHotKey.UnRegHotKey(this.Handle, HotKeyID); //銷毀熱鍵 break; default: break; } }
在上面代碼中,WM_HOTKEY、WM_CREATE、WM_DESTROY 三個常量的值是系統定義,不用關心。HotKeyID 是自訂的一個數值,用於在註冊了多個熱鍵的時候使用該數值來區分不同熱鍵處理邏輯,系統會在使用者觸發熱鍵時將該值做為參數傳遞給處理常式。
另外,上面代碼中重寫了一個系統方法 WndProc,這個方法叫“視窗過程”(參考百度百科),用於接收處理註冊到該表單上的所有事件,包括表單建立、表單銷毀、系統熱鍵等等。該方法有一個 Message 結構體參數,該參數封裝了 Windows 訊息的一些基本屬性,比如訊息ID、參數等等。
上面代碼在該方法接收到視窗建立訊息的時候註冊熱鍵 F1,並且在接收到視窗銷毀訊息的時候登出該熱鍵,並且在接收到系統熱鍵訊息的時候,根據訊息參數(熱鍵ID)來確認觸發我們想要的動作,比如這裡的類比使用者按下 Ctrl+V 鍵。
最後,運行該程式,就可以在任意應用程式裡使用 F1 鍵完成 Ctrl+V 的效果了。
C# 註冊 Windows 熱鍵