C语言 如何全局拦截和阻止大写锁定切换事件,而不影响其他事件?

67up9zun  于 2023-01-12  发布在  其他
关注(0)|答案(2)|浏览(115)

bounty将在3天后过期。回答此问题可获得+50的声誉奖励。NS studios正在寻找来自声誉良好来源的答案:提供至少一种经过验证的方法来解决任务,最好不涉及驱动程序或第三方库,或者如果没有解决方案,可以选择提供其他方法来实现类似的结果。

我需要检查Caps Lock的切换状态并阻止它。我曾尝试使用WH_KEYBOARD_LL的低级键盘挂钩SetWindowsHookEx并检查WPARAM==WM_KEYDOWN || WPARAM==WM_SYSKEYDOWN消息和LPARAM.vkCode==VK_CAPITAL || LPARAM.scanCode==0x3A,但这导致我在按下/按下Caps Lock时拦截/阻止它。而不是在它实际被切换的时候。我专门拦截切换事件是很重要的,因为我不希望依赖于一次按下Caps Lock来切换它的状态,我不想在大写锁定被用作修饰符的情况下中断其他事件。我目前正在使用GetKeyState(VK_CAPITAL)&1检查我的窗口回调中的大写锁定状态,并使用SendInput强制它返回,但如果可能的话,我宁愿拦截/阻止它。我也尝试过原始输入,当切换大写锁定时,它会生成一对RI_KEY_BREAK和RI_KEY_MAKE消息,但是(除非我弄错了),没有办法阻止基于WM_INPUT消息的键,试图同步钩子和原始输入似乎很困难,因为钩子总是先得到它们。从钩子使用GetKeyState或GetAsyncKeyState似乎也不起作用,因为他们似乎是在钩拳之后才得到事件。

gojuced7

gojuced71#

使用GetAsyncKeyState来检测caps键何时/是否被点击,以及它的当前状态(向上或向下),然后调用keybd_event(或SendInput)以编程方式将caps键设置回您希望的状态。
in this link中包含以下代码片段(沿着其他设置代码),执行时将打开或关闭CAPS锁定:

RUN keybd_event ({&VK_CAPITAL}, 0, {&KEYEVENTF_KEYUP},       0, OUTPUT intResult).
RUN keybd_event ({&VK_CAPITAL}, 0, {&KEYEVENTF_EXTENDEDKEY}, 0, OUTPUT intResult).
RUN keybd_event ({&VK_SHIFT}, 0, {&KEYEVENTF_KEYUP},       0, OUTPUT intResult).
RUN keybd_event ({&VK_SHIFT}, 0, {&KEYEVENTF_EXTENDEDKEY}, 0, OUTPUT intResult).

在应用程序中部署此实现(GetAsyncKeyState/keybd_event组合)的建议方法是将其封装到永久循环中的工作线程集,并将sleep()设置为允许大约每100 ms采样一次状态。
(Note,我相信GetAsyncKeyState()优于GetKeyState(),因为GetKeyState()从线程的消息队列中获取键状态。该状态不反映与硬件相关的中断级状态。GetAsyncKeyState()指定自上次调用GetAsyncKeyState()以来是否按下了键。以及键当前是向上还是向下)。利用使用GetAsyncKeyState()的合理且适当的采样周期。
上面的概念由运行在user-mode中的函数组成,因此几乎可以肯定,它只限于 reaction 算法(检测切换,然后执行另一个切换)的实现,而不是真正的 prevention 算法(即,在运行时将键重新Map到no-op,或者在低级别捕获请求)。
大多数真正的 * 预防 * 算法可能会利用内核模式驱动程序调用,这些调用可以通过WinAPI访问和实现,并且通过深入研究RAWKEYBOARD中的内容到Keyboard and Mouse HID drivers等领域来介绍其概念(以及其他地方)。

2ekbmq32

2ekbmq322#

您可以使用SetWindowsHookEx设置一个低级钩子。请参考线程:Best way to intercept pressing of Caps Lock

相关问题