Fix [#25715] [!] key doesn't work on french keyboard with Windows XP/7.\nSubmitted by Eric Le Pape\n\nThe key sent VK_OEM_8, which wasn't handled at all. Added code to detect primary language and handle VK_OEM_8 specifically for certain layouts.

This commit is contained in:
Nathan Letwory
2011-01-24 14:37:10 +00:00
parent 2adb55f2cd
commit f949c567b9
2 changed files with 40 additions and 5 deletions

View File

@@ -144,8 +144,10 @@ GHOST_SystemWin32::GHOST_SystemWin32()
GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
m_displayManager->initialize();
// Check if current keyboard layout uses AltGr
this->keyboardAltGr();
// Check if current keyboard layout uses AltGr and save keylayout ID for
// specialized handling if keys like VK_OEM_*. I.e. french keylayout
// generates VK_OEM_8 for their exclamation key (key left of right shift)
this->handleKeyboardChange();
// Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
OleInitialize(0);
}
@@ -478,6 +480,20 @@ void GHOST_SystemWin32::handleModifierKeys(GHOST_IWindow *window, WPARAM wParam,
}
}
//! note: this function can be extended to include other exotic cases as they arise.
// This function was added in response to bug [#25715]
GHOST_TKey GHOST_SystemWin32::processSpecialKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const
{
GHOST_TKey key = GHOST_kKeyUnknown;
switch(PRIMARYLANGID(m_langId)) {
case LANG_FRENCH:
if(wParam==VK_OEM_8) key = GHOST_kKey1; // on 'normal' shift + 1 to create '!' we also get GHOST_kKey1. ASCII will be '!'.
break;
}
return key;
}
GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const
{
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
@@ -621,6 +637,9 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, L
case VK_NUMLOCK: key = GHOST_kKeyNumLock; break;
case VK_SCROLL: key = GHOST_kKeyScrollLock; break;
case VK_CAPITAL: key = GHOST_kKeyCapsLock; break;
case VK_OEM_8:
key = ((GHOST_SystemWin32*)getSystem())->processSpecialKey(window, wParam, lParam);
break;
default:
key = GHOST_kKeyUnknown;
break;
@@ -719,6 +738,7 @@ GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, bool k
}
event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii);
std::cout << ascii << std::endl;
}
else {
event = 0;
@@ -812,7 +832,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
switch (msg) {
// we need to check if new key layout has AltGr
case WM_INPUTLANGCHANGE:
system->keyboardAltGr();
system->handleKeyboardChange();
break;
////////////////////////////////////////////////////////////////////////
// Keyboard events, processed

View File

@@ -282,6 +282,15 @@ protected:
*/
static GHOST_EventKey* processKeyEvent(GHOST_IWindow *window, bool keyDown, WPARAM wParam, LPARAM lParam);
/**
* Process special keys (VK_OEM_*), to see if current key layout
* gives us anything special, like ! on french AZERTY.
* @param window The window receiving the event (the active window).
* @param wParam The wParam from the wndproc
* @param lParam The lParam from the wndproc
*/
virtual GHOST_TKey processSpecialKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const;
/**
* Creates a window event.
* @param type The type of event to create.
@@ -311,7 +320,7 @@ protected:
/**
* Check current key layout for AltGr
*/
inline virtual void keyboardAltGr(void);
inline virtual void handleKeyboardChange(void);
/**
* Windows call back routine for our window class.
@@ -338,6 +347,8 @@ protected:
__int64 m_start;
/** AltGr on current keyboard layout. */
bool m_hasAltGr;
/** language identifier. */
WORD m_langId;
/** holding hook handle for low-level keyboard handling */
HHOOK m_llKeyboardHook;
bool m_prevKeyStatus[255]; /* VK_* codes 0x01-0xFF, with 0xFF reserved */
@@ -354,11 +365,15 @@ inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys)
m_modifierKeys = keys;
}
inline void GHOST_SystemWin32::keyboardAltGr(void)
inline void GHOST_SystemWin32::handleKeyboardChange(void)
{
HKL keylayout = GetKeyboardLayout(0); // get keylayout for current thread
int i;
SHORT s;
// save the language identifier.
m_langId = LOWORD(keylayout);
for(m_hasAltGr = false, i = 32; i < 256; ++i) {
s = VkKeyScanEx((char)i, keylayout);
// s == -1 means no key that translates passed char code