在给软件添加快捷键时,经常遇到其它软件或者系统已设置的快捷键,导致功能冲突。
HotKey函数
下面介绍一个user32.dll的RegisterHotKey以及UnregisterHotKey热键处理的函数
BOOL RegisterHotKey(
HWND hWnd, //响应热键的窗口句柄,如果为空,则注册到调用线程上
Int id, //热键的唯一标识
UINT fsModifiers, //热键的辅助按键
UINT vk //热键的键值
);
解除注册热键UnregisterHotKey function
BOOL WINAPI UnregisterHotKey(
HWND hWnd,//热键注册的窗口
int id//要解除注册的热键ID
);
添加热键注册和注销函数
流程:
Register方法 - 注册user32.dll函数RegisterHotKey以禁用全局键,并在缓存内添加禁用记录
ProcessHotKey方法 - 外界全局键调用时,调用回调函数
1 public class HotKeys
2 {
3 //引入系统API
4 [DllImport("user32.dll")]
5 static extern bool RegisterHotKey(IntPtr hWnd, int id, int modifiers, Keys vk);
6 [DllImport("user32.dll")]
7 static extern bool UnregisterHotKey(IntPtr hWnd, int id);
8
9 //标识-区分不同的快捷键
10 int keyid = 10;
11 //添加key值注册字典,后续调用时有回调处理函数
12 Dictionary<int, HotKeyCallBackHanlder> keyDict = new Dictionary<int, HotKeyCallBackHanlder>();
13 public delegate void HotKeyCallBackHanlder();
14
15 //组合控制键
16 public enum HotkeyModifiers
17 {
18 Alt = 1,
19 Control = 2,
20 Shift = 4,
21 Win = 8
22 }
23
24 //注册快捷键
25 public void Register(IntPtr hWnd, int modifiers, Keys vk, HotKeyCallBackHanlder callBack)
26 {
27 int id = keyid++;
28 if (!RegisterHotKey(hWnd, id, modifiers, vk))
29 throw new Exception("注册失败!");
30 keyDict[id] = callBack;
31 }
32
33 // 注销快捷键
34 public void UnRegister(IntPtr hWnd, HotKeyCallBackHanlder callBack)
35 {
36 foreach (KeyValuePair<int, HotKeyCallBackHanlder> var in keyDict)
37 {
38 if (var.Value == callBack)
39 {
40 UnregisterHotKey(hWnd, var.Key);
41 return;
42 }
43 }
44 }
45
46 // 快捷键消息处理
47 public void ProcessHotKey(Message message)
48 {
49 if (message.Msg == 0x312)
50 {
51 int id = message.WParam.ToInt32();
52 HotKeyCallBackHanlder callback;
53 if (keyDict.TryGetValue(id, out callback))
54 callback();
55 }
56 }
57 //快捷键消息处理
58 public void ProcessHotKey(int msg, IntPtr wParam)
59 {
60 if (msg == 0x312)
61 {
62 int id = wParam.ToInt32();
63 HotKeyCallBackHanlder callback;
64 if (keyDict.TryGetValue(id, out callback))
65 callback();
66 }
67 }
68 }
在上方的HotKeys类中,注册方法Register提供了一个回调函数,后续监听到外界全局键时,可以通知回调函数处理。
参数WParam,是窗口响应时快捷键值,在winform和WPF窗口消息函数中都是有的。
另,组合快捷键内部枚举类HotkeyModifiers,枚举值来自官网文档WM_HOTKEY message
无感知禁用全局快捷键
比如:禁用Ctrl+Alt+1、Ctrl+Alt+2、Ctrl+Alt+3、Ctrl+Alt+4(Windows桌面图标大小的调节快捷键)
1 HotKeys hotKeys = new HotKeys();
2 hotKeys.Register(IntPtr.Zero, (int)HotKeys.HotkeyModifiers.Control + (int)HotKeys.HotkeyModifiers.Alt, Keys.D1, () => { });
3 hotKeys.Register(IntPtr.Zero, (int)HotKeys.HotkeyModifiers.Control + (int)HotKeys.HotkeyModifiers.Alt, Keys.D2, () => { });
4 hotKeys.Register(IntPtr.Zero, (int)HotKeys.HotkeyModifiers.Control + (int)HotKeys.HotkeyModifiers.Alt, Keys.D3, () => { });
5 hotKeys.Register(IntPtr.Zero, (int)HotKeys.HotkeyModifiers.Control + (int)HotKeys.HotkeyModifiers.Alt, Keys.D4, () => { });
注:
- 窗口句柄参数,如果提供空的话,则注册到调用线程上。
- Keys类型在system.windows.Forms程序集下,如果是WPF的Key,可以使用KeyInterop将Wpf键值类型转换为Winform键值再调用此函数。
无感知禁用全局快捷键后回调
如果禁用全局快捷键的同时,外界触发快捷键时需要此程序回调处理,可以添加窗口消息处理:
1. 新建一个类HotKeyHandleWindow,继承自Window
- 窗口样式 - 高宽为0,窗口样式None
- 添加热键注册的调用
- 添加WndProc,处理窗口消息
1 public class HotKeyHandleWindow : Window
2 {
3 private readonly HotKeys _hotKeys = new HotKeys();
4 public HotKeyHandleWindow()
5 {
6 WindowStyle = WindowStyle.None;
7 Width = 0;
8 Height = 0;
9 Loaded += (s, e) =>
10 {
11 //这里注册了Ctrl+Alt+1 快捷键
12 _hotKeys.Register(new WindowInteropHelper(this).Handle,
13 (int)HotKeys.HotkeyModifiers.Control + (int)HotKeys.HotkeyModifiers.Alt, Keys.D1, CallBack);
14 };
15 }
16 protected override void OnSourceInitialized(EventArgs e)
17 {
18 base.OnSourceInitialized(e);
19 var hwndSource = PresentationSource.FromVisual(this) as HwndSource;
20 hwndSource?.AddHook(new HwndSourceHook(WndProc));
21 }
22 public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
23 {
24 //窗口消息处理函数
25 _hotKeys.ProcessHotKey(msg, wParam);
26 return hwnd;
27 }
28 //按下快捷键时被调用的方法
29 public void CallBack()
30 {
31 }
32 }
2. 调用窗口类:
1 var hotKeyHandleWindow = new HotKeyHandleWindow();
2 hotKeyHandleWindow.Show();
3 hotKeyHandleWindow.Hide();
以上有回调响应,但是也是无感知的。
来源:https://www.cnblogs.com/kybs0/p/12558056.html