OSDN Git Service

Use Win32 API to convert codes between virtual-key and ASCII.
authorKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Tue, 27 Dec 2011 08:04:07 +0000 (17:04 +0900)
committerKazuhiro Fujieda <fujieda@users.sourceforge.jp>
Fri, 13 Jan 2012 03:17:12 +0000 (12:17 +0900)
xkeymacsdll/xkeymacsdll.cpp
xkeymacsdll/xkeymacsdll.h

index d994bd5..28126e3 100644 (file)
@@ -672,19 +672,15 @@ LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lPa
                        memset(szPath, 0, sizeof(szPath));\r
                        goto HOOK;\r
                } else if (nKey && index < MAX_PATH - 1) {\r
-                       BOOL bIsShiftDown = IsDown(VK_SHIFT, FALSE);\r
-                       TCHAR nAscii = 0;\r
-                       do { // 1-127\r
-                               if (a2v(++nAscii) == nKey && bIsShiftDown == IsShift(nAscii)) {\r
-//                                     CUtils::Log("M-x: %#X (%c), %#X (%c)", nKey, nKey, nAscii, nAscii);\r
-                                       if (index < _tcslen(szPath))\r
-                                               memmove(szPath + index + 1, szPath + index, MAX_PATH - index - 1);\r
-                                       szPath[index++] = nAscii;\r
-//                                     CUtils::Log("M-x: %c(%#04x)", nAscii, nAscii);\r
-                                       SetM_xTip(szPath);\r
-                                       goto HOOKX;\r
-                               }\r
-                       } while (nAscii != 127);\r
+                       if (SHORT ascii = ConvVkey(nKey | (static_cast<BYTE>(IsDown(VK_SHIFT, FALSE)) << 8), 1)) {\r
+//                             CUtils::Log("M-x: %#X (%c), %#X (%c)", nKey, nKey, ascii, ascii);\r
+                               if (index < _tcslen(szPath))\r
+                                       memmove(szPath + index + 1, szPath + index, MAX_PATH - index - 1);\r
+                               szPath[index++] = static_cast<TCHAR>(ascii);\r
+//                             CUtils::Log("M-x: %c(%#04x)", ascii, ascii);\r
+                               SetM_xTip(szPath);\r
+                               goto HOOKX;\r
+                       }\r
                }\r
        }\r
 \r
@@ -1206,16 +1202,8 @@ void CXkeymacsDll::CallFunction(int FuncID)
                if (bM_x) {\r
                        if (bVk == VK_RETURN)\r
                                InvokeM_x(szPath);\r
-                       else if (bVk != 0) {\r
-                               TCHAR nAscii = 0;\r
-                               do { // 1-127\r
-                                       if (a2v(++nAscii) == bVk && ((nType & SHIFT) != 0) == IsShift(nAscii)) {\r
-//                                             CUtils::Log("M-x: %#X (%c), %#X (%c)", bVk, bVk, nAscii, nAscii);\r
-                                               szPath[index++] = nAscii;\r
-                                               break;\r
-                                       }\r
-                               } while (nAscii != 127);\r
-                       }\r
+                       else if (bVk != 0)\r
+                               szPath[index++] = static_cast<TCHAR>(ConvVkey((bVk | (nType << 8)) & 0x7ff /* drop CONTROLX */, 1));\r
                        continue;\r
                }\r
                if (!bInitialized) {\r
@@ -1263,8 +1251,6 @@ KeyBind CXkeymacsDll::ParseKey(LPCTSTR& def)
                        }\r
                }\r
        }\r
-       if (IsShift(*def) && !(keybind.nType & (WIN_CTRL | WIN_ALT | WIN_WIN)))\r
-               keybind.nType |= SHIFT;\r
        int i = 0;\r
        for (; i < MAX_KEYNAME; ++i) {\r
                size_t len = _tcslen(KeyNames[i].name);\r
@@ -1273,158 +1259,44 @@ KeyBind CXkeymacsDll::ParseKey(LPCTSTR& def)
                        break;\r
                }\r
        }\r
-       keybind.bVk = i < MAX_KEYNAME ? KeyNames[i].bVk : a2v(*def++);\r
+       if (i < MAX_KEYNAME) {\r
+               keybind.bVk = KeyNames[i].bVk;\r
+               return keybind;\r
+       }\r
+       SHORT r = ConvVkey(*def++, 0);\r
+       if (r & (1 << 8) && !(keybind.nType & (WIN_CTRL | WIN_ALT | WIN_WIN)))\r
+               keybind.nType |= SHIFT;\r
+       keybind.bVk = static_cast<BYTE>(r);\r
        return keybind;\r
 }\r
 \r
-BOOL CXkeymacsDll::IsShift(TCHAR nAscii)\r
+SHORT CXkeymacsDll::ConvVkey(SHORT in, int mode)\r
 {\r
-       switch (nAscii) {\r
-       case _T(' '):\r
-               return FALSE;\r
-       case _T('!'):\r
-       case _T('"'):\r
-       case _T('#'):\r
-       case _T('$'):\r
-       case _T('%'):\r
-       case _T('&'):\r
-               return TRUE;\r
-       case _T('\''):\r
-               return m_Config.Is106Keyboard;\r
-       case _T('('):\r
-       case _T(')'):\r
-       case _T('*'):\r
-       case _T('+'):\r
-               return TRUE;\r
-       case _T(','):\r
-       case _T('-'):\r
-       case _T('.'):\r
-       case _T('/'):\r
-       case _T('0'): case _T('1'): case _T('2'): case _T('3'): case _T('4'): case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'):\r
-               return FALSE;\r
-       case _T(':'):\r
-               return !m_Config.Is106Keyboard;\r
-       case _T(';'):\r
-               return FALSE;\r
-       case _T('<'):\r
-               return TRUE;\r
-       case _T('='):\r
-               return m_Config.Is106Keyboard;\r
-       case _T('>'):\r
-       case _T('?'):\r
-               return TRUE;\r
-       case _T('@'):\r
-               return !m_Config.Is106Keyboard;\r
-       case _T('A'): case _T('B'): case _T('C'): case _T('D'): case _T('E'): case _T('F'): case _T('G'): case _T('H'): case _T('I'): case _T('J'): \r
-       case _T('K'): case _T('L'): case _T('M'): case _T('N'): case _T('O'): case _T('P'): case _T('Q'): case _T('R'): case _T('S'): case _T('T'): \r
-       case _T('U'): case _T('V'): case _T('W'): case _T('X'): case _T('Y'): case _T('Z'): \r
-               return TRUE;\r
-       case _T('['):\r
-       case _T('\\'):\r
-       case _T(']'):\r
-               return FALSE;\r
-       case _T('^'):\r
-               return !m_Config.Is106Keyboard;\r
-       case _T('_'):\r
-               return TRUE;\r
-       case _T('`'):\r
-               return m_Config.Is106Keyboard;\r
-       case _T('a'): case _T('b'): case _T('c'): case _T('d'): case _T('e'): case _T('f'): case _T('g'): case _T('h'): case _T('i'): case _T('j'): \r
-       case _T('k'): case _T('l'): case _T('m'): case _T('n'): case _T('o'): case _T('p'): case _T('q'): case _T('r'): case _T('s'): case _T('t'): \r
-       case _T('u'): case _T('v'): case _T('w'): case _T('x'): case _T('y'): case _T('z'): \r
-               return FALSE;\r
-       case _T('{'):\r
-       case _T('|'):\r
-       case _T('}'):\r
-       case _T('~'):\r
-               return TRUE;\r
-       default:\r
-               return FALSE;\r
+       HKL h = GetKeyboardLayout(0);\r
+       if (mode == 0) { // ASCII to VKey and state\r
+               SHORT r = VkKeyScanEx(static_cast<TCHAR>(in), h);\r
+               if (r < 0) // no key correcpont to the char\r
+                       return 0;\r
+               return r & 0x7ff; // drop state flags of Hankaku and others\r
        }\r
-}\r
-\r
-BYTE CXkeymacsDll::a2v(TCHAR nAscii)\r
-{\r
-       switch (nAscii) {\r
-       case _T(' '):\r
-               return VK_SPACE;\r
-       case _T('!'):\r
-               return '1';\r
-       case _T('"'):\r
-               return m_Config.Is106Keyboard ? '2' : (BYTE) 0xde;      // VK_OEM_7\r
-       case _T('#'):\r
-               return '3';\r
-       case _T('$'):\r
-               return '4';\r
-       case _T('%'):\r
-               return '5';\r
-       case _T('&'):\r
-               return m_Config.Is106Keyboard ? '6' : '7';\r
-       case _T('\''):\r
-               return m_Config.Is106Keyboard ? '7' : (BYTE) 0xde;      // VK_OEM_7\r
-       case _T('('):\r
-               return m_Config.Is106Keyboard ? '8' : '9';\r
-       case _T(')'):\r
-               return m_Config.Is106Keyboard ? '9' : '0';\r
-       case _T('*'):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xba : '8';      // VK_OEM_1\r
-       case _T('+'):\r
-               return 0xbb;    // VK_OEM_PLUS\r
-       case _T(','):\r
-               return 0xbc;    // VK_OEM_COMMA\r
-       case _T('-'):\r
-               return 0xbd;    // VK_OEM_MINUS\r
-       case _T('.'):\r
-               return 0xbe;    // VK_OEM_PERIOD\r
-       case _T('/'):\r
-               return 0xbf;    // VK_OEM_2\r
-       case _T('0'): case _T('1'): case _T('2'): case _T('3'): case _T('4'): case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'):\r
-               return nAscii;\r
-       case _T(':'):\r
-               return 0xba;    // VK_OEM_1\r
-       case _T(';'):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xbb : (BYTE) 0xba;      // VK_OEM_PLUS  VK_OEM_1\r
-       case _T('<'):\r
-               return 0xbc;    // VK_OEM_COMMA\r
-       case _T('='):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xbd : (BYTE) 0xbb;      // VK_OEM_MINUS VK_OEM_PLUS\r
-       case _T('>'):\r
-               return 0xbe;    // VK_OEM_PERIOD\r
-       case _T('?'):\r
-               return 0xbf;    // VK_OEM_2\r
-       case _T('@'):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xc0 : '2';\r
-       case _T('A'): case _T('B'): case _T('C'): case _T('D'): case _T('E'): case _T('F'): case _T('G'): case _T('H'): case _T('I'): case _T('J'): \r
-       case _T('K'): case _T('L'): case _T('M'): case _T('N'): case _T('O'): case _T('P'): case _T('Q'): case _T('R'): case _T('S'): case _T('T'): \r
-       case _T('U'): case _T('V'): case _T('W'): case _T('X'): case _T('Y'): case _T('Z'): \r
-               return nAscii;\r
-       case _T('['):\r
-               return 0xdb;    // VK_OEM_4\r
-       case _T('\\'):\r
-               return 0xdc;    // VK_OEM_5\r
-       case _T(']'):\r
-               return 0xdd;    // VK_OEM_6\r
-       case _T('^'):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xde : '6';      // VK_OEM_7\r
-       case _T('_'):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xe2 : (BYTE) 0xbd;      // VK_OEM_102   VK_OEM_MINUS\r
-       case _T('`'):\r
-               return 0xc0;    // VK_OEM_3\r
-       case _T('a'): case _T('b'): case _T('c'): case _T('d'): case _T('e'): case _T('f'): case _T('g'): case _T('h'): case _T('i'): case _T('j'): \r
-       case _T('k'): case _T('l'): case _T('m'): case _T('n'): case _T('o'): case _T('p'): case _T('q'): case _T('r'): case _T('s'): case _T('t'): \r
-       case _T('u'): case _T('v'): case _T('w'): case _T('x'): case _T('y'): case _T('z'): \r
-               return (BYTE) (nAscii - (_T('a') - _T('A')));\r
-       case _T('{'):\r
-               return 0xdb;    // VK_OEM_4\r
-       case _T('|'):\r
-               return 0xdc;    // VK_OEM_5\r
-       case _T('}'):\r
-               return 0xdd;    // VK_OEM_6\r
-       case _T('~'):\r
-               return m_Config.Is106Keyboard ? (BYTE) 0xde : (BYTE) 0xc0;      // VK_OEM_7     VK_OEM_3\r
-       default:\r
+       // VKey and state to ASCII\r
+       const BYTE down = 0x80;\r
+       BYTE state[256] = {0};\r
+       if (in & (1 << 8))\r
+               state[VK_SHIFT] = down;\r
+       if (in & (2 << 8))\r
+               state[VK_CONTROL] = down;\r
+       if (in & (4 << 8))\r
+               state[VK_MENU] = down;\r
+       UINT vkey = in & 0xff;\r
+       state[vkey] = down;\r
+       WORD word = 0;\r
+       int r = ToAsciiEx(vkey, MapVirtualKeyEx(vkey, MAPVK_VK_TO_VSC, h), state, &word, 0, h);\r
+       if (r == 0)\r
                return 0;\r
-       }\r
+       if (r == 1)\r
+               return static_cast<SHORT>(word);\r
+       return static_cast<SHORT>(word >> 8); // drop a dead key\r
 }\r
 \r
 void CXkeymacsDll::SetAccelerate(int nAccelerate)\r
index 2b19f9a..6c2cdb0 100644 (file)
@@ -90,8 +90,7 @@ private:
        static KbdMacro* m_kbdMacro;\r
        static void CallFunction(int nFuncID);\r
        static KeyBind ParseKey(LPCTSTR& def);\r
-       static BOOL IsShift(TCHAR nAscii);\r
-       static BYTE a2v(TCHAR nAscii);\r
+       static SHORT ConvVkey(SHORT in, int mode);\r
        static int m_nAccelerate;\r
        static int m_nKeyboardSpeed;\r
        static HCURSOR m_hCurrentCursor;\r