在我的 WPF 应用程序中捕获没有焦点的按键事件

2024-03-03

我在 WPF 中开发了一个屏幕键盘。我需要夺取钥匙 新闻事件(通过键盘)以跟踪 Caps Lock、Shift 等等(无论它们是否被按下)。 请注意,当任何其他应用程序时,我的应用程序会失去焦点 (比如记事本)被打开。

谁能建议如何在 WPF 中实现这一目标? 简而言之,我的 WPF 应用程序甚至需要捕获按键事件 虽然它没有焦点。


如果您希望 WPF 应用程序能够检测和处理按键,即使当前未激活或聚焦在屏幕上,您也可以在 Windows 中实现所谓的全局热键。

可以将以下两个方法添加到 C# 类中,以便能够注册和取消注册全局热键:

[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
 
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

示例代码

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
 
namespace Mm.Wpf.GlobalHotKeys
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
 
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
 
        private const int HOTKEY_ID = 9000;
 
        //Modifiers:
        private const uint MOD_NONE = 0x0000; //(none)
        private const uint MOD_ALT = 0x0001; //ALT
        private const uint MOD_CONTROL = 0x0002; //CTRL
        private const uint MOD_SHIFT = 0x0004; //SHIFT
        private const uint MOD_WIN = 0x0008; //WINDOWS
        //CAPS LOCK:
        private const uint VK_CAPITAL = 0x14;
 
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private IntPtr _windowHandle;
        private HwndSource _source;
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
 
            _windowHandle = new WindowInteropHelper(this).Handle;
            _source = HwndSource.FromHwnd(_windowHandle);
            _source.AddHook(HwndHook);
 
            RegisterHotKey(_windowHandle, HOTKEY_ID, MOD_CONTROL, VK_CAPITAL); //CTRL + CAPS_LOCK
        }
 
        private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            const int WM_HOTKEY = 0x0312;
            switch (msg)
            {
                case WM_HOTKEY:
                    switch (wParam.ToInt32())
                    {
                        case HOTKEY_ID:
                            int vkey = (((int)lParam >> 16) & 0xFFFF);
                            if (vkey == VK_CAPITAL)
                            {
                                tblock.Text += "CapsLock was pressed" + Environment.NewLine;
                            }
                            handled = true;
                            break;
                    }
                    break;
            }
            return IntPtr.Zero;
        }
 
        protected override void OnClosed(EventArgs e)
        {
            _source.RemoveHook(HwndHook);
            UnregisterHotKey(_windowHandle, HOTKEY_ID);
            base.OnClosed(e);
        }
    }
}
<Window x:Class="Mm.Wpf.GlobalHotKeys.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock x:Name="tblock"></TextBlock>
    </Grid>
</Window>

参考 https://blog.magnusmontin.net/2015/03/31/implementing-global-hot-keys-in-wpf/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在我的 WPF 应用程序中捕获没有焦点的按键事件 的相关文章

随机推荐

  • BigQuery 正则表达式中的前瞻

    BigQuery regexp 似乎不支持前瞻功能 有谁知道这是否正确 如果是 是否有计划在不久的将来支持它 BigQuery 正则表达式用途re2 https code google com p re2 似乎没有计划向 re2 添加环视断
  • MySQL 数学和 LIMIT 中的 COUNT(*)

    是否可以让 MySQL LIMIT 具有总行数除以 2 的偏移量 以便查询看起来像这样 SELECT FROM test LIMIT COUNT 2 5 其中 5 只是一个数字 这不可能 来自文档 http dev mysql com do
  • c++:错误:无法识别的命令行选项“-std=c++14”

    我刚刚将我的电脑从 Ubuntu 15 10 迁移到 Linux Mint 17 3 在此转变之前 该项目在 CLion 中编译得很好 现在 它给出了以下错误 c 错误 无法识别的命令行选项 std c 14 这可能是由于我的 CMake
  • 在 java 中处理文件

    我有一个字符串数组 我想将这些字符串保存在文件中 问题是 我需要创建一个名为 db txt 的新文件 仅当它不存在时 然后以某种方式向其写入字符串 然后我希望能够从该文件读取字符串并将它们插入到数组中 插入和使用数组不是问题 但问题是如何弄
  • Android 市场上的 Android 发布商帐户

    我已于12月2日在Android Market支付了25美元 但到目前为止我的开发者帐户尚未激活 我无法通过它发布应用程序 您对 Android Market 的注册仍在处理中 你 可以将应用程序上传到Android Market 但不能发
  • 为什么我在 Logcat 中看不到我的打印语句?

    我尝试在我的第一个 Android 程序上调试代码 我开始使用常规 println 它在早期的 main onCreate 方法中工作 在 LogCat 中显示结果 然而 它似乎在下面不起作用 所以然后我开始尝试计算 Log i Log d
  • 告诉我为什么这不会导致超时错误(selenium 2 webdriver)?

    from selenium import webdriver from selenium webdriver support ui import WebDriverWait browser webdriver Firefox browser
  • 如何将已经签出的 svn 存储库导入到 Eclipse 中?

    我已经签出了一个 Subversion 存储库 并将其保存在我的本地硬盘中 现在 我如何将其导入到 Eclipse 中 当我选择的时候文件 gt 导入选择SVN 只有一个选项可以再次从服务器签出项目 文件 gt 新建项目似乎是针对我们正在从
  • 在 AutoCompleteTextView Android HoneyComb 操作栏中显示光标

    我在 Honeycomb 操作栏中放置了一个 Android AutoCompleteTextView 问题是即使 AutoCompleteTextView 具有焦点 它也不会显示光标 因此最终用户认为该框没有焦点 将这些属性添加到 Aut
  • Django queryset - 是否可以对 FloatField 进行过滤?

    我正在尝试执行一个非常简单的操作 但遇到了问题 我有一个简单的模型 class MyModel models Model date models DateTimeField null False value models FloatFiel
  • 内部类对象错误

    import java io class YY int a 0 void putValue int m a m inner x new inner x display class inner void display System out
  • 为什么将短变量分配给整数引用会产生编译时错误?

    我有以下 Java 代码 class Boxing public static void main String args short s 10 Integer iRef s 为什么编译时会产生错误 如果我在表达式中显式地将短整型类型转换为
  • python os.listdir 不显示所有文件

    在我的windows 7 64位系统中 有一个名为msconfig exe在文件夹中c windows system32 是的 它必须存在 但是当我使用os listdir搜索文件夹c windows system32 我没有收到文件 这是
  • Oracle - 第二级子查询无法看到主查询中的字段

    在 Oracle 12c 中 以下查询有效 但在 Oracle 11g 中无效 因为二级子查询无法看到主查询中的字段 如何重写查询以使其在 Oracle 11 中也能工作 SELECT lvl unique code SELECT uniq
  • setPreferredSize 有哪些副作用?

    我有包含多个面板的窗口 我无权访问窗口代码 我只能修改面板的代码 我从面板上移除了一些组件 窗户的尺寸缩小了 但窗口太小 无法正确显示所有内容 我添加了行setPreferredSize getPreferredSize 现在窗口大小合适
  • 附近 API 的 Strategy.DISTANCE _TYPE_ EARSHOT 似乎并不限制消息接近度

    我正在使用新的附近 API https developers google com nearby https developers google com nearby 在设备之间短距离 约 5 英尺 发送消息 我已将策略距离类型设置为 DI
  • 如何以编程方式在 jupyter 笔记本中添加幻灯片单元格元数据?

    Jupyter 笔记本有一种可视化单元格元数据的方法 以便您能够使用以下命令参数化当您将笔记本导出到幻灯片时单元格的外观nbconvert Example 例如 我想以编程方式将该元数据添加到单元格中 而不使用 GUI 以便我可以自动创建幻
  • 在 sparql IN 子句中使用另一个 sparql

    我正在使用 SPARQL 我想知道是否可以在 in 子句中放入 sparql 更具体地说 我需要获取具有此 sparql 查询特定条件的实体 s1 s2 s1 在某个字段上的聚合值大于 5 select s1 x s2 WHERE s1 r
  • 没有模型的 MVC 3 验证

    我有一个关于 mvc3 验证的问题 内置的验证看起来很棒 然而 在一种情况下 我不得不使用 javascript 导致它的外观和感觉不一致 警报窗口与漂亮的红色文本 我们有一个表单 其中包含一些供用户输入的字段 提交后 一些 ajax 代码
  • 在我的 WPF 应用程序中捕获没有焦点的按键事件

    我在 WPF 中开发了一个屏幕键盘 我需要夺取钥匙 新闻事件 通过键盘 以跟踪 Caps Lock Shift 等等 无论它们是否被按下 请注意 当任何其他应用程序时 我的应用程序会失去焦点 比如记事本 被打开 谁能建议如何在 WPF 中实