續上篇[su_button url="https://akru.plus/archives/282" target="blank" style="flat" background="#2db0ef"]鍵盤消息鉤子[/su_button]
有時候微軟幫我們做了很多,也想到了很多,那就不要浪費別人一番苦心,好好利用。
先上管理熱鍵的類,示例代碼的註釋是必須的。
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了,下一篇文章就說程序內的熱鍵,不是全局。