Skip to content

Commit 57d771a

Browse files
Merge pull request #1714 from maisvendoo/master-RRS-winkeys
Fixed incorrect keyboard events process in win32 subsystem
2 parents bb414c8 + 07ad763 commit 57d771a

2 files changed

Lines changed: 52 additions & 53 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,5 @@ DerivedData/
8484
include/glslang
8585
src/vsg/CHANGES.md
8686
src/vsg/vsgTargets.cmake
87-
87+
*.txt.user
88+
*.txt.user.*

include/vsg/platform/win32/Win32_Window.h

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)