Leaked source code of windows server 2003
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.

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