I'm trying to use the ToUnicode
function in response to receiving a WM_KEYDOWN
notification, which sounds a lot easier than it is.
Actually, ToUnicode
should superfluous if one simply uses WM_CHAR
, but much to my surprise this actually does not work properly at all! Having used WM_CHAR
in no-common-controls-programs for ages, I've just for the first time ever typed a word with a diacritic accent1 only to realize that dead keys don't work at all!
As in, if I type for example ´e
, then WM_CHAR
is telling me e
when it should be telling é
(similar for other dead key combinations, such asâ
).
ToUnicode
seems like the obvious solution according to its documentation -- unwieldy as it is, its MSDN description page states that it does exactly what I need. It does take an awful lot of parameters, but those too seem straighforward.
The first parameter is simply the virtual key code (wParam
), and the second one can be obtained via MapVirtualKey
.
The third parameter is optional, so not actually needed (that's what "optional" means, isn't it!). Here's the first surprise: If you don't provide the key state, the function simply fails ("no key mapped") for any key you press. Which means an extra call to GetKeyboardState
is needed.
That leaves us with this code:
case WM_KEYDOWN:
BYTE kb[256];
GetKeyboardState(kb);
WCHAR uc[5] = {};
switch(ToUnicode(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), kb, uc, 4, 0))
{
case -1: _putws(L"dead key"); break;
case 0: _putws(L"no idea!"); break;
case 1:
case 2:
case 3:
case 4:
_putws(uc);
}
...
This outputs the proper Unicode character for every normal character (no big achievement, you already get that from WM_CHAR
), but spectacularly fails for dead keys, in the exact same way (one might suspect TranslateMessage
uses ToUnicode
to produce WM_CHAR
).
The shift and alt keys as well as altgr are all honored (so for example typing µ
(altgr-m) will give me µ
just fine), but the diacritic dead keys (like acute or circumflex) won't work. Which means if you were to try to type some French or Spanish words on my German-layout keyboard, you're without luck.
Is there a way to use this function properly, so it works? Or, alternatively, is there a different function that works properly for dead keys?
1Well, obviously not for the first time, but for the first time
in this context.