C# 注册全局热键(快捷键)

准备

先引入动态链接库

using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

正式开整

创建一个类

class HotKey
{
}

引入非托管动态链接库

[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);
//注册热键
//hWnd是窗口句柄, id是热键的ID, vk是按键
//fsModifiers是热键种类(Ctrl,Shift...)这里也可以换成int,为了方便写代码就写一个枚举

[DllImport("user32.dll"]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
//注销热键
public enum KeyModifiers 
{
    None = 0,
    Alt = 1,
    Ctrl = 2,
    Shift = 4,
    WindowsKey = 8
    /*
    前面几个都是基础键,你会发现对应的数字不连续, 那是因为还有组合键, 比如 Ctrl+Shift
    组合键对应的数是多个基础键的和, 比如 Ctrl(2)+Shift(4) = 6
    这里没有给出的组合方式可以自己定义
    */
}

定义一个结构体来储存热键信息

struct Keyinfo 
{
    public HotKeyCallbackHandler Callback;
    public IntPtr hWnd;

    public Keyinfo (HotKeyCallbackHandler callback, IntPtr Hwnd) {
        this.Callback = callback;
        this.hWnd = Hwnd;
    }
}
//其中 HotKeyCallbackHandler 是委托, 回调快捷键处理方法
public delegate void HotKeyCallbackHandler();
//为了把Keyinfo和id(定义一个全局变量int KeyID初始值随意)对应起来,定义一个字典
static Dictionary<int, Keyinfo> keymap = new Dictionary<int, Keyinfo>();

为了方便维护写一个注册热键的方法

public bool Register (IntPtr hWnd, KeyModifiers fsModifiers, Keys vk, HotKeyCallbackHandler callBack) 
{
    if (!RegisterHotKey (hWnd, KeyID, fsModifiers, vk)) 
    {
        return false;
    }
    keymap[KeyID] = new Keyinfo (callBack, hWnd);
    KeyID++;
    return true;
}

//这个是处理热键的方法
public static void ProcessHotKey (System.Windows.Forms.Message m) 
{
    if (m.Msg == 0x312) //0x312是十六进制也可以直接786
    {
        int id = m.WParam.ToInt32 ();
        Keyinfo ki;
        if (keymap.TryGetValue (id, out ki)) 
        {
            ki.Callback ();
        }
    }
}

基本上就写完了, 注销热键自己搞搞就行了
下面调用一下

HotKey hotkey = new HotKey();

private void Form1_Load (object sender, EventArgs e) 
{
    if (!hotkey.Register (Handle, HotKey.KeyModifiers.CS, Keys.W, Function)) 
    {
        MessageBox.Show ("注册失败");
    }
}

//这个方法是处理Windows消息的
protected override void WndProc (ref Message m) 
{
    HotKey.ProcessHotKey (m);
    base.WndProc (ref m);
}

public void Function () 
{
    MessageBox.Show ("你按下了快捷键");
}

我不是太懂委托, 不知道这样写对不对, 如果有问题在下面给我留言

最后

下面放一下整个 HotKey 类, 补充一下上面遗漏的地方

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace HotKey
{
    public class HotKey
    {
        int KeyID = 0;

        /// <summary>
        /// 数值相加即组合键 例:Ctrl(2)+Shift(4)=6
        /// </summary>
        [Flags]
        public enum KeyModifiers
        {
            None = 0,
            Alt = 1,
            Ctrl = 2,
            Shift = 4,
            CS = 6,
            WindowsKey = 8,
        }

        [DllImport("user32.dll")]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, Keys vk);

        [DllImport("user32.dll")]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        public delegate void HotKeyCallbackHandler();

        static Dictionary<int, Keyinfo> keymap = new Dictionary<int, Keyinfo>();

        struct Keyinfo
        {
            public HotKeyCallbackHandler Callback;
            public IntPtr hWnd;

            public Keyinfo(HotKeyCallbackHandler callback, IntPtr Hwnd)
            {
                this.Callback = callback;
                this.hWnd = Hwnd;
            }
        }

        public bool Register(IntPtr hWnd, KeyModifiers fsModifiers, Keys vk, HotKeyCallbackHandler callBack)
        {
            if (!RegisterHotKey(hWnd, KeyID, fsModifiers, vk))
            {
                return false;
            }
            keymap[KeyID] = new Keyinfo(callBack, hWnd);
            KeyID++;
            return true;
        }

        public static void ProcessHotKey(System.Windows.Forms.Message m)
        {
            if (m.Msg == 0x312)
            {
                int id = m.WParam.ToInt32();
                Keyinfo ki;
                if (keymap.TryGetValue(id, out ki))
                {
                    ki.Callback();
                }
            }
        }
    }
}
暂无评论

发送评论 编辑评论


				
上一篇
下一篇