I tried to call the ToUnicode
inside a low level keyboard hook and print the character(s) it returned. However, it seems that the function doesn't take into account whether special keys, such as shift or caps lock were pressed, so the output is the same as from MapVirtualKey
function with current key's virtual code passed as parameter.
For example (pressed keys => characters returned by ToUnicode
):
abcd => abcd (correct)
[caps lock]abcd => abcd (wrong: should be ABCD)
ab[holding shift]cd => abcd (wrong: should be abCD)
How I call the function (inside the hook procedure):
KBDLLHOOKSTRUCT* pressedKeyInformation = (KBDLLHOOKSTRUCT*)lParam;
BYTE keysStates[256]; // 256 bo tyle virtualnych klawiszy wpisze GetKeyboardState
if(!GetKeyboardState(keysStates))
//error
else
{
WCHAR charactersPressed[8] = {};
int charactersCopiedAmount = ToUnicode(pressedKeyInformation->vkCode, pressedKeyInformation->scanCode, keysStates, charactersPressed, 8, 0);
//std::wcout << ...
}
Later I noticed that calling GetKeyState
with any virtual key code passed as parameter (e.g. VK_RETURN
, VK_SHIFT
) before ToUnicode
causes it to return the correct character, e.g.:
abcd => abcd (correct)
[caps lock]abcd => ABCD (correct)
ab[holding shift]cd => abCD (correct)
It also returns properly keyboard locale dependent keys pressed with AltGr then, e.g. [AltGr]a => ą
.
The above example isn't entirely correct, since there appears another problem - if e.g. caps lock was pressed, the next character still depends on its previous state, only the latter characters are affected, e.g.:
abcd => abcd (correct)
(caps lock is off)[caps lock]abcd => aBCD (wrong: should be ABCD)
(caps lock is off)ab[caps lock]cd => abcD (wrong: should be abCD)
Have you any idea why the GetKeyState(<whatever>)
fixes one of the problems and what's the cause of the latter caps lock (and other special keys) problem?