Search code examples
winapicapslock

Detect physical CapsLock position after sending a KEYEVENTF_KEYUP to the Virtual Keyboard Buffer


I am developing a program that will make the CapsLock key work as a control key under Windows. I understand that this can be trivially done with a registry change. Unfortunately, I am not able to run that registry change, nor am I able to run a device driver.

My idea is to watch the keyscans coming over the virtual keyboard. When I see a CapsLock down event, I will send a CapsLock Up event, a second CapsLock down event, a second CapsLock Up event, and then a control-key down event. All of this code works! However, I have not been able to catch the physical UP action of the CapsLock key.

I've tried reading the CapsLock Up key with both win32api.GetKeyState() and win32api.GetAsyncKeyState(). After I stuff the CapsLock up event, they both say that the key is up. There seems to be no way to look at the actual hardware and see that it's still down.

Is there a way to catch the events BEFORE they go to the virtual keyboard buffer? If I could do that, I could catch the REAL CapsLock down and Up events. But I can't seem to find it.

I need to be able to do this entirely from the win32 api.


Solution

  • GetKeyState is the state your thread was in when it last received a message. GetAsyncKeyState is the current state. These functions can miss events if you are trying to pull for state changes.

    Use a low-level keyboard hook to see all input early in the input processing chain. You can also hook your thread with a normal keyboard hook if you don't care about global events.