2

When I switch to Russian layout in Windows 7 and press ; key on the keyboard, I get Russian letter ж on the screen.

I am working on a application where I need to detected pressed keys and draw text on the screen. The requirement is handle all supported languages. This is my code:

// I scan the keyboard for pressed keys
for (short key = KEY_SCAN_MIN; key <= KEY_SCAN_MAX; ++key)
{
    if (GetAsyncKeyState(key) & 0x8000)
    {

// When I detect a pressed key, I convert the scan code into virtual key. 
// The hkl is current keyboard layout parameter, which is Russian.
UINT virtualKey = MapVirtualKeyEx((UINT)key, MAPVK_VK_TO_CHAR, hkl);

// Next I get the state of the keyboard and convert the virtual key 
// into Unicode letter
if (!GetKeyboardState(kbrdState))
{
     continue;
}

// unicode is defined as wchar_t unicode[2];                    
int result = ToUnicodeEx(virtualKey, key, (BYTE*)kbrdState, unicode, 2, 0, hkl);

Everything works great except a couple letters in Russian and I cannot figure out why. One specific letter that does not work is ж. When I attempt to translate its scan code, the translation is б, which is a different Russian letter.

I have spent entire day debugging this issue and do not get too far. When I press this Russian key I get 168 for scan code and 1078 for the virtual key. I did this small test to convert the letter back to the virtual key.

short test = VkKeyScanEx(L'ж', hkl);

The value of variable test is 1078! I do not understand why converting letter ж to virtual key gives me 1078 but converting 1078 virtual key (using the same keyboard layout) gives me б.

Lev Khomich
  • 2,247
  • 14
  • 18
Evgeny
  • 21
  • 1
  • 3
  • I always use [`WM_CHAR`](http://msdn.microsoft.com/en-us/library/ms646276(v=vs.85).aspx) to read scan codes as it does the translation work for you and returns the final character in UTF-16. Works with all languages, even ones with which it takes more than one key press to represent a single character. – Josh Brown Apr 17 '11 at 01:44
  • I figured this out but the web site does not let me to post answer to my own question within 24-hours period. Thank you! – Evgeny Apr 17 '11 at 03:38
  • @Josh Brown: Please post that as an answer so I can upvote it. – Mechanical snail Sep 01 '11 at 21:53
  • `1078` is decimal value of `ж` (codepoint `U+0436`) so `result = ToUnicodeEx( … ,hkl)` returns a correct value. As a side note, `VkKeyScanEx('ж', hkl);` returns `88` using the same `hkl` (I suppose `0x04190419`). – JosefZ Nov 22 '19 at 20:35

1 Answers1

2

I always use WM_CHAR to read scan codes as it does the translation work for you and returns the final character in UTF-16. Works with all languages, even ones with which it takes more than one key press to represent a single character.

Josh Brown
  • 935
  • 1
  • 11
  • 21