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.

1426 lines
39 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. CONFIG.c
  5. ++*/
  6. /**********************************************************************/
  7. #include <windows.h>
  8. #include <commdlg.h>
  9. #include <immdev.h>
  10. #include <shlobj.h>
  11. #include "imeattr.h"
  12. #include "imedefs.h"
  13. #include "imerc.h"
  14. #if defined(UNIIME)
  15. #include "uniime.h"
  16. #endif
  17. #if !defined(ROMANIME)
  18. /**********************************************************************/
  19. /* ReverseConversionList() */
  20. /**********************************************************************/
  21. void PASCAL ReverseConversionList(
  22. #if defined(UNIIME)
  23. LPIMEL lpImeL,
  24. #endif
  25. HWND hLayoutListBox)
  26. {
  27. TCHAR szImeName[16];
  28. HKL FAR *lpKLMem;
  29. int nLayouts, i, nIMEs;
  30. LoadString(hInst, IDS_NONE, szImeName, sizeof(szImeName)/sizeof(TCHAR));
  31. SendMessage(hLayoutListBox, LB_INSERTSTRING,
  32. 0, (LPARAM)szImeName);
  33. SendMessage(hLayoutListBox, LB_SELECTSTRING,
  34. 0, (LPARAM)szImeName);
  35. SendMessage(hLayoutListBox, LB_SETITEMDATA,
  36. 0, (LPARAM)(HKL)NULL);
  37. nLayouts = GetKeyboardLayoutList(0, NULL);
  38. lpKLMem = GlobalAlloc(GPTR, sizeof(HKL) * nLayouts);
  39. if (!lpKLMem) {
  40. return;
  41. }
  42. GetKeyboardLayoutList(nLayouts, lpKLMem);
  43. for (i = 0, nIMEs = 0; i < nLayouts; i++) {
  44. HKL hKL;
  45. hKL = *(lpKLMem + i);
  46. if (LOWORD(hKL) != NATIVE_LANGUAGE) {
  47. // not support other language
  48. continue;
  49. }
  50. // NULL hIMC ???????
  51. if (!ImmGetConversionList(hKL, (HIMC)NULL, NULL,
  52. NULL, 0, GCL_REVERSECONVERSION)) {
  53. // this IME not support reverse conversion
  54. continue;
  55. }
  56. if (!ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME,
  57. szImeName)) {
  58. // this IME does not report the IME name
  59. continue;
  60. }
  61. nIMEs++;
  62. SendMessage(hLayoutListBox, LB_INSERTSTRING,
  63. nIMEs, (LPARAM)szImeName);
  64. if (hKL == lpImeL->hRevKL) {
  65. SendMessage(hLayoutListBox, LB_SELECTSTRING, nIMEs,
  66. (LPARAM)szImeName);
  67. }
  68. SendMessage(hLayoutListBox, LB_SETITEMDATA,
  69. nIMEs, (LPARAM)hKL);
  70. }
  71. GlobalFree((HGLOBAL)lpKLMem);
  72. return;
  73. }
  74. #endif
  75. /**********************************************************************/
  76. /* ChangeConfiguration() */
  77. /**********************************************************************/
  78. void PASCAL ChangeConfiguration(
  79. #if defined(UNIIME)
  80. LPIMEL lpImeL,
  81. #endif
  82. HWND hDlg)
  83. {
  84. #if !defined(ROMANIME)
  85. DWORD fdwModeConfig;
  86. DWORD fdwImeMsg;
  87. #if defined(PHON)
  88. int i;
  89. #endif
  90. fdwModeConfig = 0;
  91. fdwImeMsg = 0;
  92. if (IsDlgButtonChecked(hDlg, IDD_OFF_CARET_UI)) {
  93. fdwModeConfig |= MODE_CONFIG_OFF_CARET_UI;
  94. }
  95. if ((lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) ^
  96. (fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)) {
  97. fdwImeMsg |= MSG_IMN_TOGGLE_UI;
  98. }
  99. #if defined(WINAR30)
  100. if (IsDlgButtonChecked(hDlg, IDD_QUICK_KEY)) {
  101. fdwModeConfig |= MODE_CONFIG_QUICK_KEY;
  102. }
  103. if ((lpImeL->fdwModeConfig & MODE_CONFIG_QUICK_KEY) ^
  104. (fdwModeConfig & MODE_CONFIG_QUICK_KEY)) {
  105. fdwImeMsg |= MSG_IMN_UPDATE_QUICK_KEY;
  106. }
  107. #endif
  108. if (IsDlgButtonChecked(hDlg, IDD_PREDICT)) {
  109. fdwModeConfig |= MODE_CONFIG_PREDICT;
  110. }
  111. if ((lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) ^
  112. (fdwModeConfig & MODE_CONFIG_PREDICT)) {
  113. fdwImeMsg |= MSG_IMN_UPDATE_PREDICT;
  114. }
  115. // check BIG5ONLY
  116. if (IsDlgButtonChecked(hDlg, IDD_BIG5ONLY)) {
  117. fdwModeConfig |= MODE_CONFIG_BIG5ONLY;
  118. }
  119. if (lpImeL->fdwModeConfig != fdwModeConfig) {
  120. SetUserSetting(
  121. #if defined(UNIIME)
  122. lpImeL,
  123. #endif
  124. szRegModeConfig, REG_DWORD, (LPBYTE)&fdwModeConfig,
  125. sizeof(fdwModeConfig));
  126. lpImeL->fdwModeConfig = fdwModeConfig;
  127. if (fdwImeMsg & MSG_IMN_TOGGLE_UI) {
  128. InitImeUIData(lpImeL);
  129. }
  130. }
  131. #if defined(PHON)
  132. // get the reading layout
  133. for (i = IDD_DEFAULT_KB; i < IDD_DEFAULT_KB + READ_LAYOUTS; i++) {
  134. if (IsDlgButtonChecked(hDlg, i)) {
  135. break;
  136. }
  137. }
  138. if (i >= IDD_DEFAULT_KB + READ_LAYOUTS) {
  139. i = READ_LAYOUT_DEFAULT;
  140. } else {
  141. i -= IDD_DEFAULT_KB;
  142. }
  143. if ((int)lpImeL->nReadLayout != i) {
  144. SetUserSetting(
  145. #if defined(UNIIME)
  146. lpImeL,
  147. #endif
  148. szRegReadLayout, REG_DWORD, (LPBYTE)&i, sizeof(i));
  149. lpImeL->nReadLayout = (WORD)i;
  150. fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
  151. }
  152. #endif
  153. {
  154. HWND hLayoutListBox;
  155. int iCurSel;
  156. HKL hKL;
  157. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  158. iCurSel = (int)SendMessage(hLayoutListBox, LB_GETCURSEL, 0, 0);
  159. hKL = (HKL)SendMessage(hLayoutListBox, LB_GETITEMDATA,
  160. iCurSel, 0);
  161. if (lpImeL->hRevKL != hKL) {
  162. WORD nRevMaxKey;
  163. lpImeL->hRevKL = hKL;
  164. SetUserSetting(
  165. #if defined(UNIIME)
  166. lpImeL,
  167. #endif
  168. szRegRevKL, REG_DWORD, (LPBYTE)&hKL, sizeof(hKL));
  169. // get the new size
  170. nRevMaxKey = (WORD)ImmEscape(hKL, (HIMC)NULL, IME_ESC_MAX_KEY,
  171. NULL);
  172. if (nRevMaxKey < lpImeL->nMaxKey) {
  173. nRevMaxKey = lpImeL->nMaxKey;
  174. }
  175. if (lpImeL->nRevMaxKey != nRevMaxKey) {
  176. lpImeL->nRevMaxKey = nRevMaxKey;
  177. SetCompLocalData(lpImeL);
  178. fdwImeMsg |= MSG_IMN_COMPOSITIONSIZE;
  179. }
  180. }
  181. }
  182. if (fdwImeMsg) {
  183. HIMC hIMC;
  184. LPINPUTCONTEXT lpIMC;
  185. LPPRIVCONTEXT lpImcP;
  186. hIMC = (HIMC)ImmGetContext(hDlg);
  187. if (!hIMC) {
  188. return;
  189. }
  190. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  191. if (!lpIMC) {
  192. return;
  193. }
  194. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  195. if (!lpImcP) {
  196. goto ChgConfigUnlockIMC;
  197. }
  198. lpImcP->fdwImeMsg |= fdwImeMsg;
  199. GenerateMessage(hIMC, lpIMC, lpImcP);
  200. ImmUnlockIMCC(lpIMC->hPrivate);
  201. ChgConfigUnlockIMC:
  202. ImmUnlockIMC(hIMC);
  203. }
  204. #endif
  205. return;
  206. }
  207. #if !defined(ROMANIME) && !defined(WINIME) && !defined(UNICDIME)
  208. /**********************************************************************/
  209. /* BinaryMatched() */
  210. /**********************************************************************/
  211. BOOL PASCAL BinaryMatched(
  212. LPBYTE lpData1,
  213. LPBYTE lpData2,
  214. UINT uLen)
  215. {
  216. UINT i;
  217. for (i = 0; i < uLen; i++) {
  218. if (*lpData1++ != *lpData2++) {
  219. return (FALSE);
  220. }
  221. }
  222. return (TRUE);
  223. }
  224. /**********************************************************************/
  225. /* VerifyEudcDic() */
  226. /**********************************************************************/
  227. #define TITLE_BUF_SIZE 32
  228. #define MESSAGE_BUF_SIZE 256
  229. BOOL PASCAL VerifyEudcDic(
  230. #if defined(UNIIME)
  231. LPIMEL lpImeL,
  232. #endif
  233. HWND hWnd,
  234. LPTSTR szTitle, // this buffer size must >= TITLE_BUF_SIZE
  235. LPTSTR szMessage) // this buffer size must >= MESSAGE_BUF_SIZE
  236. {
  237. HANDLE hUsrDicFile, hUsrDic;
  238. LPUSRDICIMHDR lpUsrDic;
  239. BOOL fRet;
  240. int i;
  241. DWORD dwSize, dwFileSize;
  242. PSECURITY_ATTRIBUTES psa;
  243. psa = CreateSecurityAttributes();
  244. hUsrDicFile = CreateFile(szMessage, GENERIC_READ,
  245. FILE_SHARE_READ|FILE_SHARE_WRITE,
  246. psa, OPEN_EXISTING,
  247. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  248. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  249. FreeSecurityAttributes(psa);
  250. if (!hWnd) {
  251. return (FALSE);
  252. }
  253. LoadString(hInst, IDS_NOTOPEN_TITLE, szTitle, TITLE_BUF_SIZE);
  254. LoadString(hInst, IDS_NOTOPEN_MSG, szMessage, MESSAGE_BUF_SIZE);
  255. MessageBox(hWnd, szMessage, szTitle,
  256. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  257. return (FALSE);
  258. }
  259. fRet = FALSE;
  260. // we do not need to care about DBCS here, even no problem for DBCS
  261. for (i = 0; i < MAX_PATH; i++) {
  262. if (szMessage[i] == '\\') {
  263. szMessage[i] = '!';
  264. }
  265. }
  266. hUsrDic = CreateFileMapping((HANDLE)hUsrDicFile, psa,
  267. PAGE_READONLY, 0, 0, szMessage);
  268. if (!hUsrDic) {
  269. if (!hWnd) {
  270. goto VerifyCloseEudcDic;
  271. }
  272. LoadString(hInst, IDS_NOTOPEN_TITLE, szTitle, TITLE_BUF_SIZE);
  273. LoadString(hInst, IDS_NOTOPEN_MSG, szMessage, MESSAGE_BUF_SIZE);
  274. MessageBox(hWnd, szMessage, szTitle,
  275. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  276. goto VerifyCloseEudcDicFile;
  277. }
  278. lpUsrDic = MapViewOfFile(hUsrDic, FILE_MAP_READ, 0, 0, 0);
  279. if (!lpUsrDic) {
  280. if (!hWnd) {
  281. goto VerifyCloseEudcDic;
  282. }
  283. LoadString(hInst, IDS_NOTOPEN_TITLE, szTitle, TITLE_BUF_SIZE);
  284. LoadString(hInst, IDS_NOTOPEN_MSG, szMessage, MESSAGE_BUF_SIZE);
  285. MessageBox(hWnd, szMessage, szTitle,
  286. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  287. goto VerifyCloseEudcDic;
  288. }
  289. dwSize = lpUsrDic->ulTableCount * (sizeof(WORD) + sizeof(WORD) +
  290. lpUsrDic->cMethodKeySize) + 256;
  291. dwFileSize = GetFileSize(hUsrDicFile, (LPDWORD)NULL);
  292. if (dwSize != dwFileSize) {
  293. if (!hWnd) {
  294. goto VerifyUnmapEudcDic;
  295. }
  296. LoadString(hInst, IDS_FILESIZE_TITLE, szTitle, TITLE_BUF_SIZE);
  297. LoadString(hInst, IDS_FILESIZE_MSG, szMessage, MESSAGE_BUF_SIZE);
  298. MessageBox(hWnd, szMessage, szTitle,
  299. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  300. } else if (lpUsrDic->uHeaderSize != 256) {
  301. if (!hWnd) {
  302. goto VerifyUnmapEudcDic;
  303. }
  304. LoadString(hInst, IDS_HEADERSIZE_TITLE, szTitle, TITLE_BUF_SIZE);
  305. LoadString(hInst, IDS_HEADERSIZE_MSG, szMessage, MESSAGE_BUF_SIZE);
  306. MessageBox(hWnd, szMessage, szTitle,
  307. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  308. } else if (lpUsrDic->uInfoSize != 13) {
  309. if (!hWnd) {
  310. goto VerifyUnmapEudcDic;
  311. }
  312. LoadString(hInst, IDS_INFOSIZE_TITLE, szTitle, TITLE_BUF_SIZE);
  313. LoadString(hInst, IDS_INFOSIZE_MSG, szMessage, MESSAGE_BUF_SIZE);
  314. MessageBox(hWnd, szMessage, szTitle,
  315. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  316. } else if (lpUsrDic->idCP != NATIVE_CP && lpUsrDic->idCP != ALT_NATIVE_CP) {
  317. if (!hWnd) {
  318. goto VerifyUnmapEudcDic;
  319. }
  320. LoadString(hInst, IDS_CODEPAGE_TITLE, szTitle, TITLE_BUF_SIZE);
  321. LoadString(hInst, IDS_CODEPAGE_MSG, szMessage, MESSAGE_BUF_SIZE);
  322. MessageBox(hWnd, szMessage, szTitle,
  323. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  324. } else if (*(LPUNADWORD)lpUsrDic->idUserCharInfoSign != SIGN_CWIN) {
  325. // != CWIN
  326. if (!hWnd) {
  327. goto VerifyUnmapEudcDic;
  328. }
  329. LoadString(hInst, IDS_CWINSIGN_TITLE, szTitle, TITLE_BUF_SIZE);
  330. LoadString(hInst, IDS_CWINSIGN_MSG, szMessage, MESSAGE_BUF_SIZE);
  331. MessageBox(hWnd, szMessage, szTitle,
  332. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  333. } else if (*(LPUNADWORD)((LPBYTE)lpUsrDic->idUserCharInfoSign +
  334. sizeof(DWORD)) != SIGN__TBL) {
  335. // != _TBL
  336. if (!hWnd) {
  337. goto VerifyUnmapEudcDic;
  338. }
  339. LoadString(hInst, IDS_CWINSIGN_TITLE, szTitle, TITLE_BUF_SIZE);
  340. LoadString(hInst, IDS_CWINSIGN_MSG, szMessage, MESSAGE_BUF_SIZE);
  341. MessageBox(hWnd, szMessage, szTitle,
  342. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  343. } else if (!BinaryMatched((LPBYTE)lpImeL->szIMEName,
  344. (LPBYTE)lpUsrDic->achMethodName, sizeof(lpUsrDic->achMethodName))) {
  345. if (!hWnd) {
  346. goto VerifyUnmapEudcDic;
  347. }
  348. // The IME Name is not match with this file
  349. LoadString(hInst, IDS_UNMATCHED_TITLE, szTitle, TITLE_BUF_SIZE);
  350. LoadString(hInst, IDS_UNMATCHED_MSG, szMessage, MESSAGE_BUF_SIZE);
  351. MessageBox(hWnd, szMessage, szTitle,
  352. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  353. } else {
  354. fRet = TRUE;
  355. }
  356. VerifyUnmapEudcDic:
  357. UnmapViewOfFile(lpUsrDic);
  358. VerifyCloseEudcDic:
  359. CloseHandle(hUsrDic);
  360. VerifyCloseEudcDicFile:
  361. CloseHandle(hUsrDicFile);
  362. FreeSecurityAttributes(psa);
  363. return (fRet);
  364. }
  365. #if 0
  366. /**********************************************************************/
  367. /* GetEudcDic() */
  368. /**********************************************************************/
  369. void PASCAL GetEudcDic(
  370. #if defined(UNIIME)
  371. LPIMEL lpImeL,
  372. #endif
  373. HWND hWnd)
  374. {
  375. TCHAR chReplace;
  376. int i, cbString;
  377. OPENFILENAME ofn;
  378. TCHAR szFilter[64];
  379. TCHAR szFileName[MAX_PATH];
  380. TCHAR szDirName[MAX_PATH];
  381. cbString = LoadString(hInst, IDS_USRDIC_FILTER,
  382. szFilter, sizeof(szFilter)/sizeof(TCHAR));
  383. chReplace = szFilter[cbString - 1];
  384. for (i = 0; szFilter[i]; i++) {
  385. if (szFilter[i] == chReplace) {
  386. szFilter[i] = '\0';
  387. }
  388. }
  389. GetWindowsDirectory(szDirName, sizeof(szDirName));
  390. lstrcpy(szFileName, TEXT("*.TBL"));
  391. // prompt a dialog
  392. ofn.lStructSize = sizeof(OPENFILENAME);
  393. ofn.hwndOwner = (HWND)NULL;
  394. ofn.lpstrFilter = szFilter;
  395. ofn.lpstrCustomFilter = NULL;
  396. ofn.nMaxCustFilter = 0;
  397. ofn.nFilterIndex = 1;
  398. ofn.lpstrFile = szFileName;
  399. ofn.nMaxFile = sizeof(szFileName) / sizeof(TCHAR);
  400. ofn.lpstrFileTitle = NULL;
  401. ofn.nMaxFileTitle = 0;
  402. ofn.lpstrInitialDir = szDirName;
  403. ofn.lpstrTitle = lpImeL->szIMEName;
  404. ofn.Flags = OFN_NOCHANGEDIR|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|
  405. OFN_FILEMUSTEXIST;
  406. ofn.lpstrDefExt = NULL;
  407. if (!GetOpenFileName(&ofn)) {
  408. return;
  409. }
  410. lstrcpy( szDirName, szFileName );
  411. if (!VerifyEudcDic(
  412. #if defined(UNIIME)
  413. lpImeL,
  414. #endif
  415. hWnd, szFilter, szDirName)) {
  416. return;
  417. }
  418. SetWindowText(hWnd, szFileName);
  419. return;
  420. }
  421. /**********************************************************************/
  422. /* ChangeEudcDic() */
  423. /**********************************************************************/
  424. BOOL PASCAL ChangeEudcDic(
  425. #if defined(UNIIME)
  426. LPINSTDATAL lpInstL,
  427. LPIMEL lpImeL,
  428. #endif
  429. HWND hWnd)
  430. {
  431. BOOL fRet;
  432. TCHAR szFileName[MAX_PATH];
  433. TCHAR szTitle[32];
  434. TCHAR szMessage[MAX_PATH];
  435. #if defined(DEBUG)
  436. // internal error, the data structure need byte alignment
  437. // it should not use WORD or DWORD alignment
  438. if (sizeof(USRDICIMHDR) != 256) {
  439. LoadString(hInst, IDS_INTERNAL_TITLE, szTitle, sizeof(szTitle)/sizeof(TCHAR));
  440. LoadString(hInst, IDS_INTERNAL_MSG, szMessage, sizeof(szMessage)/sizeof(TCHAR));
  441. MessageBox(hWnd, szMessage, szTitle,
  442. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  443. return (FALSE);
  444. }
  445. #endif
  446. GetWindowText(hWnd, szFileName, sizeof(szFileName) / sizeof(TCHAR));
  447. if (!lstrcmp(szFileName, lpImeL->szUsrDic)) {
  448. return (TRUE);
  449. }
  450. if (szFileName[0] == '\0') {
  451. LRESULT lRet;
  452. #if defined(UNIIME)
  453. lRet = UniImeEscape(lpInstL, lpImeL, (HIMC)NULL,
  454. IME_ESC_SET_EUDC_DICTIONARY, szFileName);
  455. #else
  456. lRet = ImeEscape((HIMC)NULL, IME_ESC_SET_EUDC_DICTIONARY, szFileName);
  457. #endif
  458. if (lRet) {
  459. return (TRUE);
  460. } else {
  461. LoadString(hInst, IDS_EUDCDICFAIL_TITLE, szTitle, sizeof(szTitle)/sizeof(TCHAR));
  462. LoadString(hInst, IDS_EUDCDICFAIL_MSG, szMessage, sizeof(szMessage)/sizeof(TCHAR));
  463. MessageBox(hWnd, szMessage, szTitle,
  464. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  465. return (FALSE);
  466. }
  467. }
  468. lstrcpy( szMessage, szFileName );
  469. if (fRet = VerifyEudcDic(
  470. #if defined(UNIIME)
  471. lpImeL,
  472. #endif
  473. hWnd, szTitle, szMessage)) {
  474. LRESULT lRet;
  475. #if defined(UNIIME)
  476. lRet = UniImeEscape(lpInstL, lpImeL, (HIMC)NULL,
  477. IME_ESC_SET_EUDC_DICTIONARY, szFileName);
  478. #else
  479. lRet = ImeEscape((HIMC)NULL, IME_ESC_SET_EUDC_DICTIONARY, szFileName);
  480. #endif
  481. if (lRet) {
  482. fRet = TRUE;
  483. } else {
  484. LoadString(hInst, IDS_EUDCDICFAIL_TITLE, szTitle, sizeof(szTitle)/sizeof(TCHAR));
  485. LoadString(hInst, IDS_EUDCDICFAIL_MSG, szMessage, sizeof(szMessage)/sizeof(TCHAR));
  486. MessageBox(hWnd, szMessage, szTitle,
  487. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  488. }
  489. }
  490. return (fRet);
  491. }
  492. #endif
  493. #endif
  494. /**********************************************************************/
  495. /* ConfigureDlgProc() */
  496. /* Return Value: */
  497. /* TRUE - successful, FALSE - failure */
  498. /**********************************************************************/
  499. INT_PTR CALLBACK ConfigDlgProc( // dialog procedure of configuration
  500. HWND hDlg,
  501. UINT uMessage,
  502. WPARAM wParam,
  503. LPARAM lParam)
  504. {
  505. #if !defined(ROMANIME)
  506. HWND hLayoutListBox;
  507. HIMC hIMC;
  508. static HIMC hOldIMC;
  509. #endif
  510. #if defined(UNIIME)
  511. static LPINSTDATAL lpInstL;
  512. static LPIMEL lpImeL;
  513. #endif
  514. switch (uMessage) {
  515. case WM_INITDIALOG:
  516. #if defined(UNIIME)
  517. lpInstL = (LPINSTDATAL)lParam;
  518. lpImeL = lpInstL->lpImeL;
  519. #endif
  520. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  521. CheckDlgButton(hDlg, IDD_OFF_CARET_UI, BST_CHECKED);
  522. }
  523. #if !defined(ROMANIME)
  524. #if defined(PHON)
  525. CheckRadioButton(hDlg, IDD_DEFAULT_KB,
  526. IDD_DEFAULT_KB + READ_LAYOUTS - 1,
  527. lpImeL->nReadLayout + IDD_DEFAULT_KB);
  528. #endif
  529. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  530. hIMC = ImmCreateContext();
  531. if (hIMC) {
  532. ImmSetOpenStatus(hIMC, FALSE);
  533. hOldIMC = ImmAssociateContext(hLayoutListBox, hIMC);
  534. }
  535. if (!hOldIMC) {
  536. } else if (!hIMC) {
  537. } else {
  538. LPINPUTCONTEXT lpIMC;
  539. POINT ptPos;
  540. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hOldIMC);
  541. if (!lpIMC) {
  542. goto ConfigDlgStatusPosOvr;
  543. }
  544. ptPos = lpIMC->ptStatusWndPos;
  545. ImmUnlockIMC(hOldIMC);
  546. ImmSetStatusWindowPos(hIMC, &ptPos);
  547. }
  548. ConfigDlgStatusPosOvr:
  549. // put all reverse conversion hKL into this list
  550. ReverseConversionList(
  551. #if defined(UNIIME)
  552. lpImeL,
  553. #endif
  554. hLayoutListBox);
  555. if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) {
  556. CheckDlgButton(hDlg, IDD_PREDICT, BST_CHECKED);
  557. }
  558. if ( lpImeL->fdwModeConfig & MODE_CONFIG_BIG5ONLY ) {
  559. CheckDlgButton(hDlg, IDD_BIG5ONLY, BST_CHECKED);
  560. }
  561. #if defined(WINAR30)
  562. if (lpImeL->fdwModeConfig & MODE_CONFIG_QUICK_KEY) {
  563. CheckDlgButton(hDlg, IDD_QUICK_KEY, BST_CHECKED);
  564. }
  565. #endif
  566. #endif
  567. SetWindowText(hDlg, lpImeL->szIMEName);
  568. return (TRUE); // don't want to set focus to special control
  569. case WM_COMMAND:
  570. switch (LOWORD(wParam)) {
  571. case IDOK:
  572. ChangeConfiguration(
  573. #if defined(UNIIME)
  574. lpImeL,
  575. #endif
  576. hDlg);
  577. // falling throgh ....
  578. case IDCANCEL:
  579. #if !defined(ROMANIME)
  580. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  581. hIMC = ImmGetContext(hLayoutListBox);
  582. ImmAssociateContext(hLayoutListBox, hOldIMC);
  583. ImmDestroyContext(hIMC);
  584. #endif
  585. EndDialog(hDlg, FALSE);
  586. break;
  587. default:
  588. return (FALSE);
  589. break;
  590. }
  591. return (TRUE);
  592. default:
  593. return (FALSE);
  594. }
  595. return (TRUE);
  596. }
  597. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  598. /**********************************************************************/
  599. /* SetUsrDic */
  600. /* Return Value: */
  601. /* TRUE - successful, FALSE - failure */
  602. /**********************************************************************/
  603. BOOL PASCAL SetUsrDic(
  604. #if defined(UNIIME)
  605. LPINSTDATAL lpInstL,
  606. LPIMEL lpImeL,
  607. #endif
  608. HWND hWnd,
  609. LPCTSTR szEudcDic,
  610. LPTSTR szTitle, // this buffer size must >= TITLE_BUF_SIZE
  611. LPTSTR szMessage) // this buffer size must >= MESSAGE_BUF_SIZE
  612. {
  613. HANDLE hUsrDicFile, hUsrDicMem, hReadUsrDicMem;
  614. BOOL fRet;
  615. DWORD dwUsrDicSize;
  616. UINT uRecLen, uReadLen, uWriteLen;
  617. UINT uUsrDicSize;
  618. PSECURITY_ATTRIBUTES psa;
  619. psa = CreateSecurityAttributes();
  620. hUsrDicFile = CreateFile(szEudcDic, GENERIC_WRITE,
  621. FILE_SHARE_READ|FILE_SHARE_WRITE,
  622. psa, OPEN_ALWAYS,
  623. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  624. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  625. FreeSecurityAttributes(psa);
  626. return (FALSE);
  627. }
  628. fRet = TRUE;
  629. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  630. lstrcpy( szMessage, szEudcDic );
  631. fRet = VerifyEudcDic(
  632. #if defined(UNIIME)
  633. lpImeL,
  634. #endif
  635. hWnd, szTitle, szMessage);
  636. } else {
  637. LPUSRDICIMHDR lpUsrDicImHdr;
  638. DWORD dwWriteBytes;
  639. lpUsrDicImHdr = (LPUSRDICIMHDR)GlobalAlloc(GPTR, sizeof(USRDICIMHDR));
  640. if (!lpUsrDicImHdr) {
  641. fRet = FALSE;
  642. goto SetUsrDicClose;
  643. }
  644. // write the header
  645. lpUsrDicImHdr->uHeaderSize = sizeof(USRDICIMHDR);
  646. lpUsrDicImHdr->idMajor = 1;
  647. lpUsrDicImHdr->ulTableCount = 0;
  648. lpUsrDicImHdr->cMethodKeySize = lpImeL->nMaxKey;
  649. lpUsrDicImHdr->uInfoSize = 13;
  650. lpUsrDicImHdr->idCP = NATIVE_CP;
  651. *(LPUNADWORD)lpUsrDicImHdr->idUserCharInfoSign = SIGN_CWIN;
  652. *(LPUNADWORD)((LPBYTE)lpUsrDicImHdr->idUserCharInfoSign +
  653. sizeof(DWORD)) = SIGN__TBL;
  654. *(LPMETHODNAME)lpUsrDicImHdr->achMethodName =
  655. *(LPMETHODNAME)lpImeL->szIMEName;
  656. WriteFile(hUsrDicFile, lpUsrDicImHdr, sizeof(USRDICIMHDR),
  657. &dwWriteBytes, NULL);
  658. GlobalFree((HANDLE)lpUsrDicImHdr);
  659. }
  660. SetUsrDicClose:
  661. CloseHandle(hUsrDicFile);
  662. if (!fRet) {
  663. FreeSecurityAttributes(psa);
  664. return (fRet);
  665. }
  666. lstrcpy( lpImeL->szUsrDic, szEudcDic );
  667. SetUserSetting(
  668. #if defined(UNIIME)
  669. lpImeL,
  670. #endif
  671. szRegUserDic, REG_SZ, (LPBYTE)lpImeL->szUsrDic,
  672. lstrlen(lpImeL->szUsrDic) * sizeof(TCHAR));
  673. if (!lpImeL->szUsrDicMap[0]) {
  674. UINT i;
  675. TCHAR szDirName[MAX_PATH];
  676. GetTempPath(sizeof(szDirName) / sizeof(TCHAR), szDirName);
  677. // we do not want to create a real file so we GetTickCount()
  678. i = (UINT)GetTickCount();
  679. if (!i) {
  680. i++;
  681. }
  682. GetTempFileName(szDirName, lpImeL->szUIClassName, i, szMessage);
  683. GetFileTitle(szMessage, lpImeL->szUsrDicMap,
  684. sizeof(lpImeL->szUsrDicMap) / sizeof(TCHAR));
  685. }
  686. hUsrDicFile = CreateFile(szEudcDic, GENERIC_READ,
  687. FILE_SHARE_READ|FILE_SHARE_WRITE,
  688. psa, OPEN_EXISTING,
  689. FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  690. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  691. FreeSecurityAttributes(psa);
  692. return (FALSE);
  693. }
  694. uRecLen = lpImeL->nMaxKey + 4;
  695. uReadLen = lpImeL->nMaxKey + 2;
  696. uWriteLen = lpImeL->nSeqBytes + 2;
  697. dwUsrDicSize = GetFileSize(hUsrDicFile, (LPDWORD)NULL);
  698. uUsrDicSize = (UINT)(dwUsrDicSize - 256) / uRecLen * uWriteLen;
  699. // max EUDC chars
  700. hUsrDicMem = CreateFileMapping(INVALID_HANDLE_VALUE,
  701. psa, PAGE_READWRITE, 0, MAX_EUDC_CHARS * uWriteLen + 20,
  702. lpImeL->szUsrDicMap);
  703. if (!hUsrDicMem) {
  704. fRet = FALSE;
  705. goto SetUsrDicCloseRead;
  706. }
  707. if (lpInstL->hUsrDicMem) {
  708. CloseHandle(lpInstL->hUsrDicMem);
  709. lpInstL->hUsrDicMem = NULL;
  710. }
  711. lpInstL->hUsrDicMem = hUsrDicMem;
  712. fRet = ReadUsrDicToMem(
  713. #if defined(UNIIME)
  714. lpInstL, lpImeL,
  715. #endif
  716. hUsrDicFile, dwUsrDicSize, uUsrDicSize, uRecLen, uReadLen, uWriteLen);
  717. if (fRet) {
  718. hReadUsrDicMem = OpenFileMapping(FILE_MAP_READ, FALSE,
  719. lpImeL->szUsrDicMap);
  720. } else {
  721. hReadUsrDicMem = NULL;
  722. uUsrDicSize = 0;
  723. }
  724. CloseHandle(lpInstL->hUsrDicMem);
  725. lpInstL->hUsrDicMem = hReadUsrDicMem;
  726. lpImeL->uUsrDicSize = uUsrDicSize;
  727. SetUsrDicCloseRead:
  728. CloseHandle(hUsrDicFile);
  729. FreeSecurityAttributes(psa);
  730. return (fRet);
  731. }
  732. /**********************************************************************/
  733. /* UsrDicFileName */
  734. /* Return Value: */
  735. /* TRUE - successful, FALSE - failure */
  736. /**********************************************************************/
  737. BOOL PASCAL UsrDicFileName(
  738. #if defined(UNIIME)
  739. LPINSTDATAL lpInstL,
  740. LPIMEL lpImeL,
  741. #endif
  742. HWND hWnd)
  743. {
  744. #if !defined(ROMANIME) && !defined(UNICDIME) && !defined(WINIME)
  745. TCHAR szFileName[MAX_PATH];
  746. TCHAR szTitle[TITLE_BUF_SIZE+1];
  747. TCHAR szMessage[MESSAGE_BUF_SIZE+1];
  748. TCHAR szIMEUserPath[MAX_PATH];
  749. PSECURITY_ATTRIBUTES psa = NULL;
  750. if ( lpImeL->szUsrDic[0] == TEXT('\0') ) {
  751. // psa = CreateSecurityAttributes();
  752. SHGetSpecialFolderPath(NULL, szIMEUserPath, CSIDL_APPDATA , FALSE);
  753. if ( szIMEUserPath[lstrlen(szIMEUserPath) - 1] == TEXT('\\') )
  754. szIMEUserPath[lstrlen(szIMEUserPath) - 1] = TEXT('\0');
  755. lstrcat(szIMEUserPath, TEXT("\\Microsoft") );
  756. // Because CreateDirectory( ) cannot create directory like \AA\BB,
  757. // if AA and BB both do not exist. It can create only one layer of
  758. // directory each time. so we must call twice CreateDirectory( ) for
  759. // \AA\BB
  760. if ( GetFileAttributes(szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  761. CreateDirectory(szIMEUserPath, psa);
  762. lstrcat(szIMEUserPath, TEXT("\\IME") );
  763. if ( GetFileAttributes(szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  764. CreateDirectory(szIMEUserPath, psa);
  765. lstrcat(szIMEUserPath, TEXT("\\") );
  766. lstrcat(szIMEUserPath, lpImeL->szUIClassName);
  767. //
  768. // Create the directory, so that CreateFile( ) can work fine later.
  769. // ortherwise, if the directory does not exist, and you try to create a
  770. // file under that dir, CreateFile will return error.
  771. //
  772. if ( GetFileAttributes(szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  773. CreateDirectory(szIMEUserPath, psa);
  774. // FreeSecurityAttributes(psa);
  775. lstrcpy(szFileName, szIMEUserPath);
  776. lstrcat(szFileName, TEXT("\\"));
  777. lstrcat(szFileName, lpImeL->szUIClassName);
  778. lstrcat(szFileName, TEXT(".TBL") );
  779. }
  780. return SetUsrDic(
  781. #if defined(UNIIME)
  782. lpInstL, lpImeL,
  783. #endif
  784. hWnd, szFileName, szTitle, szMessage);
  785. #endif //!defined(ROMANIME) && !defined(UNICDIME) && !defined(WINIME)
  786. }
  787. #endif
  788. /**********************************************************************/
  789. /* ImeConfigure() / UniImeConfigure() */
  790. /* Return Value: */
  791. /* TRUE - successful, FALSE - failure */
  792. /**********************************************************************/
  793. // configurate the IME setting
  794. #if defined(UNIIME)
  795. BOOL WINAPI UniImeConfigure(
  796. LPINSTDATAL lpInstL,
  797. LPIMEL lpImeL,
  798. #else
  799. BOOL WINAPI ImeConfigure(
  800. #endif
  801. HKL hKL, // hKL of this IME
  802. HWND hAppWnd, // the owner window
  803. DWORD dwMode, // mode of dialog
  804. LPVOID lpData) // the data depend on each mode
  805. {
  806. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  807. BOOL fRet;
  808. #endif
  809. switch (dwMode) {
  810. case IME_CONFIG_GENERAL:
  811. if (lpImeL->lConfigGeneral) {
  812. ResourceLocked(
  813. #if defined(UNIIME)
  814. lpImeL,
  815. #endif
  816. hAppWnd);
  817. return (FALSE);
  818. }
  819. InterlockedIncrement(&lpImeL->lConfigGeneral);
  820. if (lpImeL->lConfigGeneral > 1) {
  821. InterlockedDecrement(&lpImeL->lConfigGeneral);
  822. ResourceLocked(
  823. #if defined(UNIIME)
  824. lpImeL,
  825. #endif
  826. hAppWnd);
  827. return (FALSE);
  828. }
  829. DialogBoxParam(hInst, MAKEINTRESOURCE(IDDG_IME_CONFIG), hAppWnd,
  830. ConfigDlgProc, (LPARAM)lpInstL);
  831. InterlockedDecrement(&lpImeL->lConfigGeneral);
  832. break;
  833. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  834. case IME_CONFIG_SELECTDICTIONARY:
  835. if (lpImeL->lConfigSelectDic) {
  836. ResourceLocked(
  837. #if defined(UNIIME)
  838. lpImeL,
  839. #endif
  840. hAppWnd);
  841. return (FALSE);
  842. }
  843. InterlockedIncrement(&lpImeL->lConfigSelectDic);
  844. if (lpImeL->lConfigSelectDic != 1) {
  845. InterlockedDecrement(&lpImeL->lConfigSelectDic);
  846. ResourceLocked(
  847. #if defined(UNIIME)
  848. lpImeL,
  849. #endif
  850. hAppWnd);
  851. return (FALSE);
  852. }
  853. // currently, we can only select end user dictionary
  854. // because we do not multiple phrase prediction dictionary or
  855. // multiple phrase box.
  856. fRet = UsrDicFileName(
  857. #if defined(UNIIME)
  858. lpInstL, lpImeL,
  859. #endif
  860. hAppWnd);
  861. InterlockedDecrement(&lpImeL->lConfigSelectDic);
  862. return (fRet);
  863. break;
  864. #endif
  865. default:
  866. return (FALSE);
  867. break;
  868. }
  869. return (TRUE);
  870. }
  871. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  872. /**********************************************************************/
  873. /* Input2Sequence */
  874. /* Return Value: */
  875. /* LOWORD - Internal Code, HIWORD - sequence code */
  876. /**********************************************************************/
  877. LRESULT PASCAL Input2Sequence(
  878. #if defined(UNIIME)
  879. LPIMEL lpImeL,
  880. #endif
  881. DWORD uVirtKey,
  882. LPBYTE lpSeqCode)
  883. {
  884. UINT uCharCode;
  885. UINT uSeqCode;
  886. UINT uInternalCode;
  887. char cIndex;
  888. uVirtKey = LOWORD(uVirtKey);
  889. uCharCode = MapVirtualKey(uVirtKey, 2);
  890. if (uCharCode < ' ') {
  891. return (FALSE);
  892. } else if (uCharCode > 'z') {
  893. return (FALSE);
  894. } else {
  895. }
  896. uCharCode = bUpper[uCharCode - ' '];
  897. #if defined(PHON)
  898. uCharCode = bStandardLayout[lpImeL->nReadLayout][uCharCode - ' '];
  899. #endif
  900. if (lpImeL->fCompChar[(uCharCode - ' ') >> 4] &
  901. fMask[uCharCode & 0x000F]) {
  902. } else {
  903. return (FALSE);
  904. }
  905. uSeqCode = lpImeL->wChar2SeqTbl[uCharCode - ' '];
  906. #if defined(PHON)
  907. cIndex = cIndexTable[uCharCode - ' '];
  908. if (*(lpSeqCode + cIndex)) {
  909. uSeqCode |= 0x4000;
  910. }
  911. {
  912. int i;
  913. for (i = 0; i < cIndex; i++) {
  914. if (*(lpSeqCode + i) == 0) {
  915. *(lpSeqCode + i) = 0xFF;
  916. }
  917. }
  918. }
  919. #else
  920. for (cIndex = 0; cIndex < lpImeL->nMaxKey; cIndex++) {
  921. if (*(lpSeqCode + cIndex) == 0) {
  922. break;
  923. }
  924. }
  925. #endif
  926. if (cIndex >= lpImeL->nMaxKey) {
  927. return (FALSE);
  928. } else if (cIndex == lpImeL->nMaxKey - 1) {
  929. uSeqCode |= 0x8000;
  930. } else if (uCharCode == ' ') {
  931. uSeqCode |= 0x8000;
  932. } else {
  933. }
  934. *(lpSeqCode + cIndex) = (BYTE)uSeqCode;
  935. uInternalCode = lpImeL->wSeq2CompTbl[(BYTE)uSeqCode];
  936. #ifndef UNICODE
  937. uInternalCode = HIBYTE(uInternalCode) | (LOBYTE(uInternalCode) << 8);
  938. #endif
  939. return MAKELRESULT(uInternalCode, uSeqCode);
  940. }
  941. #endif
  942. /**********************************************************************/
  943. /* ImeEscape() / UniImeEscape() */
  944. /* Return Value: */
  945. /* TRUE - successful, FALSE - failure */
  946. /**********************************************************************/
  947. #define IME_INPUTKEYTOSEQUENCE 0x22
  948. // escape function of IMEs
  949. #if defined(UNIIME)
  950. LRESULT WINAPI UniImeEscape(
  951. LPINSTDATAL lpInstL,
  952. LPIMEL lpImeL,
  953. #else
  954. LRESULT WINAPI ImeEscape(
  955. #endif
  956. HIMC hIMC,
  957. UINT uSubFunc,
  958. LPVOID lpData)
  959. {
  960. LRESULT lRet;
  961. switch (uSubFunc) {
  962. case IME_ESC_QUERY_SUPPORT:
  963. if (!lpData) {
  964. return (FALSE);
  965. }
  966. switch (*(LPUINT)lpData) {
  967. case IME_ESC_QUERY_SUPPORT:
  968. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  969. case IME_ESC_SEQUENCE_TO_INTERNAL:
  970. case IME_ESC_GET_EUDC_DICTIONARY:
  971. case IME_ESC_SET_EUDC_DICTIONARY:
  972. case IME_INPUTKEYTOSEQUENCE: // will not supported in next version
  973. // and not support 32 bit applications
  974. #endif
  975. case IME_ESC_MAX_KEY:
  976. case IME_ESC_IME_NAME:
  977. case IME_ESC_SYNC_HOTKEY:
  978. #ifndef HANDLE_PRIVATE_HOTKEY
  979. case IME_ESC_PRIVATE_HOTKEY:
  980. #endif
  981. return (TRUE);
  982. default:
  983. return (FALSE);
  984. }
  985. break;
  986. #if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
  987. case IME_ESC_SEQUENCE_TO_INTERNAL:
  988. if (!lpData) {
  989. return (FALSE);
  990. }
  991. if (*(LPDWORD)lpData > lpImeL->nSeqCode) {
  992. return (FALSE);
  993. }
  994. lRet = lpImeL->wSeq2CompTbl[*(LPDWORD)lpData];
  995. #ifndef UNICODE
  996. lRet = HIBYTE(lRet) | (LOBYTE(lRet) << 8);
  997. #endif
  998. return (lRet);
  999. case IME_ESC_GET_EUDC_DICTIONARY:
  1000. if (!lpData) {
  1001. return (FALSE);
  1002. }
  1003. if (lpImeL->szUsrDic[0] == '\0') {
  1004. *(LPTSTR)lpData = '\0';
  1005. return (TRUE);
  1006. }
  1007. lstrcpy(lpData, lpImeL->szUsrDic);
  1008. return (TRUE);
  1009. case IME_ESC_SET_EUDC_DICTIONARY:
  1010. {
  1011. TCHAR szTitle[TITLE_BUF_SIZE];
  1012. TCHAR szMessage[MESSAGE_BUF_SIZE];
  1013. return SetUsrDic(
  1014. #if defined(UNIIME)
  1015. lpInstL, lpImeL,
  1016. #endif
  1017. NULL, lpData, szTitle, szMessage);
  1018. }
  1019. case IME_INPUTKEYTOSEQUENCE:
  1020. return Input2Sequence(
  1021. #if defined(UNIIME)
  1022. lpImeL,
  1023. #endif
  1024. *(LPDWORD)lpData, *(LPBYTE FAR *)((LPBYTE)lpData + sizeof(DWORD)));
  1025. #endif
  1026. case IME_ESC_MAX_KEY:
  1027. return (lpImeL->nMaxKey);
  1028. case IME_ESC_IME_NAME:
  1029. if (!lpData) {
  1030. return (FALSE);
  1031. }
  1032. *(LPMETHODNAME)lpData = *(LPMETHODNAME)lpImeL->szIMEName;
  1033. // append a NULL terminator
  1034. *(LPTSTR)((LPBYTE)lpData + sizeof(METHODNAME)) = '\0';
  1035. return (TRUE);
  1036. case IME_ESC_SYNC_HOTKEY:
  1037. #ifdef HANDLE_PRIVATE_HOTKEY
  1038. {
  1039. UINT i;
  1040. for (i = 0; i < NUM_OF_IME_HOTKEYS; i++) {
  1041. BOOL fRet;
  1042. fRet = ImmGetHotKey(IME_ITHOTKEY_RESEND_RESULTSTR + i,
  1043. &sImeG.uModifiers[i], &sImeG.uVKey[i], NULL);
  1044. if (!fRet) {
  1045. sImeG.uVKey[i] = 0;
  1046. sImeG.uModifiers[i] = 0;
  1047. }
  1048. }
  1049. }
  1050. #endif
  1051. return (TRUE);
  1052. #ifndef HANDLE_PRIVATE_HOTKEY
  1053. case IME_ESC_PRIVATE_HOTKEY: {
  1054. LPINPUTCONTEXT lpIMC;
  1055. lRet = FALSE;
  1056. //
  1057. // early return for invalid input context
  1058. //
  1059. if ( (lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)) == NULL ) {
  1060. return (FALSE);
  1061. }
  1062. //
  1063. // those private hotkeys are effective only in NATIVE mode
  1064. //
  1065. if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|IME_CMODE_EUDC|
  1066. IME_CMODE_NOCONVERSION|IME_CMODE_CHARCODE)) == IME_CMODE_NATIVE) {
  1067. LPPRIVCONTEXT lpImcP;
  1068. LPCOMPOSITIONSTRING lpCompStr;
  1069. if ( (lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate)) == NULL ) {
  1070. ImmUnlockIMC(hIMC);
  1071. return (FALSE);
  1072. }
  1073. switch (*(LPUINT)lpData) {
  1074. case IME_ITHOTKEY_RESEND_RESULTSTR: // 0x200
  1075. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  1076. if ( lpCompStr != NULL ) {
  1077. if (lpCompStr->dwResultStrLen) {
  1078. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  1079. lpImcP->dwCompChar = 0;
  1080. lpImcP->fdwGcsFlag |= GCS_RESULTREAD|GCS_RESULT;
  1081. GenerateMessage(hIMC, lpIMC, lpImcP);
  1082. lRet = TRUE;
  1083. }
  1084. ImmUnlockIMCC(lpIMC->hCompStr);
  1085. }
  1086. break;
  1087. case IME_ITHOTKEY_PREVIOUS_COMPOSITION: // 0x201
  1088. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  1089. if ( lpCompStr == NULL ) {
  1090. break;
  1091. }
  1092. if (lpCompStr->dwResultReadStrLen) {
  1093. DWORD dwResultReadStrLen;
  1094. TCHAR szReading[16];
  1095. dwResultReadStrLen = lpCompStr->dwResultReadStrLen;
  1096. if (dwResultReadStrLen > lpImeL->nMaxKey*sizeof(WCHAR)/sizeof(TCHAR)) {
  1097. dwResultReadStrLen = lpImeL->nMaxKey*sizeof(WCHAR)/sizeof(TCHAR);
  1098. }
  1099. CopyMemory(szReading, (LPBYTE)lpCompStr +
  1100. lpCompStr->dwResultReadStrOffset,
  1101. dwResultReadStrLen * sizeof(TCHAR));
  1102. // NULL termainator
  1103. szReading[dwResultReadStrLen] = TEXT('\0');
  1104. #if defined(UNIIME)
  1105. UniImeSetCompositionString(lpInstL, lpImeL, hIMC, SCS_SETSTR,
  1106. NULL, 0, szReading, dwResultReadStrLen * sizeof(TCHAR));
  1107. #else
  1108. ImeSetCompositionString(hIMC, SCS_SETSTR, NULL, 0, szReading,
  1109. dwResultReadStrLen * sizeof(TCHAR));
  1110. #endif
  1111. GenerateMessage(hIMC, lpIMC, lpImcP);
  1112. lRet = TRUE;
  1113. }
  1114. ImmUnlockIMCC(lpIMC->hCompStr);
  1115. break;
  1116. case IME_ITHOTKEY_UISTYLE_TOGGLE: // 0x202
  1117. lpImeL->fdwModeConfig ^= MODE_CONFIG_OFF_CARET_UI;
  1118. SetUserSetting(
  1119. #if defined(UNIIME)
  1120. lpImeL,
  1121. #endif
  1122. szRegModeConfig, REG_DWORD, (LPBYTE)&lpImeL->fdwModeConfig,
  1123. sizeof(lpImeL->fdwModeConfig));
  1124. InitImeUIData(lpImeL);
  1125. lpImcP->fdwImeMsg |= MSG_IMN_TOGGLE_UI;
  1126. GenerateMessage(hIMC, lpIMC, lpImcP);
  1127. lRet = TRUE;
  1128. break;
  1129. default:
  1130. break;
  1131. }
  1132. ImmUnlockIMCC(lpIMC->hPrivate);
  1133. if ( ! lRet ) {
  1134. MessageBeep((UINT)-1);
  1135. }
  1136. }
  1137. ImmUnlockIMC(hIMC);
  1138. return (lRet);
  1139. }
  1140. #endif // HANDLE_PRIVATE_HOTKEY
  1141. default:
  1142. return (FALSE);
  1143. }
  1144. return (lRet);
  1145. }