c# 快捷键模块
文章目录
- 命名空间和类
- 类成员
- 静态成员
- 静态方法
- `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();});}
相关文章:
c# 快捷键模块
文章目录 命名空间和类类成员静态成员 静态方法GenerateHotkeyIdWndProcGetWindowHandleAndSourceRegisterUnregister 静态方法(外部调用)RegisterHotKey 和 UnRegisterHotKey 委托HotKeyCallbackHandler 枚举HotkeyModifiers 应用示例 using System; us…...
【笔记】增值税计算笔记
增值税计算笔记 设 进价为 α \alpha α元 出价为 α τ \alpha\tau ατ元 增值税率为 r r r ∵ { 进 项 税 α 1 r r 销 项 税 α τ 1 r r 增 值 税 销 项 税 − 进 项 税 ∴ 增 值 税 α ( τ − 1 ) r 1 r \because \left\{ \begin{aligned}进项税 &\frac{…...
请解释 JavaScript 中的闭包,以及它的优缺点和常见使用场景?
闭包(Closure)是什么? 闭包是JavaScript中的一个重要概念,指的是一个函数能够记住并访问它的词法作用域,即使这个函数在其词法作用域之外执行。 换句话说,闭包使得函数可以“记住”它被创建时的环境。 闭…...
SpringBoot 集成 Caffeine 实现本地缓存
目录 1、Caffeine 简介 1.1、Caffeine 简介1.2、对比 Guava cache 的性能主要优化项1.3、常见的缓存淘汰算法1.4、SpringBoot 集成 Caffeine 两种方式 2、SpringBoot 集成 Caffeine 方式一 2.1、缓存加载策略 2.1.1、手动加载2.1.2、自动加载【Loading Cache】2.1.3、异步加载…...
druid连接池参数配置
最近发现生产环境经常有数据库连接超时的问题,排查发现是druid连接池参数设置不合理导致 总结问题如下: 为了防止僵尸连接,k8s ipvs做了连接超时限制,如果TCP连接闲置超过900s(15分钟),客户端再尝试通过这个连接去发起…...
【OceanBase】通过 OceanBase 的向量检索技术构建图搜图应用
文章目录 一、向量检索概述1.1 关键概念① 非结构化数据② 向量③ 向量嵌入(Embedding)④ 向量相似性检索 1.2 应用场景 二、向量检索核心功能三、图搜图架构四、操作步骤4.1 使用 Docker 部署 OceanBase 数据库4.2 测试OceanBase数据库连通性4.3 开启数据库向量检索功能4.4 克…...
Linux 安装运行gatk的教程
1.下载安装 wget https://github.com/broadinstitute/gatk/releases/download/4.1.8.1/gatk-4.1.8.1.zip2.解压 unzip *.zip3.查看 gatk --help 如下显示表示安装成功: 注意:仅限在该包所在位置的路径下能使用...
什么是unit l2 norm
1. L2 Norm 定义 L2 norm(或称欧几里得范数)是用来衡量一个向量的“长度”或“大小”的一种方式。在 n 维空间中,给定一个向量V(V1,V2,…,Vn),其 L2 norm 定义为: 也可以理解为该向量与原点之间的欧几里得距离。 2…...
手写顺序流程图组件
效果图 完整代码 <template><div><div class"container" :style"{ width: ${spacingX * (colNum - 1) itemWidth * colNum}px }"><divv-for"(item, i) in recordList":key"i"class"list-box":style&…...
适配器模式概述
大体介绍 适配器模式(Adapter Pattern)是一种结构型设计模式,其核心目的是通过提供一个适配器类来使得原本接口不兼容的类可以一起工作。它通过将一个类的接口转换成客户端所期望的接口,使得原本因接口不兼容而无法一起工作的类可…...
Logo设计免费生成器:轻松设计个性化标志
在当今这个信息爆炸的时代,一个好的Logo标志已经成为品牌和企业的名片。它不仅是品牌的象征,也是企业文化和价值观的体现。然而,很多初创企业或小型团队往往因为预算有限,无法请专业的设计师来打造专属的Logo。这时候,…...
智能停车场车牌识别计费系统
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…...
谷歌开通第三方平台OAuth登录及Java对接步骤
调研起因: 当然还是因为手头的海外项目,用户注册通常要用邮箱,正常流程需要给用户邮箱发送验证码,再让用户输入密码进行注册。 为了简化流程,让用户使用谷歌邮箱一键完成注册或登录, 我们直接获取谷歌邮箱、…...
人体:精妙绝伦的生命之躯
人体:精妙绝伦的生命之躯 在浩瀚宇宙中,人体犹如一颗璀璨的明珠,是自然界最伟大的杰作之一。它是一个高度复杂且精妙绝伦的有机系统,承载着生命的奥秘与奇迹,展现出令人惊叹的适应性、协调性和自我修复能力。从微观的…...
python的urllib模块和http模块
1.python的urllib库用于操作网页,并对网页内容进行处理 urllib包有如下模块: urllib.request:打开和读取URL urllib.error: 包含urllib.request抛出的异常 urllib.parse: 解析URL urllib.robotparser࿱…...
Java [后端] 开发日常记录(1)
目录 1、常用的注解 2、对字符串的处理 3、对JSON串的处理 -- The End -- 详细如下: 1、常用的注解 若返回的字段中有NUll,则不返回 JsonInclude(value JsonInclude.Include.NON_NULL) //在实体类中添加这个注解 JsonInclude(JsonInclude.Include.NON…...
jetbrain 安装 copilot
问题一:Sign in failed. Reason: Request signInInitiate failed with message: Request to /github.com/login/device/code> timed out after 30000ms, request id: 11, error code: -32603 解决方案: 参考资料:https://github.com/orgs/…...
万里数据库GreatSQL监控解析
GreatSQL是MySQL的一个分支,专注于提升MGR(MySQL Group Replication)的可靠性及性能。乐维监控平台可以有效地监控GreatSQL,帮助用户及时发现并解决潜在的性能问题。 通过在GreatSQL服务器上安装监控代理,收集数据库性…...
OpenCV-Python实战(9)——滤波降噪
一、均值滤波器 cv2.blur() img cv2.blur(src*,ksize*,anchor*,borderType*)img:目标图像。 src:原始图像。 ksize:滤波核大小,(width,height)。 anchor:滤波核锚点,…...
Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击
Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集DTA介绍算法流程 DTA代码实现DTA算法实现攻击效果 代码汇总dta.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器: Pytorch | 从零构建AlexNet对CIFAR10进行分类 Pytorch | 从零构建…...
安卓开发工程师(无人售卖机方向):核心技术解析与实践指南
引言:智能零售浪潮下的安卓开发新机遇 随着物联网(IoT)技术、移动支付、人工智能等技术的飞速发展与深度融合,无人零售业态正经历一场深刻的变革。无人售卖机(或称自动售货机)作为其中的典型代表,已从简单的投币式机械装置,演变为集成了多种传感器、支付模块、通信模块、…...
2026届最火的六大降AI率神器实际效果
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 要是针对知网那AI检测系统而言,要想降低文本被识别成是AI生成的概率,…...
RTX4090D优化版Qwen3-32B+OpenClaw实战:低成本构建个人AI工作流
RTX4090D优化版Qwen3-32BOpenClaw实战:低成本构建个人AI工作流 1. 为什么选择本地部署大模型OpenClaw组合 去年我开始尝试用AI自动化处理日常工作,最初直接调用公有云API,但很快遇到三个痛点:一是敏感文件不敢上传第三方服务&am…...
TEKLauncher:如何通过三重技术架构重新定义《方舟:生存进化》的游戏管理体验
TEKLauncher:如何通过三重技术架构重新定义《方舟:生存进化》的游戏管理体验 【免费下载链接】TEKLauncher Launcher for ARK: Survival Evolved 项目地址: https://gitcode.com/gh_mirrors/te/TEKLauncher TEKLauncher是一个专为《方舟ÿ…...
云优化 SEO 软件的内容优化功能有哪些
云优化 SEO 软件的内容优化功能有哪些 在当今的数字化时代,网站的流量和排名直接关系到企业的知名度和市场竞争力。而在这其中,云优化 SEO 软件的内容优化功能起到了至关重要的作用。云优化 SEO 软件的内容优化功能具体有哪些呢?本文将详细探…...
书匠策AI:学术江湖里的“论文剑客”,助你披荆斩棘!
书匠策AI官网:www.shujiangce.com | 微信公众号搜一搜:书匠策AI 在学术的江湖里,写期刊论文就像是一场“闯关游戏”——选题、查文献、搭框架、写内容、调格式……每一关都充满挑战,稍有不慎就可能“Game Over”。但别怕…...
数聚智连转战港交所:年营收16亿 净利4340万 蓝标与险峰是股东
雷递网 雷建平 4月2日北京数聚智连科技股份有限公司(简称:“数聚智连”)日前递交招股书,准备在港交所上市。数聚智连曾向深交所创业板递交招股书,计划募资8亿元,最终IPO被终止,此番是数聚智连转…...
Blender 3MF插件:重塑3D打印数据流转的技术突破
Blender 3MF插件:重塑3D打印数据流转的技术突破 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 一、问题导入:3D打印数据传递的行业痛点与解决方案…...
FreeCAD钣金实战:从零到一,用SheetMetal工作台搞定Z型固定片设计与展开
1. 钣金设计与FreeCAD SheetMetal工作台入门 钣金件在机械设计中无处不在,从机箱外壳到支架固定片,几乎每个DIY项目都会用到。传统手工绘制展开图既耗时又容易出错,而FreeCAD的SheetMetal工作台让这个过程变得直观高效。最近我在改造工作室铝…...
WarcraftHelper完全指南:从显示异常到性能飞跃的5个关键突破
WarcraftHelper完全指南:从显示异常到性能飞跃的5个关键突破 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 诊断宽屏适配问题 在34英寸2…...
