@@ -40,93 +40,91 @@ namespace vsgWin32
4040 {
4141 uint16_t modifierMask = 0 ;
4242
43- // see https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#keystroke-message-flags
44- WORD keyFlags = HIWORD (lParam);
45- WORD scanCode = LOBYTE (keyFlags); // scan code
46- BOOL isExtendedKey = (keyFlags & KF_EXTENDED ) == KF_EXTENDED ; // extended-key flag, 1 if scancode has 0xE0 prefix
43+ // Get scancode
44+ uint16_t keyFlags = HIWORD (lParam);
45+ uint16_t scanCode = LOBYTE (lParam);
46+ bool isExtendedKey = (keyFlags & KF_EXTENDED ) == KF_EXTENDED ;
4747
4848 if (isExtendedKey)
49+ {
4950 scanCode = MAKEWORD (scanCode, 0xE0 );
51+ }
52+
53+ // Get virtual key code
54+ uint32_t virtualKey = static_cast <uint32_t >(wParam);
55+
56+ // Left and right modifier detection
57+ if (virtualKey == VK_SHIFT )
58+ {
59+ virtualKey = (scanCode == 0x2A ) ? VK_RSHIFT : VK_LSHIFT ;
60+ }
61+ else if (virtualKey == VK_CONTROL )
62+ {
63+ virtualKey = isExtendedKey ? VK_RCONTROL : VK_LCONTROL ;
64+ }
65+ else if (virtualKey == VK_MENU )
66+ {
67+ virtualKey = isExtendedKey ? VK_RMENU : VK_LMENU ;
68+ }
5069
51- uint32_t virtualKey = ::MapVirtualKeyEx (scanCode, MAPVK_VSC_TO_VK_EX , ::GetKeyboardLayout (0 ));
5270 auto itr = _vk2vsg.find (virtualKey);
5371
5472 if (itr == _vk2vsg.end ())
5573 {
56- // What ever the code was in lParam should translate to a Virtual Key that we know of in _vk2vsg
57- // If we cannot find it, we simply return.
5874 return false ;
5975 }
6076
61- // This is the base-key that was pressed. (i.e., the VSG enum of the physical key pressed).
6277 keySymbol = itr->second ;
6378
64- // Look for any modifiers that may be active.
79+ // Get keys state
6580 BYTE keyState[256 ];
66- if (virtualKey == 0 || !::GetKeyboardState (keyState))
67- {
68- // if virtualKey was undefined or we could not get the keyboard state, simply return.
69- return false ;
70- }
7181
72- // If any of the specific left/right modifier keys are active
73- // add the side-independent vsg modifier to the modifier Mask
74- switch (virtualKey)
82+ if (!::GetKeyboardState (keyState))
7583 {
76- case VK_LSHIFT :
77- case VK_RSHIFT :
78- modifierMask |= vsg::KeyModifier::MODKEY_Shift;
79- break ;
80-
81- case VK_LCONTROL :
82- case VK_RCONTROL :
83- modifierMask |= vsg::KeyModifier::MODKEY_Control;
84- break ;
85-
86- case VK_LMENU :
87- case VK_RMENU :
88- modifierMask |= vsg::KeyModifier::MODKEY_Alt;
89- break ;
90-
91- default :
92- virtualKey = static_cast <uint32_t >(wParam);
93- break ;
84+ return false ;
9485 }
9586
96- // Check if caps lock or numlock is toggled.
87+ // Modifier's flags setting
88+ if (keyState[VK_SHIFT ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Shift;
89+ if (keyState[VK_CONTROL ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Control;
90+ if (keyState[VK_MENU ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Alt;
9791 if (keyState[VK_CAPITAL ] & 0x01 ) modifierMask |= vsg::KeyModifier::MODKEY_CapsLock;
9892 if (keyState[VK_NUMLOCK ] & 0x01 ) modifierMask |= vsg::KeyModifier::MODKEY_NumLock;
9993
100- // Check if the modifier keys are down (these are non-toggle keys, so the high-order bit is relevant!)
101- // again, vsg only has a side-independent modifier
102- if (keyState[VK_LSHIFT ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Shift;
103- if (keyState[VK_RSHIFT ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Shift;
104- if (keyState[VK_LCONTROL ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Control;
105- if (keyState[VK_RCONTROL ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Control;
106- if (keyState[VK_LMENU ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Alt;
107- if (keyState[VK_RMENU ] & 0x80 ) modifierMask |= vsg::KeyModifier::MODKEY_Alt;
108-
109- // This is the final keyModifier
11094 keyModifier = static_cast <vsg::KeyModifier>(modifierMask);
11195
112- // The actual keystroke is what we get after the ::ToAscii call
113- char asciiKey[2 ];
114- int32_t numChars = ::ToAsciiEx (static_cast <UINT >(wParam), scanCode, keyState, reinterpret_cast <WORD *>(asciiKey), 0 , ::GetKeyboardLayout (0 ));
96+ // Get Unicode symbol
97+ wchar_t unicodeChar[2 ] = {0 };
98+ int numChars = ::ToUnicodeEx (virtualKey, scanCode, keyState, unicodeChar, 2 , 0 , ::GetKeyboardLayout (0 ));
99+
115100 if (numChars == 1 )
116101 {
117- // it is indeed an ascii character. 0-127
118- modifiedKeySymbol = static_cast <vsg::KeySymbol>(asciiKey[0 ]);
102+ wchar_t ch = unicodeChar[0 ];
103+
104+ modifiedKeySymbol = mapCharToKeySymbol (ch);
119105 }
120106 else
121107 {
122- // otherwise treat the modifiedKeySymbol as the same as the keySymbol.
123108 modifiedKeySymbol = keySymbol;
124109 }
125110
126111 return true ;
127112 }
128113
129114 protected:
115+
116+ vsg::KeySymbol mapCharToKeySymbol (wchar_t ch)
117+ {
118+ // Special characters (with and without Shift)
119+ switch (ch)
120+ {
121+ case L' \t ' : return vsg::KEY_Tab;
122+ case L' \r ' : return vsg::KEY_Return;
123+ }
124+
125+ return static_cast <vsg::KeySymbol>(ch);
126+ }
127+
130128 VirtualKeyToKeySymbolMap _vk2vsg;
131129 };
132130
0 commit comments