Home > Software design >  Is there a way to intercept and block the CapsLock toggled event?
Is there a way to intercept and block the CapsLock toggled event?

Time:01-06

I'm trying to find a way to intercept and block the CapsLock toggle event globally with WinAPI.

I have tried using SetWindowsHookEx with WH_KEYBOARD_LL and checking for WPARAM==WM_KEYDOWN || WPARAM==WM_SYSKEYDOWN messages, and LPARAM->vkCode==VK_CAPITAL || LPARAM->scanCode==0x3A, but this results in me intercepting/blocking CapsLock when it's held down/pressed, not only when it's actually toggled.
The reason it's important to me that it only intercepts the toggled event is because certain software (like screen readers) can use a single press or holding of CapsLock as a modifier, which is not something I wish to disrupt. I'm currently using GetKeyState(VK_CAPITAL)&1 to check for capslock getting toggled and forcing it back off by sending CapsLock with SendInput , but I would rather intercept/block it if any possible.

Is there any way to hook into whatever GetKeyState(VK_CAPITAL)&1 does or intercept/block something like wm_toggle message before other things can receive it?

CodePudding user response:

Use GetAsyncKeyState to detect when/if the caps key is hit, and its current state. Then call keybd_event to programmatically set the caps key back to the state that you want it to be.

The following code snippet (along with other setup code) is included in this link, and will toggle CAPS lock on or off when executed:

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).    

The recommended way to deploy this implementation (GetAsyncKeyState / keybd_event combination) within your application is to encapsulate it into a worker thread set in a forever loop with sleep() set to allow sampling of the state approximately every 100ms.

(Note, I believe GetAsyncKeyState() over GetKeyState() is an improvement for what you want to do here as GetKeyState() gets the key status returned from the thread's message queue. The status does not reflect the interrupt-level state associated with the hardware. GetAsyncKeyState() specifies whether the key was pressed since the last call to GetAsyncKeyState(), and whether the key is currently up or down.)

CodePudding user response:

You could set a low-level hook with SetWindowsHookEx. Refer to the thread: Best way to intercept pressing of Caps Lock

  • Related