Fix generation of key events for non-alphabetic keys under Windows.
Don't hardcode the values of VK_OEM_XXX keys which are completely nonsensical on keyboards with non-US layouts. Use the real unshifted value of the key as its key code instead -- at least if it's a Latin-1 character. Otherwise, use WXK_NONE as the key code and pass the character generated by the key as Unicode character code. Also generate WXK_NONE events for dead keys to avoid confusing them with the corresponding normal key events. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65525 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
e7b12eece0
commit
5844ad30dd
@ -25,7 +25,11 @@ namespace wxMSWKeyboard
|
|||||||
// Translate MSW virtual key code to wx key code. lParam is used to distinguish
|
// Translate MSW virtual key code to wx key code. lParam is used to distinguish
|
||||||
// between numpad and extended version of the keys, extended is assumed by
|
// between numpad and extended version of the keys, extended is assumed by
|
||||||
// default if lParam == 0.
|
// default if lParam == 0.
|
||||||
WXDLLIMPEXP_CORE int VKToWX(WXWORD vk, WXLPARAM lParam = 0);
|
//
|
||||||
|
// Returns WXK_NONE if translation couldn't be done at all (this happens e.g.
|
||||||
|
// for dead keys) or if the key corresponds to a non-ASCII character in which
|
||||||
|
// case uc is filled with its Unicode value.
|
||||||
|
WXDLLIMPEXP_CORE int VKToWX(WXWORD vk, WXLPARAM lParam = 0, wchar_t *uc = NULL);
|
||||||
|
|
||||||
// Translate wxKeyCode enum element (passed as int for compatibility reasons)
|
// Translate wxKeyCode enum element (passed as int for compatibility reasons)
|
||||||
// to MSW virtual key code. isExtended is set to true if the key corresponds to
|
// to MSW virtual key code. isExtended is set to true if the key corresponds to
|
||||||
|
@ -2342,6 +2342,14 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
eventType = wxEVT_COMMAND_LIST_KEY_DOWN;
|
eventType = wxEVT_COMMAND_LIST_KEY_DOWN;
|
||||||
|
|
||||||
event.m_code = wxMSWKeyboard::VKToWX(wVKey);
|
event.m_code = wxMSWKeyboard::VKToWX(wVKey);
|
||||||
|
|
||||||
|
if ( event.m_code == WXK_NONE )
|
||||||
|
{
|
||||||
|
// We can't translate this to a standard key code,
|
||||||
|
// until support for Unicode key codes is added to
|
||||||
|
// wxListEvent we just ignore them.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
event.m_itemIndex =
|
event.m_itemIndex =
|
||||||
|
@ -5665,17 +5665,14 @@ wxWindowMSW::CreateKeyEvent(wxEventType evType,
|
|||||||
wxKeyEvent event(evType);
|
wxKeyEvent event(evType);
|
||||||
InitAnyKeyEvent(event, wParam, lParam);
|
InitAnyKeyEvent(event, wParam, lParam);
|
||||||
|
|
||||||
event.m_keyCode = wxMSWKeyboard::VKToWX(wParam, lParam);
|
event.m_keyCode = wxMSWKeyboard::VKToWX
|
||||||
|
(
|
||||||
|
wParam,
|
||||||
|
lParam
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
if ( event.m_keyCode < WXK_START )
|
, &event.m_uniChar
|
||||||
{
|
|
||||||
// It's an ASCII character, set Unicode key code to the same value
|
|
||||||
// for compatibility (both with the previous versions of wx and with
|
|
||||||
// the other ports), even if it's not very useful for these events as
|
|
||||||
// Unicode character is/should be mostly used by EVT_CHAR handlers.
|
|
||||||
event.m_uniChar = event.m_keyCode;
|
|
||||||
}
|
|
||||||
#endif // wxUSE_UNICODE
|
#endif // wxUSE_UNICODE
|
||||||
|
);
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
@ -6158,32 +6155,76 @@ const struct wxKeyMapping
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
int VKToWX(WXWORD vk, WXLPARAM lParam)
|
int VKToWX(WXWORD vk, WXLPARAM lParam, wchar_t *uc)
|
||||||
{
|
{
|
||||||
|
int wxk;
|
||||||
|
|
||||||
// check the table first
|
// check the table first
|
||||||
for ( size_t n = 0; n < WXSIZEOF(gs_specialKeys); n++ )
|
for ( size_t n = 0; n < WXSIZEOF(gs_specialKeys); n++ )
|
||||||
{
|
{
|
||||||
if ( gs_specialKeys[n].vk == vk )
|
if ( gs_specialKeys[n].vk == vk )
|
||||||
return gs_specialKeys[n].wxk;
|
{
|
||||||
|
wxk = gs_specialKeys[n].wxk;
|
||||||
|
if ( wxk < WXK_START )
|
||||||
|
{
|
||||||
|
// Unicode code for this key is the same as its ASCII code.
|
||||||
|
if ( uc )
|
||||||
|
*uc = wxk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// keys requiring special handling
|
// keys requiring special handling
|
||||||
int wxk;
|
|
||||||
switch ( vk )
|
switch ( vk )
|
||||||
{
|
{
|
||||||
// the mapping for these keys may be incorrect on non-US keyboards so
|
case VK_OEM_1:
|
||||||
// maybe we shouldn't map them to ASCII values at all
|
case VK_OEM_PLUS:
|
||||||
case VK_OEM_1: wxk = ';'; break;
|
case VK_OEM_COMMA:
|
||||||
case VK_OEM_PLUS: wxk = '+'; break;
|
case VK_OEM_MINUS:
|
||||||
case VK_OEM_COMMA: wxk = ','; break;
|
case VK_OEM_PERIOD:
|
||||||
case VK_OEM_MINUS: wxk = '-'; break;
|
case VK_OEM_2:
|
||||||
case VK_OEM_PERIOD: wxk = '.'; break;
|
case VK_OEM_3:
|
||||||
case VK_OEM_2: wxk = '/'; break;
|
case VK_OEM_4:
|
||||||
case VK_OEM_3: wxk = '~'; break;
|
case VK_OEM_5:
|
||||||
case VK_OEM_4: wxk = '['; break;
|
case VK_OEM_6:
|
||||||
case VK_OEM_5: wxk = '\\'; break;
|
case VK_OEM_7:
|
||||||
case VK_OEM_6: wxk = ']'; break;
|
// MapVirtualKey() returns 0 if it fails to convert the virtual
|
||||||
case VK_OEM_7: wxk = '\''; break;
|
// key which nicely corresponds to our WXK_NONE.
|
||||||
|
wxk = ::MapVirtualKey(vk, MAPVK_VK_TO_CHAR);
|
||||||
|
|
||||||
|
if ( HIWORD(wxk) & 0x8000 )
|
||||||
|
{
|
||||||
|
// It's a dead key and we don't return anything at all for them
|
||||||
|
// as we simply don't have any way to indicate the difference
|
||||||
|
// between e.g. a normal "'" and "'" as a dead key -- and
|
||||||
|
// generating the same events for them just doesn't seem like a
|
||||||
|
// good idea.
|
||||||
|
wxk = WXK_NONE;
|
||||||
|
}
|
||||||
|
else // Not a dead key.
|
||||||
|
{
|
||||||
|
// In any case return this as a Unicode character value.
|
||||||
|
if ( uc )
|
||||||
|
*uc = wxk;
|
||||||
|
|
||||||
|
// For compatibility with the old non-Unicode code we continue
|
||||||
|
// returning key codes for Latin-1 characters directly
|
||||||
|
// (normally it would really only make sense to do it for the
|
||||||
|
// ASCII characters, not Latin-1 ones).
|
||||||
|
if ( wxk > 255 )
|
||||||
|
{
|
||||||
|
// But for anything beyond this we can only return the key
|
||||||
|
// value as a real Unicode character, not a wxKeyCode
|
||||||
|
// because this enum values clash with Unicode characters
|
||||||
|
// (e.g. WXK_LBUTTON also happens to be U+012C a.k.a.
|
||||||
|
// "LATIN CAPITAL LETTER I WITH BREVE").
|
||||||
|
wxk = WXK_NONE;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// handle extended keys
|
// handle extended keys
|
||||||
case VK_PRIOR:
|
case VK_PRIOR:
|
||||||
@ -6233,9 +6274,19 @@ int VKToWX(WXWORD vk, WXLPARAM lParam)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// must be a simple alphanumeric key and the values of them
|
if ( (vk >= '0' && vk <= '9') || (vk >= 'A' && vk <= 'Z') )
|
||||||
// coincide in Windows and wx
|
{
|
||||||
wxk = vk;
|
// A simple alphanumeric key and the values of them coincide in
|
||||||
|
// Windows and wx for both ASCII and Unicode codes.
|
||||||
|
wxk = vk;
|
||||||
|
|
||||||
|
if ( uc )
|
||||||
|
*uc = vk;
|
||||||
|
}
|
||||||
|
else // Something we simply don't know about at all.
|
||||||
|
{
|
||||||
|
wxk = WXK_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxk;
|
return wxk;
|
||||||
|
Loading…
Reference in New Issue
Block a user