在不聚焦窗口的情况下捕获关键点

2024-01-04

I have a application that always checks if a key like F12 is pressed. It doesn't need to have in focus of my main window of my app. I tried this code:

public int a = 1;
    // DLL libraries used to manage hotkeys
    [DllImport("user32.dll")]
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
    [DllImport("user32.dll")]
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    const int MYACTION_HOTKEY_ID = 1;

    public Form1()
    {
        InitializeComponent();
        // Modifier keys codes: Alt = 1, Ctrl = 2, Shift = 4, Win = 8
        // Compute the addition of each combination of the keys you want to be pressed
        // ALT+CTRL = 1 + 2 = 3 , CTRL+SHIFT = 2 + 4 = 6...
        RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F12);
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID)
        {

            a++;
            MessageBox.Show(a.ToString());
        }
        base.WndProc(ref m);
    }

I put 0 to this line RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F12); so that only if F12 is pressed it will capture.

但这没有用。我该如何解决这个问题?

在这里我无法理解一些行,例如:

const int MYACTION_HOTKEY_ID = 1;
m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID
base.WndProc(ref m);

谁能帮我理解这些线条?


但这没有用。我该如何解决这个问题?

你是什​​么意思“它不起作用”?您问题中的代码对我来说看起来是正确的。

它可能不起作用的唯一原因是因为RegisterHotKey http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309.aspx函数返回错误,而您没有检查它。为了使其工作,您需要添加SetLastError属性 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.setlasterror.aspx到它的声明,这会导致运行时缓存它设置的 Win32 错误代码。完成此操作后,您可以检查错误代码(如果函数返回false)通过调用GetLastWin32Error功能 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getlastwin32error.aspx。我建议使用这个函数的结果来生成并抛出一个Win32Exception http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx.

修改您的声明RegisterHotKey如下:

[DllImport("user32.dll", PreserveSig = false)]
public static extern bool RegisterHotKey(IntPtr hWnd,
                                         int id,
                                         uint fsModifiers,
                                         Keys key);

您对该函数的调用如下:

if (!RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, Keys.F12))
{
   throw new Win32Exception(Marshal.GetLastWin32Error());
}

完成后,我怀疑您会看到抛出异常并显示错误消息:

热键已注册

好吧,这使得调试问题变得更加简单,不是吗!您可能需要选择不同的热键,因为RegisterHotKey函数文档明确告诉我们:

The F12 key is reserved for use by the debugger at all times, so it should not be registered as a hot key. Even when you are not debugging an application, F12 is reserved in case a kernel-mode debugger or a just-in-time debugger is resident.

When I run the code and register F11 as a hotkey, it works just fine for me.


在这里我无法理解一些行,例如:

const int MYACTION_HOTKEY_ID = 1;
m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID
base.WndProc(ref m);

谁能帮我理解这些线条?

Sure:

  1. 第一行声明一个常量值,该值唯一标识您使用RegisterHotKey功能。更具体地说,它对应于id函数的参数。您在初次通话时传递了它。

  2. 这会检查窗口过程(WndProc) 查看消息是否 (Msg)正在处理的是WM_HOTKEY message http://msdn.microsoft.com/en-us/library/windows/desktop/ms646279.aspx. The WM_HOTKEY每当您使用注册的热键时,消息都会自动发布到您的窗口RegisterHotKey功能被按下。

    你不应该真正使用魔法数字0x0312不过,直接说吧,因为你不是唯一一个不确定这意味着什么的人。相反,定义一个常量并使用它:

    const int WM_HOTKEY = 0x0312;
    m.Msg == WM_HOTKEY
    

    该条件测试的第二部分(在&&)检查wParam消息字段以查看按下的热键是否是您注册的热键。请记住MYACTION_HOTKEY_ID是您的热键的唯一 ID。这WM_HOTKEY消息文档告诉我们检查wParam这就是我们确定按下了哪个热键的方法。

  3. 这调用基类的窗口过程。换句话说,你所做的就是覆盖虚拟的WndProc方法,允许您添加一些额外的代码(您的处理WM_HOTKEY)。当您完成附加逻辑后,您想要继续基类的逻辑,因此您继续转发消息。

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

在不聚焦窗口的情况下捕获关键点 的相关文章

  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 如何从 C# 中的 dataTable.Select( ) 查询中删除单引号?

    所以我有一个经销商名称列表 我正在我的数据表中搜索它们 问题是 一些傻瓜必须被命名为 Young s 这会导致错误 drs dtDealers Select DealerName dealerName 所以我尝试替换字符串 尽管它对我不起作
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • 代码 GetAsyncKeyState(VK_SHIFT) & 0x8000 中的这些数字是什么?它们是必不可少的吗?

    我试图在按下按键的简单动作中找到这些数字及其含义的任何逻辑解释 GetAsyncKeyState VK SHIFT 0x8000 可以使用哪些其他值来代替0x8000它们与按键有什么关系 GetAsyncKeyState 根据文档返回 如果
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • C# 数据表更新多行

    我如何使用数据表进行多次更新 我找到了这个更新 1 行 http support microsoft com kb 307587 my code public void ExportCSV string SQLSyntax string L
  • 对 std::vector 进行排序但忽略某个数字

    我有一个std vector
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在 NaN 情况下 to_string() 可以返回什么

    我使用 VS 2012 遇到了非常令人恼火的行为 有时我的浮点数是 NaN auto dbgHelp std to string myFloat dbgHelp最终包含5008角色 你不能发明这个东西 其中大部分为0 最终结果是 0 INF
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone

随机推荐