Commit e899f77f authored by mercury233's avatar mercury233

use ToUnicodeEx instead of ToAsciiEx

parent f07e86dd
...@@ -833,33 +833,48 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ...@@ -833,33 +833,48 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
GetKeyboardState(allKeys); GetKeyboardState(allKeys);
// Ensure current key state reflects this message.
if (wParam < 256)
{
if (event.KeyInput.PressedDown)
allKeys[wParam] |= 0x80;
else
allKeys[wParam] &= ~0x80;
}
event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0); event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0);
event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0); event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0);
// Handle unicode and deadkeys in a way that works since Windows 95 and nt4.0 // Translate to Unicode using the active keyboard layout.
// Using ToUnicode instead would be shorter, but would to my knowledge not run on 95 and 98. // We intentionally don't emit characters on key-up events.
WORD keyChars[2]; if (event.KeyInput.PressedDown)
UINT scanCode = HIWORD(lParam);
int conversionResult = ToAsciiEx(wParam,scanCode,allKeys,keyChars,0,KEYBOARD_INPUT_HKL);
if (conversionResult == 1)
{ {
// ToAsciiEx writes translated ANSI chars into WORDs. Convert only the WCHAR unicodeBuf[8];
// produced byte(s) instead of interpreting the whole WORD array as a byte buffer. unicodeBuf[0] = 0;
char bytes[2]; UINT scanCode = (UINT)((lParam >> 16) & 0xFF);
bytes[0] = static_cast<char>(keyChars[0] & 0xFF); int conversionResult = ToUnicodeEx((UINT)wParam, scanCode, allKeys, unicodeBuf,
bytes[1] = static_cast<char>(keyChars[1] & 0xFF); (int)(sizeof(unicodeBuf) / sizeof(unicodeBuf[0])), 0, KEYBOARD_INPUT_HKL);
WORD unicodeChar = 0;
MultiByteToWideChar( if (conversionResult == -1)
KEYBOARD_INPUT_CODEPAGE, {
MB_PRECOMPOSED, // default // Dead-key: clear the keyboard layout state and do not emit a character.
bytes, ToUnicodeEx((UINT)wParam, scanCode, allKeys, unicodeBuf,
1, (int)(sizeof(unicodeBuf) / sizeof(unicodeBuf[0])), 0, KEYBOARD_INPUT_HKL);
(WCHAR*)&unicodeChar, event.KeyInput.Char = 0;
1 ); }
event.KeyInput.Char = unicodeChar; else if (conversionResult > 0)
{
event.KeyInput.Char = unicodeBuf[0];
}
else
{
event.KeyInput.Char = 0;
}
} }
else else
{
event.KeyInput.Char = 0; event.KeyInput.Char = 0;
}
// allow composing characters like '@' with Alt Gr on non-US keyboards // allow composing characters like '@' with Alt Gr on non-US keyboards
if ((allKeys[VK_MENU] & 0x80) != 0) if ((allKeys[VK_MENU] & 0x80) != 0)
...@@ -984,8 +999,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ...@@ -984,8 +999,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
delete[] buffer; delete[] buffer;
} }
ImmReleaseContext(hWnd, hIMC); ImmReleaseContext(hWnd, hIMC);
// Remove GCS_RESULTSTR to prevent DefWindowProc from generating WM_IME_CHAR // Remove GCS_RESULTSTR to prevent DefWindowProc from generating WM_IME_CHAR
lParam &= ~GCS_RESULTSTR; lParam &= ~GCS_RESULTSTR;
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment