C++如何使程序全局检测我的按键?

3

我正在制作一个程序,希望能够检测到按下F6键,然后调用if语句。这应该是全局有效的,不仅仅是在我的程序中。我该如何实现?


这是为哪个操作系统?标准的C++中没有相关内容,因此您需要使用特定于操作系统的API。 - cf-
2个回答

6

由于您在使用Windows系统,您可以使用SetWindowsHookEx函数来设置键盘钩子,并选择WH_KEYBOARDWH_KEYBOARD_LL参数。然后,在匹配的KeyboardProcLowLevelKeyboardProc函数中处理按键事件,并过滤掉任何F6键。请确保对于非F6键按下事件,调用CallNextHookEx函数,因为如果未调用CallNextHookEx函数,则会“吃掉”键盘消息。

您需要将这些代码放到一个DLL文件中;您需要32位和64位两个版本的DLL文件,因为32位应用程序只能注入32位DLL文件,64位应用程序只能注入64位DLL文件。


您也可以尝试基于RegisterHotKey函数的方法。这比钩子更安全,但如果另一个应用程序在您之前调用RegisterHotKey并指定F6,则您将无法注册热键。

由于您不希望在热键上添加任何额外的修饰符,因此调用将类似于:

RegisterHotKey(myHwnd, 1, 0, VK_F6);

其中myHwnd是您窗口的HWND(或者如果您更愿意在消息循环中处理WM_HOTKEY消息,则可以选择nullptr),1是热键的标识符,可以是任何int类型的值,0指定没有修饰键(如Ctrl、Alt、Windows键等),而VK_F6是F6键的虚拟键码。


我认为你不需要一个DLL来处理KeyboardProc,因为描述说明该事件将作为消息传递到你的消息循环中。 - MSalters
@MSalters,您是指SetWindowsHookEx文档中的这一部分吗?请注意,WH_MOUSE、WH_KEYBOARD、WH_JOURNAL、WH_SHELL和低级别钩子可以在安装钩子的线程上调用,而不是处理钩子的线程。我不完全理解这一点;您是说钩子回调将被视为普通的Windows消息,并留在您的正常消息循环中,而不是通常的钩子行为调用指定的回调函数吗?那么回调函数是否仍然必要呢? - cf-
我猜是为了向后兼容API。微软非常明确地表示,这些钩子函数不是好的设计,“仅用于调试”。令人惊讶的是,围绕着Vista的UAC清理仍然保留了它们。从安全角度来看,您不希望在每个进程中都有随机的DLL。 - MSalters
如果微软放弃钩子函数,至少是键盘和鼠标钩子函数,我会更加惊讶。这些钩子似乎相当普遍,我不知道有什么可以用来替代它们(虽然在我试图想出键盘钩子的替代品时,感谢你提醒我使用RegisterHotKey)。 - cf-
是的,很不幸它们是普遍使用的。所以我怀疑实现已经进行了清理而不是删除:在钩子过程中调用钩子并使用消息传递实际事件。如果 DefWindowProc 在您的钩子函数的调用堆栈上,那么这也不会让我感到惊讶。 - MSalters
如果我使用 RegisterHotKey,在退出前是否应该调用 UnregisterHotKey - LovelyHanibal

1
你需要的函数是RegisterHotKey(VK_F6 ...),它会触发发送WM_HOTKEY消息。因此你需要一个Windows消息循环。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接