[C#.NET][Winform] 全域等級的快捷鍵 (Hot Key)

[C#.NET][Winform] 全域等級的快捷鍵 (Hot Key)

續上篇,[C#.NET][Winform] 表單等級的快捷鍵 (Hot Key),這僅能在表單裡使用的快捷鍵,假若你想要讓應用程式在任何焦點下都能使用快捷鍵,這時候就要利用 RegisterHotKey function 來告知作業系統,我想要用什麼樣的組合鍵當快捷鍵,應用程式生命週期結束的時候再調用UnregisterHotKey function,開始之前我們需要一些準備動作才行。

Win32 API RegisterHotKey function的定義如下:

image_thumb[1]

 

在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
image_thumb[4]

 

還會需要 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

image_thumb[5]

 

接著補上完整的 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);
}

 

觀察執行結果:

image_thumb[7]

 


當應用程式結束時,也別忘了移除註冊 UnregisterHotKey function (Windows)

Win32 API UnregisterHotKey function的定義如下:

image_thumb[10]

 

在C#裡的宣告方式如下:


private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

 

在應用程式關閉時調用UnregisterHotKey就可以了


{
    Boolean success = UnregisterHotKey(this.Handle, this.GetType().GetHashCode());
}

image_thumb[12]

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo