My application synthesises keystrokes in other apps by using SendInput
. This almost works, except that due to circumstances I cannot change, the left Windows ke
"Correcting" the state of a modifier key by inserting a KEYEVENTF_KEYUP
event may have side-effects, but they can be avoided by inserting additional events.
The Start menu is triggered when the Win key is pressed and released, except when there is an intervening key event or if it was pressed in combination with another modifier. So instead of inserting just Win-up, insert Ctrl-down, Win-up, Ctrl-up.
Aside from the Start menu, releasing modifier keys might have other side-effects:
Inserting a key-down and key-up (or possibly just a key-up without a prior key-down) with almost any other virtual keycode first will generally prevent any of these hotkeys from activating. One can use an undefined or reserved keycode such as 0xE8, although there is still a risk that another program makes use of it.
There is not a more "straightforward way" for a program to do this without modifying the registry. The ideal solution is to track the keypresses in a table (std::map, Dictionary, etc). The intent of this on MS's part is to prevent viruses/malware from taking control of the keyboard and preventing the user from using important keyboard combos such as WinKey-L and Ctrl-Alt-Delete.
You can, however, remap the keyboard scan codes in the registry if keyboard hooking is not for you. This isn't ideal, since it's hard to reverse (especially if you make a mistake, or your program crashes, or the user uninstalls the application but the registry hack is not reverted). But it does work. Here are some references:
http://www.howtogeek.com/howto/windows-vista/map-any-key-to-any-key-on-windows-xp-vista/
http://www.howtogeek.com/howto/windows-vista/disable-caps-lock-key-in-windows-vista/
http://www.usnetizen.com/fix_capslock.php
I basically solved this exact problem yesterday :) My code is in C#, but it mostly consists of win32 API calls via p/invoke, so it should translate directly to C++.
The solution is to use a Low-Level Keyboard Hook to intercept the initial Windows key KeyDown event (and tell the OS that you handled it so that it won't be passed to other Applications and/or the OS). Then, depending on OS, simulate the Windows key KeyUp event before your input. It sounds like you're half-way there, you just need to intercept the initial KeyDown.
My solution is targeted at Windows Vista and Windows 7, so if you're in XP or below, it's possible that you don't need to send the KeyUp. That's what I'll be testing soon, it may work in both; however, Vista and 7 intercept the windows key more aggressively than XP, hence my suspicions.