WPF的热键实现
来源:互联网 发布:知乎 量子通信 骗局 编辑:程序博客网 时间:2024/05/16 05:15
项目开发中,需要实现对于热键的支持,实际上有两种方案来实现,一种是采用WPF的方式,即命令绑定,利用InputBinding实现ICommand的快捷键绑定处理,另一种是调用系统API注册热键的方式.但是如果想要实现全局热键及应用程序级别的热键处理,个人认为第二种方案更为合适.
我的代码中,最初选择的是第一种方案,但是测试过程中发现了一个问题,利用InputBinding的形式来绑定的快捷键处理,作用范围只限于当前的窗口,如果我的程序有很多非模态窗口,显示时,当焦点在不同的窗口切换时,发现快捷键只在定义过InputBinding的窗口中有效.也就是说要想在应用程序级别的范围实现快捷键的响应需要在所有的窗口中去定义InputBinding,然后将其都绑定到同一个Command上.在StackOverflow上,有人提出可以定义Style,在该Style中定义InputBinding,然后将此Style应用于所有的窗口控件中,从而实现应用程序级别的快捷键响应.但是我觉得这样一来程序的耦合性太高了,所以放弃了此种方案.
第二中方案,主要参考了如下文章,主要目的是利用系统级别的API,RegisterHotKey,注册应用程序级别的热键,然后捕获热键消息,定义自己的热键响应函数处理该消息即可.
http://outcoldman.com/en/archive/2010/09/11/register-hotkey-in-system-for-wpf-application/
主要代码如下,首先引入WindowAPI
internal class HotKeyWinApi{ public const int WmHotKey = 0x0312; [DllImport("user32.dll", SetLastError = true)] public static extern bool RegisterHotKey(IntPtr hWnd, int id, ModifierKeys fsModifiers, Keys vk); [DllImport("user32.dll", SetLastError = true)] public static extern bool UnregisterHotKey(IntPtr hWnd, int id);}
然后定义热键类,负责热键的注册和消息监听
public sealed class HotKey : IDisposable{ public event Action<HotKey> HotKeyPressed; private readonly int _id; private bool _isKeyRegistered; readonly IntPtr _handle; public HotKey(ModifierKeys modifierKeys, Keys key, Window window) : this (modifierKeys, key, new WindowInteropHelper(window)) { Contract.Requires(window != null); } public HotKey(ModifierKeys modifierKeys, Keys key, WindowInteropHelper window) : this(modifierKeys, key, window.Handle) { Contract.Requires(window != null); } public HotKey(ModifierKeys modifierKeys, Keys key, IntPtr windowHandle) { Contract.Requires(modifierKeys != ModifierKeys.None || key != Keys.None); Contract.Requires(windowHandle != IntPtr.Zero); Key = key; KeyModifier = modifierKeys; _id = GetHashCode(); _handle = windowHandle; RegisterHotKey(); ComponentDispatcher.ThreadPreprocessMessage += ThreadPreprocessMessageMethod; } ~HotKey() { Dispose(); } public Keys Key { get; private set; } public ModifierKeys KeyModifier { get; private set; } public void RegisterHotKey() { if (Key == Keys.None) return; if (_isKeyRegistered) UnregisterHotKey(); _isKeyRegistered = HotKeyWinApi.RegisterHotKey(_handle, _id, KeyModifier, Key); if (!_isKeyRegistered) throw new ApplicationException("Hotkey already in use"); } public void UnregisterHotKey() { _isKeyRegistered = !HotKeyWinApi.UnregisterHotKey(_handle, _id); } public void Dispose() { ComponentDispatcher.ThreadPreprocessMessage -= ThreadPreprocessMessageMethod; UnregisterHotKey(); } private void ThreadPreprocessMessageMethod(ref MSG msg, ref bool handled) { if (!handled) { if (msg.message == HotKeyWinApi.WmHotKey && (int)(msg.wParam) == _id) { OnHotKeyPressed(); handled = true; } } } private void OnHotKeyPressed() { if (HotKeyPressed != null) HotKeyPressed(this); }}
public partial class MainWindow : Window{ private HotKey _hotkey; public MainWindow() { InitializeComponent(); Loaded += (s, e) => { _hotkey = new HotKey(ModifierKeys.Windows | ModifierKeys.Alt, Keys.Left, this); _hotkey.HotKeyPressed += (k) => Console.Beep(); }; }}
0 0
- WPF的热键实现
- 程序热键的实现
- 实现热键的功能
- 程序热键的实现
- 热键的实现
- WPF窗体程序中实现响应系统热键所用到的键值定义
- VC全局热键的实现
- Qt 全局热键的实现
- wpf 屏蔽热键
- wpf 如何定义热键
- WPF(MVVM) 热键快捷键设置
- 在PB中实现热键的方法
- 实现一个热键注册编辑的类
- 实现一个热键注册编辑的类
- 程序中使用热键的实现
- 在PB中实现热键的方法
- 实现gnome桌面的全局热键
- 一个实现系统全局热键的模块
- 优秀js赏析-乐蜂网
- java.lang.IllegalArgumentException: Illegal character in query at index
- 正确使用 Docker 技术的四项基本原则
- sgu 128
- J-link v8固件修复
- WPF的热键实现
- JS实现AES加密并与PHP互通
- pg内置函数
- 原生广告
- hive alter table (删除某一列)语句
- atitit. orm框架的hibernate 使用SQLQuery createSQLQuery addEntity
- Android背景变暗的PopupWindow 可指定变暗区域
- C++编程命名规范
- 【问题解决】syntax error: unexpected end of file或-bash: ./full_build.sh: /bin/bash^M: bad interpreter: No