【发布时间】:2021-03-20 10:25:23
【问题描述】:
我的目标:
我希望我的应用程序能够响应特定的键盘快捷键/热键,无论它是否是前台窗口而不会干扰其他应用程序对这些快捷键的使用。
例如,如果另一个进程有前台窗口并且用户按下VK_MEDIA_PLAY_PAUSE 键,我希望我的应用程序和当前前台窗口做出响应。
此功能是用户设置,所以我不担心不良行为。
我尝试过但没有奏效的方法:
-
WM_KEYDOWN消息只发送到当前前台窗口,所以我的应用程序没有收到它们。 -
GetKeyState(),根据the MS docs,根据最近检索到的WM_KEY*消息返回key的状态,因为我的应用没有收到WM_KEYDOWN作为后台窗口,所以这个状态不会改变。 -
GetAsyncKeyState(),根据the MS docs,在以下情况下返回零:
前台线程属于另一个进程,桌面不允许hook或者journal记录。
我不确定这后半部分是什么意思,但是当我的窗口不是前景窗口时,GetAsyncKeyState() 返回零。
-
GetKeyboardState()与GetKeyState()一样,仅在检索消息时更改密钥状态。 -
RegisterHotKey()/UnregisterHotKey():与其他选项不同,我的应用程序能够响应热键,即使它不是前台窗口;但是,当前前台窗口不再响应。这些热键似乎只重定向到我的应用程序,而其他应用程序根本看不到它们。
我唯一的(凌乱的)想法:
我能想到的唯一方法是我相当肯定会被 Win32 社区回避的方法。
我可以使用RegisterHotKey()/UnregisterHotKey() 来通知热键,然后模拟按键到当前前台窗口。看到SendInput() 可能会进入循环,我需要先取消注册热键:
case WM_HOTKEY:
UnregisterHotKey(...); // unregister the hotkey to avoid looping
SendInput(...); // send keyboard input
RegisterHotKey(...); // restore it
或直接用SendMessage()模拟:
case WM_HOTKEY:
SendMessage(GetForegroundWindow(), WM_KEYDOWN, ...);
// send WM_KEYUP ?
这两者似乎都是 Win32 架构并非设计用于的黑客攻击。
是否有任何(其他)方法可以在不干扰其他应用程序的情况下从非前台窗口读取/接收键盘输入?
【问题讨论】:
标签: c++ windows winapi keyboard keyboard-shortcuts