From Wojciech Lewandowski, "There was a bug in reading modifier keys when focus to GraphicsWindowWin32 was restored. Handler of WM_SETFOCUS was reading pressed keys and sending WM_KEYDOWN messages to fill initial keyboard state. But WM_KEYDOWN messages sent had 0 on lParam and adaptKey method computing state of modifier mask was using lParam to find which modifier keys are down. Obviously when lParam was 0 it was not recording proper modifier masks.
This patch fixes this code sending proper lParam and also makes sure LEFT_CONTROL will be not confused with RIGHT_CONTROL."
This commit is contained in:
@@ -2565,7 +2565,6 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W
|
||||
///////////////////
|
||||
case WM_SETFOCUS :
|
||||
///////////////////
|
||||
|
||||
// Check keys and send a message if the key is pressed when the
|
||||
// focus comes back to the window.
|
||||
// I don't really like this hard-coded loop, but the key codes
|
||||
@@ -2573,8 +2572,32 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W
|
||||
// ok. See winuser.h for the key codes.
|
||||
for (unsigned int i = 0x08; i < 0xFF; i++)
|
||||
{
|
||||
if ((::GetAsyncKeyState(i) & 0x8000) != 0)
|
||||
::SendMessage(hwnd, WM_KEYDOWN, i, 0);
|
||||
// Wojciech Lewandowski: 2011/09/12
|
||||
// Skip CONTROL | MENU | SHIFT tests because we are polling exact left or right keys
|
||||
// above return press for both right and left so we may end up with incosistent
|
||||
// modifier mask if we report left control & right control while only right was pressed
|
||||
LONG rightSideCode = 0;
|
||||
switch( i )
|
||||
{
|
||||
case VK_CONTROL:
|
||||
case VK_SHIFT:
|
||||
case VK_MENU:
|
||||
continue;
|
||||
|
||||
case VK_RCONTROL:
|
||||
case VK_RSHIFT:
|
||||
case VK_RMENU:
|
||||
rightSideCode = 0x01000000;
|
||||
}
|
||||
if ((::GetAsyncKeyState(i) & 0x8000) != 0)
|
||||
{
|
||||
// Compute lParam because subsequent adaptKey will rely on correct lParam
|
||||
UINT scanCode = ::MapVirtualKeyEx( i, 0, ::GetKeyboardLayout(0));
|
||||
// Set Extended Key bit + Scan Code + 30 bit to indicate key was set before sending message
|
||||
// See Windows SDK help on WM_KEYDOWN for explanation
|
||||
LONG lParam = rightSideCode | ( ( scanCode & 0xFF ) << 16 ) | (1 << 30);
|
||||
::SendMessage(hwnd, WM_KEYDOWN, i, lParam );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user