- bounty将在6天后过期**。回答此问题可获得+50的声誉奖励。NS studios正在寻找来自声誉良好来源的答案:提供至少一种经过验证的方法来解决任务,最好不涉及驱动程序或第三方库,或者如果没有解决方案,可以选择提供其他方法来实现类似的结果。
我试图找到一种方法来拦截和阻止全局与WinAPI的大写锁定切换事件。
我试过将SetWindowsHookEx
与WH_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
所做的任何事情,或者拦截/阻止它?
2条答案
按热度按时间woobm2wo1#
使用GetAsyncKeyState来检测caps键何时/是否被点击,以及它的当前状态(向上或向下),然后调用keybd_event(或SendInput)以编程方式将caps键设置回您希望的状态。
in this link中包含以下代码片段(以及其他设置代码),执行时将打开或关闭CAPS锁定:
在应用程序中部署此实现(
GetAsyncKeyState
/keybd_event
组合)的建议方法是将其封装到永久循环中的工作线程集,并将sleep()
设置为允许大约每100ms采样一次状态。(Note,我相信
GetAsyncKeyState()
优于GetKeyState()
,因为GetKeyState()
从线程的消息队列中获取键状态。该状态不反映与硬件相关的中断级状态。GetAsyncKeyState()
指定自上次调用GetAsyncKeyState()
以来是否按下了键。以及键当前是向上还是向下)。利用使用GetAsyncKeyState()
的合理且适当的采样周期。上面的概念由运行在user-mode中的函数组成,因此几乎可以肯定,它只限于 * reaction * 算法(检测切换,然后执行另一个切换)的实现,而不是真正的 * prevention * 算法(即,在运行时将键重新Map到no-op,或者在低级别捕获请求)。
大多数真正的 * 预防 * 算法可能会利用内核模式驱动程序调用,这些调用可以通过WinAPI访问和实现,其概念是通过深入研究RAWKEYBOARD和Keyboard and Mouse HID drivers等领域引入的(以及其他地方)。
s4n0splo2#
您可以使用SetWindowsHookEx设置一个低级钩子。请参考线程:Best way to intercept pressing of Caps Lock