[C#.NET][Winform] 全域等級的快捷鍵 (Hot Key)
續上篇,[C#.NET][Winform] 表單等級的快捷鍵 (Hot Key),這僅能在表單裡使用的快捷鍵,假若你想要讓應用程式在任何焦點下都能使用快捷鍵,這時候就要利用 RegisterHotKey function 來告知作業系統,我想要用什麼樣的組合鍵當快捷鍵,應用程式生命週期結束的時候再調用UnregisterHotKey function,開始之前我們需要一些準備動作才行。
Win32 API RegisterHotKey function的定義如下:
在C#裡的宣告方式如下:
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
如同 Win32 API 的參數定義,我們會需要 fsModifiers,這在.NET裡對應的是 System.Windows.Input.ModifierKeys,一看到下圖就很能明白它代表的鍵盤是Alt、Ctrl、Shift、Win
還會需要 Virtual-Key Codes (Windows),這在.NET裡對應的是 KeyInterop.VirtualKeyFromKey
工具準備好之後就可以開始實作了。
以下範例是定義 Ctrl+Alt+F5 為全域快捷鍵
{
var modifierKeys = (uint)(System.Windows.Input.ModifierKeys.Alt | System.Windows.Input.ModifierKeys.Control);
var virtualKey = (uint)KeyInterop.VirtualKeyFromKey(System.Windows.Input.Key.F5);
var success = RegisterHotKey(this.Handle, this.GetType().GetHashCode(), modifierKeys, virtualKey);
if (success == true)
{
MessageBox.Show("Success");
}
else
{
MessageBox.Show("Error");
}
}
接下來就覆寫WndProc,[WinForm] Windows 視窗訊息接收 - WndProc,其中的 0x0312 是 WM_HOTKEY,也就是說當我按下全域等級的 Hot Key ,不論你的焦點在何方,就可以進行TODO:1的處理。
{
if (m.Msg == 0x0312)
{
//TODO:1
}
base.WndProc(ref m);
}
根據文件所述,hight word代表的是 Virtual-Key Codes ,low word 則是 fsModifiers
接著補上完整的 WndProc 的處理:
{
if (m.Msg == 0x0312)
{
string binary = System.Convert.ToString(m.LParam.ToInt32(), 2).PadLeft(32, '0');//轉成二進制
var modifiers = (ushort)m.LParam;//Modifiers key code
var vk = (ushort)(m.LParam.ToInt32() >> 16);//virtual key code
var key = KeyInterop.KeyFromVirtualKey(vk);
var modifiersKey = (ModifierKeys)(modifiers);
if ((modifiersKey == (System.Windows.Input.ModifierKeys.Alt | System.Windows.Input.ModifierKeys.Control) && key == Key.F5))
{
MessageBox.Show("ctrl+alt+f5 被按下");
}
}
base.WndProc(ref m);
}
觀察執行結果:
當應用程式結束時,也別忘了移除註冊 UnregisterHotKey function (Windows)
Win32 API UnregisterHotKey function的定義如下:
在C#裡的宣告方式如下:
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
在應用程式關閉時調用UnregisterHotKey就可以了
{
Boolean success = UnregisterHotKey(this.Handle, this.GetType().GetHashCode());
}
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET