C# 全局热键

定义类

public static extern bool RegisterHotKey() 这个函数用于注册热键。
由于这个函数需要引用 user32.dll 动态链接库后才能使用,并且user32.dll 是非托管代码,不能用命名空间的方式直接引用,所以需要用 DllImport 进行引入后才能使用。

于是在函数前面需要加上
[DllImport("user32.dll", SetLastError = true)]这行语句。

public static extern bool UnregisterHotKey()这个函数用于注销热键,同理也需要用DllImport引用user32.dll后才能使用。

internal class GlobalHotkey
{
    public const int MOD_ALT = 0x0001;    // Alt键
    public const int MOD_CTRL = 0x0002;   // Ctrl键
    public const int MOD_SHIFT = 0x0004;  // Shift键
    public const int MOD_WIN = 0x0008;    // Windows键
    private const int WM_HOTKEY = 0x0312;
    private Action<object, EventArgs> hotkeyAction;
    private int id;
    private IntPtr hWnd;
    [DllImport("user32.dll")]
    private static extern bool RegisterHotKey(
        IntPtr hWnd,                //要定义热键的窗口的句柄
        int id,                     //定义热键ID(不能与其它ID重复)
        int fsModifiers,            //表示是否在按Alt、Ctrl、Shift、Windows等键时才会生效
        Keys vk                     //定义热键
        );
    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(
        IntPtr hWnd,                //要取消热键的窗口的句柄
        int id                      //要取消热键的ID
        );
    public GlobalHotkey(IntPtr hWnd, Keys key, int modifier, Action<object, EventArgs> action)
    {
        this.hWnd = hWnd;
        hotkeyAction = action;
        id = this.GetHashCode();
        RegisterHotKey(hWnd, id, modifier, key);
        Application.AddMessageFilter(new MessageFilter(this));
    }
    public void Unregister()
    {
        UnregisterHotKey(hWnd, id);
    }
    private class MessageFilter : IMessageFilter
    {
        private GlobalHotkey hotkey;
        public MessageFilter(GlobalHotkey hotkey)
        {
            this.hotkey = hotkey;
        }
        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == WM_HOTKEY && (int)m.WParam == hotkey.id)
            {
                hotkey.hotkeyAction(null, EventArgs.Empty);
                return true;
            }
            return false;
        }
    }
}

使用


在 Form 类的构造方法增加下面代码:

// 注册全局热键 (Ctrl + Alt + 0) 并定义触发时要执行的操作
new GlobalHotkey(Handle,Keys.D0, GlobalHotkey.MOD_CTRL| GlobalHotkey.MOD_ALT, (s, e) =>
{
    MessageBox.Show("全局热键按下!");
});

参考:
https://blog.csdn.net/simpleshao/article/details/90755120
https://blog.csdn.net/lijingguang/article/details/134272419