清远公司网站建设东京购物
文章目录
- 命名空间和类
 - 类成员
 - 静态成员
 
- 静态方法
 - `GenerateHotkeyId`
 - `WndProc`
 - `GetWindowHandleAndSource`
 - `Register`
 - `Unregister`
 
- 静态方法(外部调用)
 - `RegisterHotKey` 和 `UnRegisterHotKey`
 
- 委托
 - `HotKeyCallbackHandler`
 
- 枚举
 - `HotkeyModifiers`
 
- 应用示例
 
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;namespace HotKeyModule
{public static class Hotkey{private static readonly Dictionary<int, HotKeyCallbackHandler> keymap = new Dictionary<int, HotKeyCallbackHandler>();private static int nextHotkeyId = 10;private static readonly object keymapLock = new object();private static int GenerateHotkeyId() => Interlocked.Increment(ref nextHotkeyId);// 窗口消息处理private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){const int WM_HOTKEY = 0x0312;if (msg == WM_HOTKEY){int hotkeyId = wParam.ToInt32();if (keymap.TryGetValue(hotkeyId, out var callback)){callback();handled = true;}}return IntPtr.Zero;}// 获取窗口句柄和HwndSourceprivate static (IntPtr hwnd, HwndSource hwndSource) GetWindowHandleAndSource(Window window){var hwnd = new WindowInteropHelper(window).Handle;var hwndSource = HwndSource.FromHwnd(hwnd) ?? throw new InvalidOperationException("Failed to get HwndSource.");return (hwnd, hwndSource);}// 注册热键public static void Register(Window window, HotkeyModifiers modifiers, Key key, HotKeyCallbackHandler callback){var (hwnd, hwndSource) = GetWindowHandleAndSource(window);hwndSource.AddHook(WndProc);int hotkeyId = GenerateHotkeyId();uint vk = (uint)KeyInterop.VirtualKeyFromKey(key);if (!RegisterHotKey(hwnd, hotkeyId, (uint)modifiers, vk)){throw new InvalidOperationException("Failed to register hotkey. Ensure the key combination is not already in use.");}lock (keymapLock){keymap[hotkeyId] = callback;}}// 注销热键public static void Unregister(Window window, HotKeyCallbackHandler callback){var (hwnd, _) = GetWindowHandleAndSource(window);lock (keymapLock){foreach (var kvp in keymap){if (kvp.Value == callback){UnRegisterHotKey(hwnd, kvp.Key);keymap.Remove(kvp.Key);break;}}}}[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]private static extern bool UnRegisterHotKey(IntPtr hWnd, int id);}// 热键回调委托public delegate void HotKeyCallbackHandler();public enum HotkeyModifiers{ALT = 0x0001,CTRL = 0x0002,SHIFT = 0x0004,WIN = 0x0008,CTRL_ALT = CTRL|ALT,CTRL_SHIFT = CTRL | SHIFT,}
}
 
命名空间和类
代码定义在一个名为 HotKeyModule 的命名空间中,其中包含一个静态类 Hotkey,用于管理热键的注册和注销。
类成员
静态成员
-  
keymap:- 类型:
Dictionary<int, HotKeyCallbackHandler> - 用途:存储热键ID和对应的回调函数。
 
 - 类型:
 -  
nextHotkeyId:- 类型:
int - 用途:生成唯一的热键ID。
 - 初始值:10
 
 - 类型:
 -  
keymapLock:- 类型:
object - 用途:用于同步访问 
keymap,确保线程安全。 
 - 类型:
 
静态方法
GenerateHotkeyId
 
- 用途:生成唯一的热键ID。
 - 实现:使用 
Interlocked.Increment方法原子性地增加nextHotkeyId,并返回其新的值。 
WndProc
 
- 用途:处理窗口消息,特别是热键消息。
 - 参数: 
hwnd:窗口句柄msg:消息类型wParam:消息参数lParam:消息参数handled:是否处理了消息
 - 实现: 
- 检查消息类型是否为 
WM_HOTKEY(0x0312)。 - 如果是热键消息,从 
wParam中提取热键ID。 - 在 
keymap中查找对应的回调函数并执行。 - 将 
handled设置为true,表示消息已处理。 
 - 检查消息类型是否为 
 
GetWindowHandleAndSource
 
- 用途:获取窗口句柄和 
HwndSource。 - 参数: 
window:需要处理的Window对象
 - 返回: 
hwnd:窗口句柄hwndSource:与窗口关联的HwndSource
 - 实现: 
- 使用 
WindowInteropHelper获取窗口句柄。 - 使用 
HwndSource.FromHwnd获取HwndSource,如果获取失败则抛出异常。 
 - 使用 
 
Register
 
- 用途:注册热键。
 - 参数: 
window:需要注册热键的Window对象modifiers:热键修饰符(例如CTRL、ALT等)key:热键按键callback:热键触发时的回调函数
 - 实现: 
- 调用 
GetWindowHandleAndSource获取窗口句柄和HwndSource。 - 将 
WndProc注册为窗口消息处理函数。 - 生成唯一的热键ID。
 - 将按键转换为虚拟键码。
 - 调用 
RegisterHotKey函数注册热键,如果注册失败则抛出异常。 - 将热键ID和回调函数添加到 
keymap中。 
 - 调用 
 
Unregister
 
- 用途:注销热键。
 - 参数: 
window:需要注销热键的Window对象callback:需要注销的回调函数
 - 实现: 
- 调用 
GetWindowHandleAndSource获取窗口句柄和HwndSource。 - 升级 
keymapLock,确保线程安全。 - 在 
keymap中查找对应回调函数的热键ID。 - 调用 
UnRegisterHotKey函数注销热键。 - 从 
keymap中移除对应的热键ID和回调函数。 
 - 调用 
 
静态方法(外部调用)
RegisterHotKey 和 UnRegisterHotKey
 
- 用途:注册和注销热键的外部调用。
 - 参数: 
hWnd:窗口句柄id:热键IDfsModifiers:热键修饰符vk:虚拟键码
 - 实现: 
- 使用 
DllImport导入user32.dll中的RegisterHotKey和UnRegisterHotKey函数。 
 - 使用 
 
委托
HotKeyCallbackHandler
 
- 用途:定义热键回调函数的委托。
 - 类型:
public delegate void HotKeyCallbackHandler() 
枚举
HotkeyModifiers
 
- 用途:定义热键修饰符。
 - 成员: 
ALT:0x0001CTRL:0x0002SHIFT:0x0004WIN:0x0008CTRL_ALT:CTRL | ALTCTRL_SHIFT:CTRL | SHIFT
 
应用示例
这段代码是 OnSourceInitialized 方法的重写,用于在窗口的 SourceInitialized 事件触发时注册热键。SourceInitialized 事件在窗口句柄创建后立即触发。
        protected override void OnSourceInitialized(EventArgs e){Hotkey.Register(this, HotkeyModifiers.CTRL, Key.D, () =>{WindowController.Get<FlowView>().Hide();WindowController.Get<MainView>().Show();});Hotkey.Register(this, HotkeyModifiers.CTRL_ALT, Key.D, () =>{Application.Current.Shutdown();});}
