Determining the state of modifier keys when hooking keyboard input
As part of a utility I was writing recently I wanted to hook keyboard input. In particular I was interested in global hooks (ie input to any program, not just mine), and I needed to handle complex key inputs, for example Ctrl-Alt-G
, i.e. keys plus modifiers. The usual way to do this is to use SetWindowsHookEx
.
Looking around I quickly found a class over on CodeProject here. The globalKeyboardHook
class deals with the hooking, allows you to specify which keys you are interested in and disregards the rest. The events are raised using the delegate type KeyEventHandler
. KeyEventHandler
uses KeyEventArgs
and has easily referenced properties for each of the modifier keys. So far so good.
However I found that the instance of KeyEventArgs
I was receiving in my event handler never had the modifier properties set to true
. Looking at the code for the class I couldn’t see anything there that would set the properties in the call back function for SetWindowsHookEx
.
The pertinent section of the original globalKeyboardHook
class looks like this:
While this code does return a KeyEventArgs
, there is no effort made to populate the modifier indicating properties on the class.
Googling around on the problem (for quite a while!), I found another reference to another WinApi command, GetKeyState
in this CodeProject article. There is documentation for GetKeyState
on the MSDN Dev Center. GetKeyState
is declared as follows:
We use a method to call GetKeyState for each vk constant above. It then adds each active key to the key code, so that, when KeyEventArgs is populated from keyCode, the modifier properties are set as we would expect.
Finally this method is included in the original hook processing code:
The returned KeyEventArgs passed in the KeyDown
and KeyUp
events will now in include the correct values of the modifier properties.
The full (and latest) implementation of globalKeyboardHook
can be found in the source for the I was working on in GitHub here.