调用Win32 API(优先级最高,全局监听, 支持最小化失焦等情况)

那么,假如我要在一个WPF程序监听CTRL+5按键,首先在主窗口程序添加以下代码:


/// <summary>
/// CTRL+5事件Id
/// </summary>
private const int Ctrl5KeyEventId = 9000; [DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk); [DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id); protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e); var handle = new WindowInteropHelper(this).Handle;
var source = HwndSource.FromHwnd(handle);
source?.AddHook(HwndHook);
//真正注册快捷键监听处理: 同时注册数字键和小键盘的CTRL+5
RegisterHotKey(handle, Ctrl5KeyEventId, (uint)ModifierKeys.Control, (uint)KeyInterop.VirtualKeyFromKey(Key.D5));
RegisterHotKey(handle, Ctrl5KeyEventId, (uint)ModifierKeys.Control, (uint)KeyInterop.VirtualKeyFromKey(Key.NumPad5));
} private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int wmHotkey = 0x0312; switch (msg)
{
case wmHotkey:
switch (wParam.ToInt32())
{
case Ctrl5KeyEventId:
Debug.WriteLine("Win32监听CTRL+5成功");
break;
}
break;
} return IntPtr.Zero;
} protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e); var handle = new WindowInteropHelper(this).Handle;
//关闭窗口后取消注册
UnregisterHotKey(handle, Ctrl5KeyEventId);
}

监听WPF的KeyDown事件(不够清真,可选择,最小化失焦等情况监听失效)


public MainWindow()
{
InitializeComponent();
KeyDown += MainWindow_KeyDown;
} private void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && (e.Key == Key.D5 || e.Key == Key.NumPad5))
{
Debug.WriteLine("WPF的KeyDown事件监听CTRL+5成功"); ;
e.Handled = true;
}
}

XAML绑定命令方式(WPF当然优先选中命令绑定啦,清真,最小化失焦等情况监听失效)

以下为Window主窗体的XAML代码


<Window.CommandBindings>
<CommandBinding Command="{x:Static local:Commands.Ctrl5Command}" Executed="Ctrl5Command_OnExecuted"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Modifiers="Control" Key="D5" Command="{x:Static local:Commands.Ctrl5Command}" />
<KeyBinding Modifiers="Control" Key="NumPad5" Command="{x:Static local:Commands.Ctrl5Command}" />
</Window.InputBindings>

在Window主窗体后台代码创建命令对应的Executed方法


private void Ctrl5Command_OnExecuted(object sender, ExecutedRoutedEventArgs e)
{
Debug.WriteLine("WPF的XAML绑定命令监听CTRL+5成功");
}

新增命令相关的静态类:


public static class Commands
{
public static ICommand Ctrl5Command { get; } = new RoutedCommand();
}

细节

三个监听方案的优先级

其中Win32 > XAML绑定命令 = KeyDown事件,假如同时监听的话,其中会只处理高优先级的,以上面的例子,假如

我同时监听三个,只会处理win32的


Win32监听CTRL+5成功
全局监听问题

其中win32支持全局监听键盘,也就是窗口在失焦情况下,例如最小化,也能监听得到,其中XAML绑定命令KeyDown事件不支持失焦情况,最小化等情况也就监听不到了,因此,要按业务选择方案

DEMO

DEMO链接

WPF监听快捷键的几种方式的更多相关文章

  1. ASP.NET Core中配置监听URLs的五种方式

    原文: 5 ways to set the URLs for an ASP.NET Core app 作者: Andrew Lock 译者: Lamond Lu 默认情况下,ASP. NET Core ...

  2. springboot 中事件监听模型的一种实现

    目录 定义事件本身 定义事件源 定义监听者 一.需要实现 ApplicationListener 二.使用 @EventListener 注解 测试 项目结构 前言: 事件监听模型是一种常用的设计模式 ...

  3. bootstrap课程12 滚动监听如何实现(bootstrap方式和自定义方式)

    bootstrap课程12 滚动监听如何实现(bootstrap方式和自定义方式) 一.总结 一句话总结:通过监听滚动的高,判断滚动的高是否大于元素距离顶端的距离 1.如何知道屏幕滚动的高? st=$ ...

  4. JS003. 事件监听和监听滚动条的三种参数( addEventListener( ) )

    全局 1 window.addEventListener('scroll', () => { 2 console.log('------') 3 console.log(document.doc ...

  5. Second Day: 关于Button监听事件的三种方法(匿名类、外部类、继承接口)

    第一种:通过匿名类实现对Button事件的监听 首先在XML文件中拖入一个Button按钮,并设好ID,其次在主文件.java中进行控件初始化(Private声明),随后通过SetOnClickLis ...

  6. WPF - 监听判断键盘组合键的按下

    对于键盘事件PreviewKeyDown.PreviewKeyUp.KeyDown.KeyUp,在其中检查当次事件是哪个按键触发的很简单,只需要判断KeyEventArgs类型的事件参数e的Key属性 ...

  7. miniui 给表格行添加监听事件的几种方法以及点击某列列名数据不能排序的问题

    最近在使用miniui框架做开发,在做表格行的点击监听事件中发现了几个属性,都可以起到监听效果但是执行的结果却大有不同.好了废话不多说,直接上代码. <div id="pageGrid ...

  8. 009-Spring Boot 事件监听、监听器配置与方式、spring、Spring boot内置事件

    一.概念 1.事件监听的流程 步骤一.自定义事件,一般是继承ApplicationEvent抽象类 步骤二.定义事件监听器,一般是实现ApplicationListener接口 步骤三.启动时,需要将 ...

  9. 解决Oracle监听错误的一种办法

    1:事出有因 安装oracle数据库,默认安装的是orcl数据库,安装完成后查看了一下字符集是gbk的,由于业务需要al32utf8的字符集,所以需要修改字符集,但是修改却无效.于是就删除了默认的or ...

  10. UIScrollView监听静止的数种情况

    1.直接通过block -(void)testInBlock { //通过block监听 [UIView animateWithDuration:1.0 animations:^{ self.scro ...

随机推荐

  1. css3边框属性学习

    1.boder-radius <!DOCTYPE html> <html> <head> <meta charset="utf-8" /& ...

  2. gdb 脚本 简单理解

    1. gdb 脚本的语法简介: 摘录博客:https://blog.csdn.net/hejinjing_tom_com/article/details/50350865 1]   # 为脚本注释命令 ...

  3. charles3.11.1抓https包

    结论先行: 用的是安卓测试机,没加固之前的生产环境的安装包,可以抓到https请求 加固之后的包[也就是要上应用市场的包],抓不到https请求 电脑上的操作: 1. 安装证书[电脑上安装了charl ...

  4. Django基础篇 07-Django后端和html交互

    一.上下文管理器 context_processors 执行顺序是 先执行views.py中代码,在views返回之前在走到TEMPLATES.OPTIONS.context_processors的方 ...

  5. springboot项目打成jar包,启动指定外部的yml文件

    java -jar xxx.jar --spring.config.local=application.yml

  6. 【APT】Bitter APT组织针对巴基斯坦航空综合部门攻击活动分析

    前言 蔓灵花(Bitter)是一个被广泛认为来自印度的APT组织,该组织长期针对我国及巴基斯坦的政府.军工.电力.核等部门发动网络攻击,窃取敏感数据,具有较强的政治背景.本次分享一个蔓灵花组织针对巴基 ...

  7. C# core 流、字节、字符串相互转换

    /// <summary> /// 将 Stream 转成 byte[] /// </summary> public byte[] StreamToBytes(Stream s ...

  8. error: You must be logged in to the server (Unauthorized) 问题处理

    故障现象: 执行kubectl 命令时: 提示"error: You must be logged in to the server (Unauthorized)" 分析: 权限问 ...

  9. 基础实验之access/trunk/valn/vlanif/静态路由

     实验要求 1,PC1,PC2,PC3,PC4分别属于VLAN10,20,30,40 2,PC1,PC2,PC3,PC4互通 步骤1:PC1,2,3,4分别配置IP,并在SW6,SW7分别配置网关,并 ...

  10. 基于CMMI的软件工程及实训指导 第一章

    第一章 软件工程基础 1. 软件工程概述 1.1 软件工程概念 软件工程是从管理和技术两方面来研究如何采用工程的概念.原理和技术方面并加以综合,指导开发人员更好地开发和维护计算机软件的一门新学科. 1 ...