windows 如何全局拦截和阻止大写锁定切换事件,而使上/下保持不变?

r7s23pms  于 2023-01-10  发布在  Windows
关注(0)|答案(2)|浏览(119)
    • bounty将在6天后过期**。回答此问题可获得+50的声誉奖励。NS studios正在寻找来自声誉良好来源的答案:提供至少一种经过验证的方法来解决任务,最好不涉及驱动程序或第三方库,或者如果没有解决方案,可以选择提供其他方法来实现类似的结果。

我试图找到一种方法来拦截和阻止全局与WinAPI的大写锁定切换事件。
我试过将SetWindowsHookExWH_KEYBOARD_LL一起使用,并检查WPARAM==WM_KEYDOWN || WPARAM==WM_SYSKEYDOWN消息和LPARAM.vkCode==VK_CAPITAL || LPARAM.scanCode==0x3A,但这导致我在按住/按下大写字母时拦截/阻止大写字母锁定,而不仅仅是在实际切换时。
它只拦截切换事件对我来说很重要的原因是因为某些软件(像屏幕阅读器)可以使用单次按下或按住caps lock作为修改器,这不是我想破坏的东西。我目前使用GetKeyState(VK_CAPITAL)&1来检查caps lock是否被切换,并通过使用SendInput发送caps lock来强制它返回。但如果可能的话,我宁愿拦截/阻止它。我也尝试过原始输入,当切换大写锁定时,它会生成一对RI_KEY_BREAK和RI_KEY_MAKE消息,但(除非我弄错了),没有办法阻止基于WM_INPUT消息的键,尝试同步钩子和原始输入似乎很困难,因为钩子总是先得到它们。
有没有办法在其他东西收到切换消息之前,钩住GetKeyState(VK_CAPITAL)&1所做的任何事情,或者拦截/阻止它?

woobm2wo

woobm2wo1#

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

s4n0splo

s4n0splo2#

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

相关问题