WPF获得全局窗体句柄,并响应全局键盘事件
场景
wpf窗体运行后,只能捕获当前Active窗体的按键事件,如果要监听windows全局事件,并对当前窗口事件响应.
第一步:导入Winows API
- public class Win32
- {
- [DllImport("User32.Dll")]
- public static extern void SetWindowText(int h, String s);
- /// <summary>
- /// 如果函数执行成功,返回值不为0。
- /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error()
- /// </summary>
- /// <param name="hWnd">要定义热键的窗口的句柄</param>
- /// <param name="id">定义热键ID(不能与其它ID重复) </param>
- /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
- /// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换,
- /// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param>
- /// <returns></returns>
- [DllImport("user32.dll", SetLastError = true)]
- public static extern bool RegisterHotKey(
- IntPtr hWnd,
- int id,
- KeyModifiers fsModifiers,
- int vk
- );
- /// <summary>
- /// 取消注册热键
- /// </summary>
- /// <param name="hWnd">要取消热键的窗口的句柄</param>
- /// <param name="id">要取消热键的ID</param>
- /// <returns></returns>
- [DllImport("user32.dll", SetLastError = true)]
- public static extern bool UnregisterHotKey(
- IntPtr hWnd,
- int id
- );
- /// <summary>
- /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
- /// </summary>
- /// <param name="lpString"></param>
- /// <returns></returns>
- [DllImport("kernel32", SetLastError = true)]
- public static extern short GlobalAddAtom(string lpString);
- [DllImport("kernel32", SetLastError = true)]
- public static extern short GlobalDeleteAtom(short nAtom);
- /// <summary>
- /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
- /// </summary>
- [Flags()]
- public enum KeyModifiers
- {
- None = ,
- Alt = ,
- Ctrl = ,
- Shift = ,
- WindowsKey =
- }
- /// <summary>
- /// 热键的对应的消息ID
- /// </summary>
- public const int WmHotkey = 0x312;
- }
第二步:注册快捷键
- /// <summary>
- /// 注册快捷集合
- /// </summary>
- readonly Dictionary<string, short> hotKeyDic = new Dictionary<string, short>();
- public MainWindow()
- {
- InitializeComponent();
- this.Loaded += (sender, e) =>
- {
- var wpfHwnd = new WindowInteropHelper(this).Handle;
- var hWndSource = HwndSource.FromHwnd(wpfHwnd);
- //添加处理程序
- if (hWndSource != null) hWndSource.AddHook(MainWindowProc);
- hotKeyDic.Add("Alt-S", Win32.GlobalAddAtom("Alt-S"));
- hotKeyDic.Add("Alt-D", Win32.GlobalAddAtom("Alt-D"));
- Win32.RegisterHotKey(wpfHwnd, hotKeyDic["Alt-S"], Win32.KeyModifiers.Alt, (int)System.Windows.Forms.Keys.S);
- Win32.RegisterHotKey(wpfHwnd, hotKeyDic["Alt-D"], Win32.KeyModifiers.Alt, (int)System.Windows.Forms.Keys.D);
- };
- }
第三步:响应快捷键事件
- /// <summary>
- /// 响应快捷键事件
- /// </summary>
- /// <param name="hwnd"></param>
- /// <param name="msg"></param>
- /// <param name="wParam"></param>
- /// <param name="lParam"></param>
- /// <param name="handled"></param>
- /// <returns></returns>
- private IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
- {
- switch (msg)
- {
- case Win32.WmHotkey:
- {
- int sid = wParam.ToInt32();
- if (sid == hotKeyDic["Alt-S"])
- {
- MessageBox.Show("按下Alt+S");
- }
- else if (sid == hotKeyDic["Alt-D"])
- {
- MessageBox.Show("按下Alt+D");
- }
- handled = true;
- break;
- }
- }
- return IntPtr.Zero;
- }
WPF获得全局窗体句柄,并响应全局键盘事件的更多相关文章
- 【winform-窗体快捷键】定义功能窗体快捷键,非全局
这里的快捷键并非系统全局快捷键.仅是普通的当窗体在焦点内发生.有很多种方法,这里列举几种项目中使用到的方法. Alt+*(一般控件快捷键) 这个比较简单,只需为该控件的Text属性声明时加上”(&am ...
- 获取当前进程(程序)主窗体句柄并设置wpf的父窗体为此句柄
有时候在c++调用wpf控件的时候,wpf控件想自己显示窗体,但需要设置owner属性.迂回解决办法是设置wpf的window窗体的父窗体为进程的句柄. 1.获取当前进程id int id = Pro ...
- duilib底层机制剖析:窗体类与窗体句柄的关联
转载请说明原出处,谢谢~~ 看到群里朋友有人讨论WTL中的thunk技术,让我联想到了duilib的类似技术.这些技术都是为了解决c++封装的窗体类与窗体句柄的关联问题. 这里是三篇关于thunk技术 ...
- VC中获取窗体句柄的各种方法
AfxGetMainWnd AfxGetMainWnd获取自身窗体句柄 HWND hWnd = AfxGetMainWnd()->m_hWnd; GetTopWindow 函数功能:该函数检查与 ...
- WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案
首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如 WPF中不规则窗体与WebBrowser控件的兼 ...
- JCEF3——谷歌浏览器内核Java版实现(一):使用jawt获取窗体句柄
前言 最近一段时间研究谷歌浏览器内核.谷歌浏览器内核一直开源,并维护更新,它的开源项目中内核更新速度和Chrome浏览器版本更新进度一样!而且它不同于WebKit(值得一题的是谷歌浏览器已不使用Web ...
- WPF 之 自定义窗体标题栏
在WPF中自定义窗体标题栏,首先需要将窗体的WindowStyle属性设置为None,隐藏掉WPF窗体的自带标题栏.然后可以在窗体内部自定义一个标题栏. 例如,标题栏如下: <WrapPanel ...
- 在DLL中封装的VCL窗体Tab键响应的问题
在DLL中的子窗体不会响应Tab按键的,这个时候就需要手动去指定Tab键的操作,但是前提是主窗体要向这个窗体发送一个消息,一个Tab键按下的消息.基本顺序是这样的: 1. 主窗体用Hook技术捕获Ta ...
- WPF中不规则窗体与WebBrowser控件的兼容问题解决办法
原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...
随机推荐
- lintcode 453 将二叉树拆成链表
将二叉树拆成链表 描述 笔记 数据 评测 将一棵二叉树按照前序遍历拆解成为一个假链表.所谓的假链表是说,用二叉树的 right 指针,来表示链表中的 next 指针. 注意事项 不要忘记将左儿子标 ...
- 接口测试入门(3)--使用httpClient进行登录用例操作/set-cookies验证/ List<NameValuePair>设置post参数/json解析
(最近学的都是很基础的接口测试,都是基于UI界面可见的接口,就是发请求,接收响应,分析返回的结果,校验,对共通模块进行封装,仅此而已,其实做自动化的思路基本都是如此,UI也是.) 现在开始用httpC ...
- Apache Spark 2.2.0 中文文档 - 快速入门 | ApacheCN
快速入门 使用 Spark Shell 进行交互式分析 基础 Dataset 上的更多操作 缓存 独立的应用 快速跳转 本教程提供了如何使用 Spark 的快速入门介绍.首先通过运行 Spark 交互 ...
- 【漏洞公告】CVE-2017-12615/CVE-2017-12616:Tomcat信息泄漏和远程代码执行漏洞
2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017-12615和CVE-2017-12616,该漏洞受影响版本为7.0-7.80之间,在一定 ...
- 一张图告诉你移动Web前端所有技术(工程化、预编译、自动化)
你要的移动web前端都在这里! 大前端方向:移动Web前端.Native客户端.Node.js. 大前端框架:React.Vue.js.Koa 跨终端技术:HTML5.CSS 3.JavaScript ...
- 【个人笔记】《知了堂》mysql表连接
为什么使用表连接 什么是表连接? 如果数据来自多个表,那么可以采用链接查询的方式来实现.因此表连接就是多个表连接合在一起实现查询效果 表连接的原理 表连接采用的是笛卡尔乘积,称之为横向连接. 笛卡尔乘 ...
- VS2015 + EF6连接MYSQL
ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,不仅支持SQL Server,还支持MySQL.Ora ...
- Python扩展方法一二事
前言 跟着一个有强迫症的老板干活是一件极其幸福的事情(你懂的).最近碰到一个问题,简单的说就是对一个对象做出部分修改后仍然返回此对象,于是我就写了一个方法,老板看了之后只有一句话:不雅观,改成直接对此 ...
- SqlHelper工具类
public class SqlHlper { public static readonly string constr = ConfigurationManager.ConnectionString ...
- 洗礼灵魂,修炼python(7)--元组,集合,不可变集合
前面已经把列表的基本用法讲解完 接着讲python的几大核心之--元组(tuple) 1.什么是元组? 类似列表,但为不可变对象,之前提到列表是可变对象,所谓可变对象就是支持原处修改,并且在修改前后对 ...