Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
6.2 KiB

  1. //
  2. // Copyright (c) 1997-1999 Microsoft Corporation.
  3. //
  4. #include <windows.h>
  5. #include <imm.h>
  6. #include "resource.h"
  7. #include "imeblink.h"
  8. #define UNICODE_CP 1200
  9. /************************************************************/
  10. /* MatchImeName() */
  11. /************************************************************/
  12. HKL MatchImeName(
  13. LPCTSTR szStr)
  14. {
  15. TCHAR szImeName[16];
  16. int nLayout;
  17. HKL hKL;
  18. HGLOBAL hMem;
  19. HKL FAR * lpMem;
  20. int i;
  21. nLayout = GetKeyboardLayoutList(0, NULL);
  22. // alloc temp buffer
  23. hMem = GlobalAlloc(GHND, sizeof(HKL) * nLayout);
  24. if (!hMem) {
  25. return (NULL);
  26. }
  27. lpMem = (HKL FAR *)GlobalLock(hMem);
  28. if (!lpMem) {
  29. GlobalFree(hMem);
  30. return (NULL);
  31. }
  32. // get all keyboard layouts, it includes all IMEs
  33. GetKeyboardLayoutList(nLayout, lpMem);
  34. for (i = 0; i < nLayout; i++) {
  35. LRESULT lRet;
  36. hKL = *(lpMem + i);
  37. lRet = ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME, szImeName);
  38. if (!lRet) { // this hKL can not ask name
  39. continue;
  40. }
  41. if (lstrcmp(szStr, szImeName) == 0) {
  42. goto MatchOvr;
  43. }
  44. }
  45. hKL = NULL;
  46. MatchOvr:
  47. GlobalUnlock(hMem);
  48. GlobalFree(hMem);
  49. return (hKL);
  50. }
  51. /************************************************************/
  52. /* RegisterTable() */
  53. /************************************************************/
  54. HKL RegisterTable(
  55. HWND hWnd,
  56. LPUSRDICIMHDR lpIsvUsrDic,
  57. DWORD dwFileSize,
  58. UINT uCodePage)
  59. {
  60. HKL hKL;
  61. // HDC hDC;
  62. // SIZE lTextSize;
  63. // RECT rcProcess;
  64. DWORD i;
  65. LPBYTE lpCurr, lpEnd;
  66. BOOL fRet;
  67. TCHAR szStr[16];
  68. // TCHAR szProcessFmt[32];
  69. // TCHAR szResult[2][32];
  70. // TCHAR szProcessInfo[48];
  71. WORD wInternalCode[256];
  72. WORD wAltInternalCode[256];
  73. #ifdef UNICODE
  74. if (uCodePage == UNICODE_CP) {
  75. LPUNATSTR lpszMethodName;
  76. lpszMethodName = (LPUNATSTR)lpIsvUsrDic->achMethodName;
  77. for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName) / sizeof(TCHAR); i++) {
  78. szStr[i] = *lpszMethodName++;
  79. }
  80. szStr[i] = '\0';
  81. } else {
  82. UINT uLen;
  83. uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
  84. (LPCSTR)lpIsvUsrDic->achMethodName,
  85. sizeof(lpIsvUsrDic->achMethodName),
  86. szStr,
  87. sizeof(szStr) / sizeof(TCHAR));
  88. if (uLen == 0)
  89. {
  90. uCodePage = CP_ACP;
  91. uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
  92. (LPCSTR)lpIsvUsrDic->achMethodName,
  93. sizeof(lpIsvUsrDic->achMethodName),
  94. szStr,
  95. sizeof(szStr) / sizeof(TCHAR));
  96. }
  97. szStr[uLen] = '\0';
  98. }
  99. #else
  100. for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName); i++) {
  101. szStr[i] = lpIsvUsrDic->achMethodName[i];
  102. }
  103. szStr[i] = '\0';
  104. #endif
  105. hKL = MatchImeName(szStr);
  106. if (!hKL) {
  107. return (hKL);
  108. }
  109. // convert sequence code to internal code
  110. for (i = 0; i < sizeof(wInternalCode) / sizeof(WORD); i++) {
  111. LRESULT lRet;
  112. lRet = ImmEscape(hKL, (HIMC)NULL,
  113. IME_ESC_SEQUENCE_TO_INTERNAL, &i);
  114. if (HIWORD(lRet) == 0xFFFF) {
  115. // This is caused by sign extent in Win9x in the return value of
  116. // ImmEscape, it causes an invalid internal code.
  117. wAltInternalCode[i] = 0;
  118. } else {
  119. wAltInternalCode[i] = HIWORD(lRet);
  120. }
  121. wInternalCode[i] = LOWORD(lRet);
  122. #ifndef UNICODE
  123. if (wAltInternalCode[i] > 0xFF) {
  124. // convert to multi byte string
  125. wAltInternalCode[i] = LOBYTE(wAltInternalCode[i]) << 8 |
  126. HIBYTE(wAltInternalCode[i]);
  127. }
  128. if (wInternalCode[i] > 0xFF) {
  129. // convert to multi byte string
  130. wInternalCode[i] = LOBYTE(wInternalCode[i]) << 8 |
  131. HIBYTE(wInternalCode[i]);
  132. }
  133. #endif
  134. }
  135. // check for each record and register it
  136. // get to the first record and skip the Bank ID
  137. lpCurr = (LPBYTE)(lpIsvUsrDic + 1) + sizeof(WORD);
  138. lpEnd = (LPBYTE)lpIsvUsrDic + dwFileSize;
  139. for (; lpCurr < lpEnd;
  140. // internal code + sequence code + Bank ID of next record
  141. lpCurr += sizeof(WORD) + lpIsvUsrDic->cMethodKeySize + sizeof(WORD)) {
  142. int j;
  143. // quick way to init \0 for the register string
  144. *(LPDWORD)szStr = 0;
  145. #ifdef UNICODE
  146. if (uCodePage == UNICODE_CP) {
  147. szStr[0] = *(LPUNATSTR)lpCurr;
  148. } else {
  149. CHAR szMultiByte[4];
  150. szMultiByte[0] = HIBYTE(*(LPTSTR)lpCurr);
  151. szMultiByte[1] = LOBYTE(*(LPTSTR)lpCurr);
  152. MultiByteToWideChar(uCodePage, MB_PRECOMPOSED,
  153. szMultiByte, 2, szStr, 2);
  154. }
  155. #else
  156. szStr[1] = *lpCurr;
  157. szStr[0] = *(lpCurr + 1);
  158. #endif
  159. for (i = 0, j = 0; i < lpIsvUsrDic->cMethodKeySize; i++) {
  160. if (!wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]) {
  161. } else if (wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) {
  162. *(LPTSTR)&szStr[4 + j] = (TCHAR)
  163. wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  164. j += sizeof(TCHAR) / sizeof(TCHAR);
  165. } else {
  166. *(LPWSTR)&szStr[4 + j] = (WCHAR)
  167. wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  168. j += sizeof(WCHAR) / sizeof(TCHAR);
  169. }
  170. if (wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) {
  171. *(LPTSTR)&szStr[4 + j] = (TCHAR)
  172. wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  173. j += sizeof(TCHAR) / sizeof(TCHAR);
  174. } else {
  175. *(LPWSTR)&szStr[4 + j] = (WCHAR)
  176. wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)];
  177. j += sizeof(WCHAR) / sizeof(TCHAR);
  178. }
  179. }
  180. szStr[4 + j] = szStr[4 + j + 1] = szStr[4 + j + 2] = '\0';
  181. fRet = ImmRegisterWord(hKL, &szStr[4], IME_REGWORD_STYLE_EUDC,
  182. szStr);
  183. }
  184. return (hKL);
  185. }