From 7b095d7243700cbb8598eecbe4054a2ad5bf7cb6 Mon Sep 17 00:00:00 2001 From: LeeRiva <76054616+LeeRiva@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:51:50 +0200 Subject: [PATCH] Fixed various issues with handling 'extended' keys on the Windows platform - the code now distinguishes between 'left' and 'right' ALT and CTRL modifiers - the code now handles the 'Applications' key (VK_MENU) correctly - added the various keys on the numpad - 'scroll lock' and 'print screen' are now correctly handled --- include/vsg/platform/win32/Win32_Window.h | 16 +++++++-- src/vsg/platform/win32/Win32_Window.cpp | 44 +++++++++++------------ 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/include/vsg/platform/win32/Win32_Window.h b/include/vsg/platform/win32/Win32_Window.h index 3d8a2149b9..9640a9f5c3 100644 --- a/include/vsg/platform/win32/Win32_Window.h +++ b/include/vsg/platform/win32/Win32_Window.h @@ -39,7 +39,17 @@ namespace vsgWin32 bool getKeySymbol(WPARAM wParam, LPARAM lParam, vsg::KeySymbol& keySymbol, vsg::KeySymbol& modifiedKeySymbol, vsg::KeyModifier& keyModifier) { uint16_t modifierMask = 0; - uint32_t virtualKey = ::MapVirtualKeyEx((lParam >> 16) & 0xff, MAPVK_VSC_TO_VK_EX, ::GetKeyboardLayout(0)); + + // see https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#keystroke-message-flags + WORD vkCode = LOWORD(wParam); // virtual-key code + WORD keyFlags = HIWORD(lParam); + WORD scanCode = LOBYTE(keyFlags); // scan code + BOOL isExtendedKey = (keyFlags & KF_EXTENDED) == KF_EXTENDED; // extended-key flag, 1 if scancode has 0xE0 prefix + + if (isExtendedKey) + scanCode = MAKEWORD(scanCode, 0xE0); + + uint32_t virtualKey = ::MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK_EX, ::GetKeyboardLayout(0)); auto itr = _vk2vsg.find(virtualKey); if (itr == _vk2vsg.end()) @@ -80,7 +90,7 @@ namespace vsgWin32 break; default: - virtualKey = static_cast(wParam); + virtualKey = static_cast(wParam); break; } @@ -102,7 +112,7 @@ namespace vsgWin32 // The actual keystroke is what we get after the ::ToAscii call char asciiKey[2]; - int32_t numChars = ::ToAscii(static_cast(wParam), (lParam >> 16) & 0xff, keyState, reinterpret_cast(asciiKey), 0); + int32_t numChars = ::ToAsciiEx(static_cast(wParam), scanCode, keyState, reinterpret_cast(asciiKey), 0, ::GetKeyboardLayout(0)); if (numChars == 1) { // it is indeed an ascii character. 0-127 diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index bc30a21d7f..b6680cd8ef 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -122,7 +122,7 @@ KeyboardMap::KeyboardMap() {VK_RETURN , KEY_Return}, {VK_SHIFT , KEY_Undefined}, {VK_CONTROL , KEY_Undefined}, - {VK_MENU , KEY_Undefined}, + {VK_MENU , KEY_Alt_L}, {VK_PAUSE , KEY_Pause}, {VK_CAPITAL , KEY_Undefined}, {VK_KANA , KEY_Undefined}, @@ -149,7 +149,7 @@ KeyboardMap::KeyboardMap() {VK_RIGHT , KEY_Right }, {VK_DOWN , KEY_Down }, {VK_SELECT , KEY_Select}, - {VK_PRINT , KEY_Print}, + {VK_SNAPSHOT , KEY_Print}, {VK_EXECUTE , KEY_Execute}, {VK_SNAPSHOT , KEY_Undefined}, {VK_INSERT , KEY_Insert}, @@ -157,24 +157,24 @@ KeyboardMap::KeyboardMap() {VK_HELP , KEY_Help}, {VK_LWIN , KEY_Super_L}, {VK_RWIN , KEY_Super_R}, - {VK_APPS , KEY_Undefined}, + {VK_APPS , KEY_Menu}, {VK_SLEEP , KEY_Undefined}, - {VK_NUMPAD0 , KEY_Undefined}, - {VK_NUMPAD1 , KEY_Undefined}, - {VK_NUMPAD2 , KEY_Undefined}, - {VK_NUMPAD3 , KEY_Undefined}, - {VK_NUMPAD4 , KEY_Undefined}, - {VK_NUMPAD5 , KEY_Undefined}, - {VK_NUMPAD6 , KEY_Undefined}, - {VK_NUMPAD7 , KEY_Undefined}, - {VK_NUMPAD8 , KEY_Undefined}, - {VK_NUMPAD9 , KEY_Undefined}, - {VK_MULTIPLY , KEY_Undefined}, - {VK_ADD , KEY_Undefined}, - {VK_SEPARATOR , KEY_Undefined}, - {VK_SUBTRACT , KEY_Undefined}, - {VK_DECIMAL , KEY_Undefined}, - {VK_DIVIDE , KEY_Undefined}, + {VK_NUMPAD0 , KEY_KP_0}, + {VK_NUMPAD1 , KEY_KP_1}, + {VK_NUMPAD2 , KEY_KP_2}, + {VK_NUMPAD3 , KEY_KP_3}, + {VK_NUMPAD4 , KEY_KP_4}, + {VK_NUMPAD5 , KEY_KP_5}, + {VK_NUMPAD6 , KEY_KP_6}, + {VK_NUMPAD7 , KEY_KP_7}, + {VK_NUMPAD8 , KEY_KP_8}, + {VK_NUMPAD9 , KEY_KP_9}, + {VK_MULTIPLY , KEY_KP_Multiply}, + {VK_ADD , KEY_KP_Add}, + {VK_SEPARATOR , KEY_KP_Separator}, + {VK_SUBTRACT , KEY_KP_Subtract}, + {VK_DECIMAL , KEY_KP_Decimal}, + {VK_DIVIDE , KEY_KP_Divide}, {VK_F1 , KEY_F1}, {VK_F2 , KEY_F2}, {VK_F3 , KEY_F3}, @@ -208,13 +208,13 @@ KeyboardMap::KeyboardMap() {VK_NAVIGATION_ACCEPT , KEY_Undefined}, // reserved {VK_NAVIGATION_CANCEL , KEY_Undefined}, // reserved {VK_NUMLOCK , KEY_Undefined}, - {VK_SCROLL , KEY_Undefined}, + {VK_SCROLL , KEY_Scroll_Lock}, {VK_LSHIFT , KEY_Shift_L}, {VK_RSHIFT , KEY_Shift_R}, {VK_LCONTROL , KEY_Control_L}, {VK_RCONTROL , KEY_Control_R}, - {VK_LMENU , KEY_Menu}, - {VK_RMENU , KEY_Menu}, + {VK_LMENU , KEY_Alt_L}, + {VK_RMENU , KEY_Alt_R}, {VK_BROWSER_BACK , KEY_Undefined}, {VK_BROWSER_FORWARD , KEY_Undefined}, {VK_BROWSER_REFRESH , KEY_Undefined},