禁用 全局快捷键

在给软件添加快捷键时,经常遇到其它软件或者系统已设置的快捷键,导致功能冲突。

HotKey函数

下面介绍一个user32.dll的RegisterHotKey以及UnregisterHotKey热键处理的函数

注册热键 RegisterHotKey function

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

时间: 2024-10-17 22:00:58

禁用 全局快捷键的相关文章

WPF之全局快捷键

目录 1.WPF快捷键实现方式 2.全局快捷键设置界面 3.Windows API调用 4.注册全局快捷键 5.快捷键触发 WPF快捷键实现方式 WPF快捷键实现主要有自定义快捷键命令和全局快捷键两种方式. 自定义快捷键命令方式是通过KeyBinding为命令绑定快捷键,按键组合可使用“+”进行连接.可以通过Modifiers+Key和Gesture两种方式定义快捷键组合.可以任选其一进行使用,MSDN中建议使用Gesture方式定义以免发生混淆. <Window.InputBindings>

删除 Intel HD Graphics 显卡工具的全局快捷键

Intel的内置显卡工具总是注册全局的快捷键,而且还是常用的(比如 Sublime Text, PyCharm等工具的默认按键绑定),如下: Ctrl + Shift + Up Ctrl + Shift + Down Ctrl + Shift + Left Ctrl + Shift + Right 这些快捷键都是由 igfxHK.exe 注册的,虽然可以在任务栏中点击禁用快捷键,但是由于快捷键是全局注册,其它应用程序仍然不能使用这些快捷键. 虽然使用 taskkill /IM igfxHK.ex

当窗体获得焦点时禁用max快捷键

最近一段时间一直在MXS里用dotnet写界面...写的各种头晕眼花... 过程中遇到了 TextBox 控件输入时 与max快捷键冲突的问题. 解决办法是 用 MaxTextBox 控件替换,今天请教了 徽神~ 才知道原来max有个系统全局变量 enableAccelerators . 可以在窗体获得焦点时禁用max的快捷键.在这里记录一下,顺便感谢徽徽的帮助~

mac 全局快捷键启动应用程序

在Mac中,我们可以通过很多方式来启动应用程序.比如通过鼠标在Finder中双击或者通过Spotlight或者QuickSilver等工具来启动.可是,你有没有想过通过一个快捷键就来启动一个应用程序呢?其实,这个功能并不需要使用第三方软件就可以实现.今天,我们就来介绍一下实现的方法. 1. 运行Automator.在弹出的新建窗口中,选择新建一个"服务". 2. 在编辑页面, 选中"资源库"中的"实用工具",然后在出现的操作中,将"开启

VC/MFC中为程序定义全局快捷键

VC 2010-05-01 18:01:34 阅读287 评论0 字号:大中小 订阅 1.注册快捷键 在初始化函数,如OnInitDialog() 注册快捷键,代码如下: #define HotKeyID1 200 BOOL CDlgCloseProSetup::OnInitDialog() { CDialog::OnInitDialog(); ::RegisterHotKey(m_hWnd, HotKeyID1, NULL, VK_HOME); return TRUE; } RegisterH

mac osx添加全局启动terminal快捷键

虽然有很多第三方工具(Alfred.keyboad Maestro)可以设置全局启动terminal快捷键,但怎么感觉都不如native的好,呵呵,本文就使用mac 自带的Automator来创建一个launch application的服务,然后在系统偏好设置中keyboard设置service的全局快捷键,实践证明挺好用的,步骤如下: 1.create a service dock-->launchpad-->others-->automator-->create a serv

xface禁用control+alt+backspace快捷键

博客主页:http://blog.csdn.net/minna_d idea快捷键太多, 今天写代码i的时候一不小心按下control+alt+backspace,导致X server重启. 在没做好心里准备的情况下重启的代价往往很大,所以我决定禁用重启X server快捷键.google之发现都是ubantu.... 下面主要说说我是怎么找到禁用这个快捷键方式过程吧 1.首先想到的命令是xface+TAB自动提示(因为我 xfce4-keyboard-settings 定义过快捷键) [[em

禁用Win10自带截图工具快捷键(Shift+Win+S)

由于在微信之前,多年使用QQ的缘故,已经习惯了使用Ctrl+Alt+A进行截图,虽然QQ后来还专门提供了TIM(Office-QQ),但仍然渐渐的以微信为主,TIM甚至已经很少登录,之前登录也仅仅是为了使用截图,所以当时觉得可以找个替代者,没必要因为个截图小工具每天登录它,便强迫自己使用Win10自带的截图工具(Snipping Tool),不足之处是没法截图后直接进行编辑做标记等操作,而且总感觉性能不是很好,每次打开都比较卡,最近在截图灰屏状态频繁出现卡顿,不像QQ.TIM.微信的截图只有初次

win8/win7屏蔽ctrl+alt+up/down快捷键的方法

win7屏蔽ctrl+alt+up/down快捷键 Eclipse有个非常好用的快捷键(当然Eclipse好用的快捷键有N个)Ctrl+Alt+UP/DOWN,用于复制当前行的内容,用法很简单,将光标置与要复制的行任意位置,然后按快捷键Ctrl+Alt+UP/DOWN(UP.DOWN分别对应与键盘的上下键按键),将分别在当前行的上一行或者下一行复制一行当前的内容,复制后光标位于复制后的行内. 前阵子机器安装了Win7后,突然发现在Eclipse里面按Ctrl+Alt+DOWN后不是预期的效果,而