0

I have the virtual key and scan code for a particular character (in this case 'つ') and I would like to convert it back to the Japanese character. How should I go about doing it? I've searched and tried the below code. However, it's not working... It only works for if the characters are ASCII.

FYI.

  1. I am only saving the VK/SC and not generating a keypress directly so I can't work with WM_CHAR.
  2. The 'Z' key on a Japanese keyboard generates 'つ'

Here are the references: C++ Win32: Converting scan code to Unicode character How to translate a virtual-key code to char (depending on locale)? How to convert VK scan codes to appropriate character for language selected How to translate a virtual-key code to char (depending on locale)?

HKL hkl = GetKeyboardLayout(0);
BYTE ks[256] = {};
GetKeyboardState(ks);
uint virtualKeyCode = VkKeyScanEx(L'つ', hkl);
uint scanCode = 44;

uint16_t sc = MapVirtualKeyW(virtualKeyCode, MAPVK_VK_TO_VSC_EX);
const uint32_t flags = 1 << 2; // Do not change keyboard state of this thread
static uint8_t state[256] = { 0 };
state[VK_SHIFT] = false << 7; // Modifiers set the high-order bit when pressed

qDebug() << (unsigned int)'つ';
wchar_t unicodeChar;
if (ToUnicode(virtualKeyCode, sc, state, &unicodeChar, 1, flags) == 1)
    qDebug() << QString::fromUtf8(QByteArray(reinterpret_cast<const char*>(&unicodeChar), 2));

unsigned short result = 0;
qDebug() << ToUnicodeEx(virtualKeyCode, scanCode, ks, reinterpret_cast<LPWSTR>(&result), (int)2, (uint)0, hkl);
qDebug() << "TEST" << result;

Output:

14909860 // (unsigned int)'つ';
0        // return value of tounicode()
TEST 0   //result
Xenius
  • 23
  • 2
  • What value is `virtualKeyCode`? I cannot get the correct `virtualKeyCode` value. `VkKeyScanEx` return 0xffff. When setting `virtualKeyCode = 0x5A`, the code run as expected. – YangXiaoPo-MSFT Jun 09 '22 at 09:55
  • @YangXiaoPo-MSFT Oh right, virtualKeyCode does in fact equals to 0xffff. Yup. I do know 0x5A works. So does the other keys on a US keyboard. What I was trying to do is: Given virtualkeycode=0x5A and the hkl is an japanese keyboard, it should returns 'つ' but instead, it will return z. Does this have anything to do with Microsoft IME? – Xenius Jun 10 '22 at 02:30
  • Please have a look at [How to translate a virtual-key code to char (depending on locale)?](https://stackoverflow.com/questions/64521296/how-to-translate-a-virtual-key-code-to-char-depending-on-locale). – YangXiaoPo-MSFT Jun 10 '22 at 02:52
  • @YangXiaoPo - MSFT Yes, I've tried that previously. It works with Hebrew character. From all my tests, with the keyboard set to : Hebrew, Arabic, French, Latin, Assames, it correctly translate to the respective characters. However, for language such as Jap/Kor which uses Microsoft IME, it does not. – Xenius Jun 10 '22 at 09:03

2 Answers2

0

It seems there is an IME rather than keyboard layout for Japanese in Windows. enter image description here

Edit: Message from Windows SDK Team in Japan is The KANA character is handled by IME, IME converts it from the scan code. There is no Win32 API to do this conversion, if the customer wants to convert the KANA character from a scan code, they will need to build their own table to convert it themselves.

YangXiaoPo-MSFT
  • 1,589
  • 1
  • 4
  • 22
  • Is there a way to use Microsoft IME api to convert the virtual key code to the respective character? – Xenius Jun 13 '22 at 02:32
  • There is a [ImmGetVirtualKey](https://learn.microsoft.com/en-us/windows/win32/api/imm/nf-imm-immgetvirtualkey) function but *Applications can only get the original virtual key by using this function after receiving the WM_KEYDOWN (VK_PROCESSKEY) message, and before TranslateMessage is called in its own message loop.* – YangXiaoPo-MSFT Jun 13 '22 at 02:41
0

IME is involved in this case. ToUnicode is working with usual keyboard layouts (that have SC/VK/CHAR tables inside their dlls).

AFAIK in Japanese case English keyboard layout is used with Japanese IME on top of it - thats why you cannot simply use ToUnicode to produce Japansese chars.

On the other side - IME injects WM_CHAR messages into your window's message queue after 'TranslateMessage' call. IMEs can be a quite complex. They can produce characters from different sources - keydown, voice, char etc.

Proper way is to process WM_CHAR and do not try to do deal with IME APIs by yourself...

DJm00n
  • 1,083
  • 5
  • 18