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.

1898 lines
58 KiB

  1. /*++
  2. Copyright (c) 1995-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. DDIS.C
  5. ++*/
  6. #include <windows.h>
  7. #include <windowsx.h>
  8. #include <winerror.h>
  9. #ifdef CROSSREF
  10. #include <winuser.h>
  11. #endif
  12. #include <immdev.h>
  13. #include <string.h>
  14. #include <regstr.h>
  15. #include <ctype.h>
  16. #include <shlobj.h>
  17. #include "imedefs.h"
  18. #include "resource.h"
  19. LPTSTR _rtcschr(LPTSTR string, TCHAR c);
  20. LONG lLock = 0; // this variable is for Lock and Unlock.
  21. //we must init hprivate->mb_name
  22. //*******************************************************************
  23. // InitMbName(hIMC);
  24. //*******************************************************************
  25. void InitMbName(HIMC hIMC)
  26. {
  27. LPINPUTCONTEXT lpIMC;
  28. if (!hIMC) {
  29. return ;
  30. }
  31. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  32. if(!lpIMC){
  33. return;
  34. }
  35. StartEngine(lpIMC->hPrivate);
  36. ImmUnlockIMC(hIMC);
  37. return;
  38. }
  39. // Get the current user's EMB file path, and IME's MB path
  40. // fill global variable sImeG.szIMESystemPath and sImeG.szIMEUserPath
  41. void GetCurrentUserEMBPath( )
  42. {
  43. PSECURITY_ATTRIBUTES psa = NULL;
  44. TCHAR szModuleName[MAX_PATH], *lpszStart, *lpszDot;
  45. int i;
  46. // Get the path for MB and EMB
  47. GetSystemDirectory(sImeG.szIMESystemPath, MAX_PATH);
  48. GetModuleFileName(hInst, szModuleName, sizeof(szModuleName)/sizeof(TCHAR) );
  49. lpszStart = szModuleName + lstrlen(szModuleName) - 1;
  50. while ( (lpszStart != szModuleName) && ( *lpszStart != TEXT('\\') ) ) {
  51. if ( *lpszStart == TEXT('.') ) {
  52. lpszDot = lpszStart;
  53. *lpszDot = TEXT('\0');
  54. }
  55. lpszStart --;
  56. }
  57. if ( *lpszStart == TEXT('\\') ) {
  58. lpszStart ++;
  59. }
  60. if ( lpszStart != szModuleName ) {
  61. for (i=0; i<lstrlen(lpszStart); i++)
  62. szModuleName[i] = lpszStart[i];
  63. szModuleName[i] = TEXT('\0');
  64. }
  65. // psa = CreateSecurityAttributes();
  66. SHGetSpecialFolderPath(NULL,sImeG.szIMEUserPath,CSIDL_APPDATA, FALSE);
  67. if ( sImeG.szIMEUserPath[lstrlen(sImeG.szIMEUserPath)-1] == TEXT('\\') )
  68. sImeG.szIMEUserPath[lstrlen(sImeG.szIMEUserPath) - 1] = TEXT('\0');
  69. // Because CreateDirectory( ) cannot create directory like \AA\BB,
  70. // if AA and BB both do not exist. It can create only one layer of
  71. // directory each time. so we must call twice CreateDirectory( ) for
  72. // \AA\BB
  73. lstrcat(sImeG.szIMEUserPath, TEXT("\\Microsoft") );
  74. if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  75. CreateDirectory(sImeG.szIMEUserPath, psa);
  76. lstrcat(sImeG.szIMEUserPath, TEXT("\\IME") );
  77. if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  78. CreateDirectory(sImeG.szIMEUserPath, psa);
  79. lstrcat(sImeG.szIMEUserPath, TEXT("\\") );
  80. lstrcat(sImeG.szIMEUserPath, szModuleName);
  81. //
  82. // Create the directory, so that CreateFile( ) can work fine later.
  83. // ortherwise, if the directory does not exist, and you try to create
  84. // a file under that dir, CreateFile will return error.
  85. //
  86. if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
  87. CreateDirectory(sImeG.szIMEUserPath, psa);
  88. // FreeSecurityAttributes(psa);
  89. return;
  90. }
  91. /**********************************************************************/
  92. /* ImeInquire() */
  93. /* Return Value: */
  94. /* TRUE - successful, FALSE - failure */
  95. /**********************************************************************/
  96. BOOL WINAPI ImeInquire( // initialized data structure of IME
  97. LPIMEINFO lpImeInfo, // IME specific data report to IMM
  98. LPTSTR lpszWndCls, // the class name of UI
  99. DWORD dwSystemInfoFlags)
  100. {
  101. if (!lpImeInfo) {
  102. return (FALSE);
  103. }
  104. lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT);
  105. lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST|
  106. #ifdef UNICODE
  107. IME_PROP_UNICODE|
  108. #endif
  109. IME_PROP_CANDLIST_START_FROM_1|
  110. IME_PROP_IGNORE_UPKEYS;
  111. lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|
  112. IME_CMODE_CHARCODE|IME_CMODE_SOFTKBD|IME_CMODE_NOCONVERSION|
  113. IME_CMODE_EUDC;
  114. lpImeInfo->fdwSentenceCaps = 0;
  115. // IME will have different distance base multiple of 900 escapement
  116. lpImeInfo->fdwUICaps = UI_CAP_ROT90|UI_CAP_SOFTKBD;
  117. // composition string is the reading string for simple IME
  118. lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR|SCS_CAP_MAKEREAD;
  119. // IME want to decide conversion mode on ImeSelect
  120. lpImeInfo->fdwSelectCaps = (DWORD) 0;
  121. lstrcpy(lpszWndCls, (LPTSTR)szUIClassName);
  122. if ( lpImeL )
  123. {
  124. if ( dwSystemInfoFlags & IME_SYSINFO_WINLOGON )
  125. {
  126. // the client app is running in logon mode.
  127. lpImeL->fWinLogon = TRUE;
  128. }
  129. else
  130. lpImeL->fWinLogon = FALSE;
  131. }
  132. return (TRUE);
  133. }
  134. /**********************************************************************/
  135. /* SetImeDlgProc() */
  136. /* Return Value: */
  137. /* TRUE - successful, FALSE - failure */
  138. /**********************************************************************/
  139. INT_PTR CALLBACK SetImeDlgProc(
  140. HWND hDlg,
  141. UINT uMessage,
  142. WPARAM wParam,
  143. LPARAM lParam)
  144. {
  145. RECT rc;
  146. LONG DlgWidth, DlgHeight;
  147. HIMC hIMC;
  148. #ifdef CROSSREF
  149. HWND hLayoutListBox;
  150. static HIMC hOldIMC;
  151. #endif //CROSSREF
  152. switch (uMessage) {
  153. case WM_INITDIALOG:
  154. hCrtDlg = hDlg;
  155. // reset position
  156. GetWindowRect(hDlg, &rc);
  157. DlgWidth = rc.right - rc.left;
  158. DlgHeight = rc.bottom - rc.top;
  159. SetWindowPos(hDlg, HWND_TOP,
  160. (int)(sImeG.rcWorkArea.right - DlgWidth)/2,
  161. (int)(sImeG.rcWorkArea.bottom - DlgHeight)/2,
  162. (int) 0, (int) 0, SWP_NOSIZE);
  163. // Init CheckFrame State
  164. SetImeCharac(hDlg, (int) 0, SIC_READY, 0);
  165. CheckDlgButton (hDlg, IDC_LX,
  166. MBIndex.IMEChara[0].IC_LX);
  167. CheckDlgButton (hDlg, IDC_CZ,
  168. MBIndex.IMEChara[0].IC_CZ);
  169. CheckDlgButton (hDlg, IDC_TS,
  170. MBIndex.IMEChara[0].IC_TS);
  171. CheckDlgButton (hDlg, IDC_CTS,
  172. MBIndex.IMEChara[0].IC_CTC);
  173. CheckDlgButton (hDlg, IDC_TC,
  174. MBIndex.IMEChara[0].IC_Trace);
  175. //CHP
  176. #ifdef FUSSYMODE
  177. CheckDlgButton (hDlg, IDC_FCSR,
  178. MBIndex.IMEChara[0].IC_FCSR);
  179. CheckDlgButton (hDlg, IDC_FCTS,
  180. MBIndex.IMEChara[0].IC_FCTS);
  181. EnableWindow(GetDlgItem(hDlg, IDC_CZ), FALSE);
  182. #endif //FUSSYMODE
  183. #if defined(COMBO_IME)
  184. if (MBIndex.IMEChara[0].IC_GB)
  185. SendMessage(GetDlgItem(hDlg, IDC_GB),
  186. BM_SETCHECK,
  187. TRUE,
  188. 0L);
  189. else
  190. SendMessage(GetDlgItem(hDlg, IDC_GBK),
  191. BM_SETCHECK,
  192. TRUE,
  193. 0L);
  194. #endif //COMBO_IME
  195. if(MBIndex.IMEChara[0].IC_TS) {
  196. EnableWindow(GetDlgItem(hDlg, IDC_CTS), TRUE);
  197. } else {
  198. EnableWindow(GetDlgItem(hDlg, IDC_CTS), FALSE);
  199. }
  200. #ifdef CROSSREF
  201. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  202. hIMC = ImmGetContext(hLayoutListBox);
  203. if(hIMC){
  204. ImmSetOpenStatus(hIMC, FALSE);
  205. }
  206. ImmReleaseContext(hLayoutListBox, hIMC);
  207. // put all reverse conversion hKL into this list
  208. ReverseConversionList(hLayoutListBox);
  209. #endif //CROSSREF
  210. return (TRUE); // don't want to set focus to special control
  211. case WM_COMMAND:
  212. switch (LOWORD(wParam)) {
  213. case IDOK:
  214. SetImeCharac(hDlg, (int) 0, SIC_SAVE1, 0);
  215. #ifdef CROSSREF
  216. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  217. hIMC = ImmGetContext(hLayoutListBox);
  218. if(hIMC) {
  219. ImmSetOpenStatus(hIMC, TRUE);
  220. }
  221. ImmReleaseContext(hLayoutListBox, hIMC);
  222. #endif //CROSSREF
  223. EndDialog(hDlg, FALSE);
  224. break;
  225. case IDCANCEL:
  226. #ifdef CROSSREF
  227. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  228. hIMC = ImmGetContext(hLayoutListBox);
  229. if(hIMC) {
  230. ImmSetOpenStatus(hIMC, TRUE);
  231. }
  232. ImmReleaseContext(hLayoutListBox, hIMC);
  233. #endif //CROSSREF
  234. EndDialog(hDlg, FALSE);
  235. break;
  236. case IDC_LX:
  237. case IDC_CZ:
  238. case IDC_TS:
  239. case IDC_CTS:
  240. case IDC_TC:
  241. //CHP
  242. #ifdef FUSSYMODE
  243. case IDC_FCSR:
  244. case IDC_FCTS:
  245. #endif //FUSSYMODE
  246. // Set Current InputMode Param(temp)
  247. SetImeCharac(hDlg, ((int)wParam - IDC_LX), SIC_MODIFY, (int) 0);
  248. break;
  249. #if defined(COMBO_IME)
  250. case IDC_GB:
  251. case IDC_GBK:
  252. // Set Current InputMode Param(temp)
  253. SetImeCharac(hDlg, 7, SIC_MODIFY, (int) 0);
  254. break;
  255. #endif //COMBO_IME
  256. default:
  257. return (FALSE);
  258. }
  259. return (TRUE);
  260. case WM_PAINT:
  261. {
  262. GetClientRect(hDlg, &rc);
  263. DrawConvexRect(GetDC(hDlg),
  264. rc.left + 6,
  265. rc.top + 8,
  266. rc.right - 6 - 1,
  267. rc.bottom - 40 - 1);
  268. DrawConvexRectP(GetDC(hDlg),
  269. rc.left + 6,
  270. rc.top + 8,
  271. rc.right - 6,
  272. rc.bottom - 40);
  273. }
  274. return (FALSE);
  275. case WM_CLOSE:
  276. #ifdef CROSSREF
  277. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  278. hIMC = ImmGetContext(hLayoutListBox);
  279. if(hIMC) {
  280. ImmSetOpenStatus(hIMC, TRUE);
  281. }
  282. ImmReleaseContext(hLayoutListBox, hIMC);
  283. #endif //CROSSREF
  284. EndDialog(hDlg, FALSE);
  285. return (TRUE);
  286. default:
  287. return (FALSE);
  288. }
  289. return (TRUE);
  290. }
  291. /**********************************************************************/
  292. /* SetImeCharac() */
  293. /* Return Value: voide */
  294. /* Entry: */
  295. /* code=0, init */
  296. /* code=1, Save temp */
  297. /* code=2, Save resault */
  298. /**********************************************************************/
  299. void SetImeCharac (
  300. HWND hDlg,
  301. int ParamNum,
  302. int Mode,
  303. DWORD ObjImeIndex)
  304. {
  305. HIMC hIMC;
  306. LPINPUTCONTEXT lpIMC;
  307. LPPRIVCONTEXT lpImcP;
  308. #if defined(COMBO_IME)
  309. static DWORD TempParam[8];
  310. #else
  311. static DWORD TempParam[7];
  312. #endif //COMBO_IME
  313. HKEY hKeyCurrVersion;
  314. HKEY hKey;
  315. DWORD retCode;
  316. #ifdef UNICODE
  317. TCHAR ValueName[][9] = {
  318. {0x8BCD, 0x8BED, 0x8054, 0x60F3, 0x0000},
  319. {0x8BCD, 0x8BED, 0x8F93, 0x5165, 0x0000},
  320. {0x9010, 0x6E10, 0x63D0, 0x793A, 0x0000},
  321. {0x5916, 0x7801, 0x63D0, 0x793A, 0x0000},
  322. {0x5149, 0x6807, 0x8DDF, 0x968F, 0x0000},
  323. #else
  324. TCHAR ValueName[][9] = {
  325. TEXT("��������"),
  326. TEXT("��������"),
  327. TEXT("������ʾ"),
  328. TEXT("������ʾ"),
  329. TEXT("��������"),
  330. #endif
  331. TEXT("FC input"),
  332. TEXT("FC aid"),
  333. #if defined(COMBO_IME)
  334. TEXT("GB/GBK")
  335. #endif //COMBO_IME
  336. };
  337. UINT i;
  338. switch (Mode)
  339. {
  340. case SIC_READY:
  341. InitImeCharac(ObjImeIndex);
  342. //CHP
  343. #ifdef FUSSYMODE
  344. if (MBIndex.IMEChara[ObjImeIndex].IC_FCSR)
  345. {
  346. if (MBIndex.IMEChara[ObjImeIndex].IC_FCTS)
  347. EnableWindow(GetDlgItem(hDlg, IDD_LAYOUT_LIST), FALSE);
  348. }
  349. else
  350. EnableWindow(GetDlgItem(hDlg, IDC_FCTS), FALSE);
  351. #endif //FUSSYMODE
  352. TempParam[0] = MBIndex.IMEChara[ObjImeIndex].IC_LX;
  353. TempParam[1] = MBIndex.IMEChara[ObjImeIndex].IC_CZ;
  354. TempParam[2] = MBIndex.IMEChara[ObjImeIndex].IC_TS;
  355. TempParam[3] = MBIndex.IMEChara[ObjImeIndex].IC_CTC;
  356. TempParam[4] = MBIndex.IMEChara[ObjImeIndex].IC_Trace;
  357. //CHP
  358. TempParam[5] = MBIndex.IMEChara[ObjImeIndex].IC_FCSR;
  359. TempParam[6] = MBIndex.IMEChara[ObjImeIndex].IC_FCTS;
  360. #if defined(COMBO_IME)
  361. TempParam[7] = MBIndex.IMEChara[ObjImeIndex].IC_GB;
  362. #endif //COMBO_IME
  363. break;
  364. case SIC_MODIFY:
  365. TempParam[ParamNum] = (TempParam[ParamNum] ^ 0x00000001) & 0x00000001;
  366. if(TempParam[2]) {
  367. EnableWindow(GetDlgItem(hDlg, IDC_CTS), TRUE);
  368. } else {
  369. EnableWindow(GetDlgItem(hDlg, IDC_CTS), FALSE);
  370. TempParam[3] = 0;
  371. CheckDlgButton (hDlg, IDC_CTS, FALSE);
  372. }
  373. //CHP
  374. #ifdef FUSSYMODE
  375. if (TempParam[5])
  376. {
  377. EnableWindow(GetDlgItem(hDlg, IDC_FCTS), TRUE);
  378. if (TempParam[6])
  379. EnableWindow(GetDlgItem(hDlg, IDD_LAYOUT_LIST), FALSE);
  380. else
  381. EnableWindow(GetDlgItem(hDlg, IDD_LAYOUT_LIST), TRUE);
  382. }
  383. else
  384. {
  385. EnableWindow(GetDlgItem(hDlg, IDC_FCTS), FALSE);
  386. EnableWindow(GetDlgItem(hDlg, IDD_LAYOUT_LIST), TRUE);
  387. }
  388. #endif //FUSSYMODE
  389. break;
  390. case SIC_SAVE1:
  391. MBIndex.IMEChara[ObjImeIndex].IC_LX = TempParam[0];
  392. MBIndex.IMEChara[ObjImeIndex].IC_CZ = TempParam[1];
  393. MBIndex.IMEChara[ObjImeIndex].IC_TS = TempParam[2];
  394. MBIndex.IMEChara[ObjImeIndex].IC_CTC = TempParam[3];
  395. MBIndex.IMEChara[ObjImeIndex].IC_Trace = TempParam[4];
  396. // CHP
  397. #ifdef FUSSYMODE
  398. MBIndex.IMEChara[ObjImeIndex].IC_FCSR = TempParam[5];
  399. MBIndex.IMEChara[ObjImeIndex].IC_FCTS = TempParam[6];
  400. #endif //FUSSYMODE
  401. #if defined(COMBO_IME)
  402. MBIndex.IMEChara[ObjImeIndex].IC_GB = TempParam[7];
  403. #endif //COMBO_IME
  404. retCode = OpenReg_PathSetup(&hKeyCurrVersion);
  405. if (retCode) {
  406. RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, &hKeyCurrVersion);
  407. }
  408. if ( hKeyCurrVersion )
  409. retCode = RegCreateKeyEx(hKeyCurrVersion, MBIndex.MBDesc[ObjImeIndex].szName, 0,
  410. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKey, NULL);
  411. else
  412. return;
  413. if ( hKey == NULL )
  414. {
  415. RegCloseKey(hKeyCurrVersion);
  416. return;
  417. }
  418. #if defined(COMBO_IME)
  419. for(i=0; i<8; i++) {
  420. #else
  421. for(i=0; i<7; i++) {
  422. #endif //COMBO_IME
  423. DWORD Value;
  424. switch (i)
  425. {
  426. case 0:
  427. Value = MBIndex.IMEChara[ObjImeIndex].IC_LX;
  428. break;
  429. case 1:
  430. Value = MBIndex.IMEChara[ObjImeIndex].IC_CZ;
  431. break;
  432. case 2:
  433. Value = MBIndex.IMEChara[ObjImeIndex].IC_TS;
  434. break;
  435. case 3:
  436. Value = MBIndex.IMEChara[ObjImeIndex].IC_CTC;
  437. break;
  438. case 4:
  439. Value = MBIndex.IMEChara[ObjImeIndex].IC_Trace;
  440. break;
  441. //CHP
  442. #ifdef FUSSYMODE
  443. case 5:
  444. Value = MBIndex.IMEChara[ObjImeIndex].IC_FCSR;
  445. break;
  446. case 6:
  447. Value = MBIndex.IMEChara[ObjImeIndex].IC_FCTS;
  448. break;
  449. #endif //FUSSYMODE
  450. #if defined(COMBO_IME)
  451. case 7:
  452. Value = MBIndex.IMEChara[ObjImeIndex].IC_GB;
  453. break;
  454. #endif //COMBO_IME
  455. }
  456. if ( hKey != NULL )
  457. {
  458. RegSetValueEx (hKey, ValueName[i],
  459. (DWORD) 0,
  460. REG_DWORD,
  461. (LPBYTE)&Value,
  462. sizeof(DWORD));
  463. }
  464. }
  465. RegCloseKey(hKey);
  466. RegCloseKey(hKeyCurrVersion);
  467. #ifdef CROSSREF
  468. {
  469. HWND hLayoutListBox;
  470. int iCurSel;
  471. HKL hKL;
  472. DWORD retCode;
  473. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  474. iCurSel = (int)SendMessage(hLayoutListBox, LB_GETCURSEL, 0, 0);
  475. hKL = (HKL)SendMessage(hLayoutListBox, LB_GETITEMDATA,
  476. iCurSel, 0);
  477. //CHP
  478. #ifdef FUSSYMODE
  479. if (MBIndex.IMEChara[ObjImeIndex].IC_FCSR &&
  480. MBIndex.IMEChara[ObjImeIndex].IC_FCTS)
  481. hKL = GetKeyboardLayout(0);
  482. #endif //FUSSYMODE
  483. if (MBIndex.hRevKL != hKL) {
  484. WORD nRevMaxKey;
  485. HKEY hKeyAppUser, hKeyIMEUser;
  486. LPPRIVCONTEXT lpImcP;
  487. MBIndex.hRevKL = hKL;
  488. //set reverse layout to registry
  489. retCode = OpenReg_PathSetup(&hKeyAppUser);
  490. if (retCode) {
  491. RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, &hKeyCurrVersion);
  492. }
  493. retCode = RegCreateKeyEx(hKeyAppUser, MBIndex.MBDesc[0].szName, 0,
  494. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKeyIMEUser, NULL);
  495. if (retCode) {
  496. DWORD dwDisposition;
  497. retCode = RegCreateKeyEx (hKeyCurrVersion,
  498. MBIndex.MBDesc[0].szName,
  499. 0,
  500. 0,
  501. REG_OPTION_NON_VOLATILE,
  502. KEY_ALL_ACCESS,
  503. NULL,
  504. &hKey,
  505. &dwDisposition);
  506. }
  507. RegSetValueEx(hKeyIMEUser, szRegRevKL, 0, REG_DWORD, (LPBYTE)&hKL,sizeof(hKL));
  508. // get the new size
  509. nRevMaxKey = (WORD)ImmEscape(hKL, (HIMC)NULL, IME_ESC_MAX_KEY,
  510. NULL);
  511. if (lpImeL->nMaxKey != nRevMaxKey) {
  512. if(lpImeL->nMaxKey < nRevMaxKey)
  513. lpImeL->nMaxKey = nRevMaxKey;
  514. // set the width & height for composition window
  515. lpImeL->rcCompText.right = lpImeL->rcCompText.left +
  516. sImeG.xChiCharWi * ((lpImeL->nMaxKey+2)/2);
  517. lpImeL->xCompWi = lpImeL->rcCompText.right + lpImeL->cxCompBorder * (2 + 4);
  518. //generate message to broadcast change comp win size
  519. hIMC = (HIMC)ImmGetContext(hDlg);
  520. if (!hIMC) {
  521. return;
  522. }
  523. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  524. if (!lpIMC) {
  525. return;
  526. }
  527. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  528. if (!lpImcP) {
  529. goto ChgConfigUnlockIMC;
  530. }
  531. lpImcP->fdwImeMsg |= MSG_IMN_COMPOSITIONPOS;
  532. GenerateMessage(hIMC, lpIMC, lpImcP);
  533. ImmUnlockIMCC(lpIMC->hPrivate);
  534. ChgConfigUnlockIMC:
  535. ImmUnlockIMC(hIMC);
  536. } //end of change nMaxKey
  537. RegSetValueEx(hKeyIMEUser, szRegRevMaxKey, 0, REG_DWORD, (LPBYTE)&lpImeL->nMaxKey,sizeof(DWORD));
  538. RegCloseKey(hKeyAppUser);
  539. RegCloseKey(hKeyIMEUser);
  540. } //end of change RegRevKL
  541. }
  542. #endif //CROSSREF
  543. break;
  544. }
  545. return;
  546. }
  547. #if defined(CROSSREF)
  548. /**********************************************************************/
  549. /* ReverseConversionList() */
  550. /**********************************************************************/
  551. void PASCAL ReverseConversionList(HWND hLayoutListBox)
  552. {
  553. int nLayouts, i, nIMEs;
  554. TCHAR szImeName[16];
  555. HKL FAR *lpKLMem;
  556. LoadString(hInst, IDS_NONE, szImeName, sizeof(szImeName)/sizeof(TCHAR));
  557. SendMessage(hLayoutListBox, LB_INSERTSTRING,
  558. 0, (LPARAM)szImeName);
  559. SendMessage(hLayoutListBox, LB_SELECTSTRING,
  560. 0, (LPARAM)szImeName);
  561. SendMessage(hLayoutListBox, LB_SETITEMDATA,
  562. 0, (LPARAM)(HKL)NULL);
  563. nLayouts = GetKeyboardLayoutList(0, NULL);
  564. lpKLMem = GlobalAlloc(GPTR, sizeof(HKL) * nLayouts);
  565. if (!lpKLMem) {
  566. return;
  567. }
  568. GetKeyboardLayoutList(nLayouts, lpKLMem);
  569. for (i = 0, nIMEs = 0; i < nLayouts; i++) {
  570. HKL hKL;
  571. hKL = *(lpKLMem + i);
  572. if (LOWORD(hKL) != NATIVE_LANGUAGE) {
  573. // not support other language
  574. continue;
  575. }
  576. // NULL hIMC ???????
  577. if (!ImmGetConversionList(hKL, (HIMC)NULL, NULL,
  578. NULL, 0, GCL_REVERSECONVERSION)) {
  579. // this IME not support reverse conversion
  580. continue;
  581. }
  582. if (!ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME,
  583. szImeName)) {
  584. // this IME does not report the IME name
  585. continue;
  586. }
  587. if( lstrcmp(szImeName, MBIndex.MBDesc[0].szName) == 0)
  588. continue;
  589. nIMEs++;
  590. SendMessage(hLayoutListBox, LB_INSERTSTRING,
  591. nIMEs, (LPARAM)szImeName);
  592. if (hKL == MBIndex.hRevKL) {
  593. SendMessage(hLayoutListBox, LB_SELECTSTRING, nIMEs,
  594. (LPARAM)szImeName);
  595. }
  596. SendMessage(hLayoutListBox, LB_SETITEMDATA,
  597. nIMEs, (LPARAM)hKL);
  598. }
  599. GlobalFree((HGLOBAL)lpKLMem);
  600. return;
  601. }
  602. #endif //CROSSREF
  603. #ifdef EUDC
  604. //**********************************************************************
  605. //BOOL EUDCDicName( HWND hWnd)
  606. //**********************************************************************
  607. BOOL EUDCDicName( HWND hWnd)
  608. {
  609. HANDLE hUsrDicFile;
  610. BOOL fRet;
  611. TCHAR szFileName[MAX_PATH];
  612. TCHAR szMapFileName[MAX_PATH];
  613. TCHAR EUDCMB_PathAndName[MAX_PATH];
  614. TCHAR *tepstr;
  615. HKEY hKeyCurrVersion,hKey;
  616. LoadString(hInst, IDS_IMEMBFILENAME, szFileName, MAX_PATH);
  617. tepstr = _rtcschr(szFileName,TEXT('.'));
  618. if ( tepstr != NULL )
  619. lstrcpy(tepstr,TEXT(".EMB"));
  620. if ( sImeG.szIMEUserPath[0] == L'\0' )
  621. {
  622. // Get the right profile path for current user.
  623. GetCurrentUserEMBPath( );
  624. }
  625. StringCchCopy(EUDCMB_PathAndName,ARRAYSIZE(EUDCMB_PathAndName), sImeG.szIMEUserPath);
  626. StringCchCat(EUDCMB_PathAndName, ARRAYSIZE(EUDCMB_PathAndName), TEXT("\\") );
  627. StringCchCat(EUDCMB_PathAndName, ARRAYSIZE(EUDCMB_PathAndName), szFileName);
  628. hUsrDicFile = CreateFile(EUDCMB_PathAndName,
  629. GENERIC_WRITE,
  630. FILE_SHARE_READ|FILE_SHARE_WRITE,
  631. NULL,
  632. OPEN_ALWAYS,
  633. FILE_ATTRIBUTE_NORMAL,
  634. (HANDLE)NULL);
  635. if (hUsrDicFile == INVALID_HANDLE_VALUE) {
  636. return (FALSE);
  637. }
  638. CloseHandle(hUsrDicFile);
  639. lstrcpy(MBIndex.EUDCData.szEudcDictName, EUDCMB_PathAndName);
  640. // if we have already got a map file, we just use it.
  641. if (MBIndex.EUDCData.szEudcMapFileName[0]) {
  642. return (TRUE);
  643. }
  644. // Otherwise, generate the Map File Name, which is Basic Filename plus EUDC
  645. lstrcpy(szMapFileName, szFileName);
  646. tepstr = _rtcschr(szMapFileName,TEXT('.'));
  647. lstrcpy(tepstr, TEXT("EUDC"));
  648. lstrcpy(MBIndex.EUDCData.szEudcMapFileName, szMapFileName);
  649. fRet = OpenReg_PathSetup(&hKeyCurrVersion);
  650. if (fRet) return FALSE;
  651. fRet = OpenReg_User (hKeyCurrVersion,
  652. MBIndex.MBDesc[0].szName,
  653. &hKey);
  654. if (fRet) {
  655. DWORD dwDisposition;
  656. fRet = RegCreateKeyEx (hKeyCurrVersion,
  657. MBIndex.MBDesc[0].szName,
  658. 0,
  659. 0,
  660. REG_OPTION_NON_VOLATILE,
  661. KEY_ALL_ACCESS,
  662. NULL,
  663. &hKey,
  664. &dwDisposition);
  665. if (fRet != ERROR_SUCCESS) return FALSE;
  666. }
  667. fRet = RegSetValueEx (hKey,
  668. szRegEudcDictName,
  669. (DWORD) 0,
  670. REG_SZ,
  671. (const unsigned char *)MBIndex.EUDCData.szEudcDictName,
  672. lstrlen(MBIndex.EUDCData.szEudcDictName)*sizeof(TCHAR));
  673. if (fRet != ERROR_SUCCESS ) return FALSE;
  674. fRet = RegSetValueEx (hKey,
  675. szRegEudcMapFileName,
  676. (DWORD) 0,
  677. REG_SZ,
  678. (const unsigned char *)MBIndex.EUDCData.szEudcMapFileName,
  679. lstrlen(MBIndex.EUDCData.szEudcMapFileName)*sizeof(TCHAR));
  680. if (fRet) return FALSE;
  681. return (TRUE);
  682. }
  683. #endif //EUDC
  684. /**********************************************************************/
  685. /* ImeConfigure() */
  686. /* Return Value: */
  687. /* TRUE - successful, FALSE - failure */
  688. /**********************************************************************/
  689. BOOL WINAPI ImeConfigure( // configurate the IME setting
  690. HKL hKL, // hKL of this IME
  691. HWND hAppWnd, // the owner window
  692. DWORD dwMode, // mode of dialog
  693. LPVOID lpData)
  694. {
  695. switch (dwMode) {
  696. case IME_CONFIG_GENERAL:
  697. DialogBox(hInst, TEXT("SETIME"), hAppWnd, SetImeDlgProc);
  698. break;
  699. #ifdef EUDC
  700. case IME_CONFIG_SELECTDICTIONARY:
  701. return(EUDCDicName(hAppWnd));
  702. break;
  703. #endif //EUDC
  704. default:
  705. return (FALSE);
  706. break;
  707. }
  708. return (TRUE);
  709. }
  710. /**********************************************************************/
  711. /* ForwordConversion() */
  712. /**********************************************************************/
  713. UINT PASCAL ForwordConversion(
  714. HIMC hIMC,
  715. LPCTSTR lpszSrc,
  716. LPCANDIDATELIST lpCandList,
  717. UINT uBufLen)
  718. {
  719. unsigned int i;
  720. LPTSTR wCode;
  721. LPINPUTCONTEXT lpIMC;
  722. UINT uMaxCand;
  723. DWORD dwSize;
  724. wCode = ConverList.szSelectBuffer;
  725. ConverList.szSelectBuffer[0] =TEXT('\0');
  726. ConverList.szInBuffer[0] =TEXT('\0');
  727. ConverList.Candi_Cnt =0;
  728. ConverList.Candi_Pos[0] =TEXT('\0');
  729. if (!hIMC) {
  730. return (0);
  731. }
  732. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  733. if (!lpIMC) {
  734. return (0);
  735. }
  736. if (!Conversion (lpIMC->hPrivate,lpszSrc,0)) {
  737. return (0);
  738. }
  739. ConverList.szSelectBuffer [lstrlen(ConverList.szSelectBuffer)-1]
  740. =TEXT('\0');
  741. dwSize =
  742. // header length
  743. sizeof(CANDIDATELIST) +
  744. // candidate string pointers
  745. sizeof(DWORD) * ConverList.Candi_Cnt+
  746. // string plus NULL terminator
  747. sizeof(TCHAR) * lstrlen (wCode);
  748. if (!uBufLen) {
  749. return (dwSize);
  750. }
  751. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  752. uMaxCand /= sizeof(DWORD) + lstrlen (wCode);
  753. if (!uMaxCand) {
  754. // can not even put one string
  755. return (0);
  756. }
  757. lpCandList->dwSize = dwSize;
  758. lpCandList->dwStyle = IME_CAND_READ; // candidate having same reading
  759. lpCandList->dwCount = 0;
  760. lpCandList->dwSelection = 0;
  761. lpCandList->dwPageSize = CANDPERPAGE;
  762. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
  763. (uMaxCand - 1);
  764. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),
  765. (LPTSTR)wCode);
  766. lpCandList->dwCount =(DWORD)ConverList.Candi_Cnt;
  767. for (i=1;i<lpCandList->dwCount;i++) {
  768. lpCandList->dwOffset[i] = lpCandList->dwOffset[0]
  769. +(DWORD)ConverList.Candi_Pos[i+1];
  770. *(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[i]-1) = TEXT('\0');
  771. }
  772. return (dwSize);
  773. }
  774. #if defined(CROSSREF)
  775. //*******************************************************************
  776. // The parameters are inherited from SelectOneCand
  777. // CrossReverseConv()
  778. //*******************************************************************
  779. int CrossReverseConv(
  780. LPINPUTCONTEXT lpIMC,
  781. LPCOMPOSITIONSTRING lpCompStr,
  782. LPPRIVCONTEXT lpImcP,
  783. LPCANDIDATELIST lpCandList)
  784. {
  785. LPGUIDELINE lpGuideLine;
  786. UINT uSize=0;
  787. if (!MBIndex.hRevKL) {
  788. return 0;
  789. }
  790. lpGuideLine = ImmLockIMCC(lpIMC->hGuideLine);
  791. if (!lpGuideLine) {
  792. return 0;
  793. }
  794. if (lpCompStr->dwResultStrLen != 2/sizeof(TCHAR)) {
  795. // we only can reverse convert one DBCS character for now
  796. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  797. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  798. } else {
  799. TCHAR szStrBuf[4];
  800. LPCANDIDATELIST lpRevCandList;
  801. if(lpImcP->hRevCandList == (HIMCC)NULL){
  802. //we alloc memory in lpImcP->hRevCandList, for reverse convert
  803. //result codes; When finish reconvert, should read out this info.
  804. REALLOC:
  805. lpImcP->hRevCandList = (HIMCC)GlobalAlloc(GHND, sizeof(CANDIDATELIST)+1*sizeof(DWORD)+MAXCODE*sizeof(TCHAR)+1);
  806. if (lpImcP->hRevCandList == (HIMCC)NULL) {
  807. return 0 ;
  808. }
  809. lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
  810. if (lpRevCandList == NULL) {
  811. return 0 ;
  812. }
  813. }else{
  814. lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
  815. if (lpRevCandList == NULL) {
  816. goto REALLOC;
  817. }
  818. }
  819. *(LPUNAWORD)szStrBuf = *(LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset);
  820. szStrBuf[2/sizeof(TCHAR)] = TEXT('\0');
  821. memset(lpRevCandList, 0, sizeof(CANDIDATELIST)+1*sizeof(DWORD)+MAXCODE*sizeof(TCHAR)+1);
  822. lpRevCandList->dwSize = sizeof(CANDIDATELIST)+1*sizeof(DWORD)+MAXCODE*sizeof(TCHAR)+1;
  823. uSize = ImmGetConversionList(MBIndex.hRevKL, (HIMC)NULL, szStrBuf,
  824. (LPCANDIDATELIST)lpRevCandList,
  825. lpRevCandList->dwSize, GCL_REVERSECONVERSION);
  826. GlobalUnlock((HGLOBAL)lpImcP->hRevCandList);
  827. if (uSize) {
  828. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  829. lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION|
  830. MSG_START_COMPOSITION);
  831. } else {
  832. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg|
  833. MSG_START_COMPOSITION) & ~(MSG_END_COMPOSITION);
  834. }
  835. } else {
  836. GlobalFree((HGLOBAL)lpImcP->hRevCandList);
  837. lpImcP->hRevCandList = (HIMCC)NULL;
  838. }
  839. }
  840. ImmUnlockIMCC(lpIMC->hGuideLine);
  841. //CHP
  842. //We need to know the result.
  843. return uSize;
  844. }
  845. #endif //CROSSREF
  846. /**********************************************************************/
  847. /* ReverseConversion() */
  848. /**********************************************************************/
  849. UINT PASCAL ReverseConversion(
  850. HIMCC hPrivate,
  851. LPCTSTR lpszSrc,
  852. LPCANDIDATELIST lpCandList,
  853. UINT uBufLen)
  854. {
  855. LPTSTR wCode;
  856. UINT uMaxCand;
  857. DWORD dwSize;
  858. wCode = ConverList.szInBuffer;
  859. ConverList.szSelectBuffer[0] =TEXT('\0');
  860. ConverList.szInBuffer[0] =TEXT('\0');
  861. ConverList.Candi_Cnt =0;
  862. ConverList.Candi_Pos[0] =TEXT('\0');
  863. dwSize =
  864. // header length
  865. sizeof(CANDIDATELIST) +
  866. // candidate string pointers
  867. sizeof(DWORD) +
  868. // string plus NULL terminator
  869. MAXCODE*sizeof(TCHAR);
  870. if (!uBufLen) {
  871. return (dwSize);
  872. }
  873. if(lpszSrc ==NULL){
  874. return (0);
  875. }
  876. if (!Conversion (hPrivate,lpszSrc,1)) {
  877. return (0);
  878. }
  879. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  880. uMaxCand /= sizeof(DWORD) + lstrlen (wCode);
  881. if (!uMaxCand) {
  882. // can not even put one string
  883. return (0);
  884. }
  885. lpCandList->dwSize = dwSize;
  886. lpCandList->dwStyle = IME_CAND_READ; // candidate having same reading
  887. lpCandList->dwCount = 1;
  888. lpCandList->dwSelection = 0;
  889. lpCandList->dwPageSize = CANDPERPAGE;
  890. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
  891. (uMaxCand - 1);
  892. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),
  893. (LPTSTR)wCode);
  894. return (dwSize);
  895. }
  896. /**********************************************************************/
  897. /* ImeConversionList() */
  898. /**********************************************************************/
  899. DWORD WINAPI ImeConversionList(
  900. HIMC hIMC,
  901. LPCTSTR lpszSrc,
  902. LPCANDIDATELIST lpCandList,
  903. DWORD dwBufLen,
  904. UINT uFlag)
  905. {
  906. if (!dwBufLen) {
  907. } else if (!lpszSrc) {
  908. return (0);
  909. } else if (!*lpszSrc) {
  910. return (0);
  911. } else if (!lpCandList) {
  912. return (0);
  913. } else if (dwBufLen <= sizeof(CANDIDATELIST)) {
  914. // buffer size can not even put the header information
  915. return (0);
  916. } else {
  917. }
  918. switch (uFlag) {
  919. case GCL_CONVERSION:
  920. return ForwordConversion(hIMC,lpszSrc, lpCandList, dwBufLen);
  921. break;
  922. case GCL_REVERSECONVERSION:
  923. if (!dwBufLen) {
  924. return ReverseConversion(NULL,0, lpCandList, dwBufLen);
  925. } else {
  926. DWORD fRet=0;
  927. HIMCC hPrivate;
  928. hPrivate = (HIMCC)ImmCreateIMCC(sizeof(PRIVCONTEXT));
  929. if(hPrivate == (HIMCC)NULL){
  930. return 0;
  931. }
  932. StartEngine(hPrivate);
  933. fRet = ReverseConversion(hPrivate,lpszSrc, lpCandList, dwBufLen);
  934. EndEngine(hPrivate);
  935. ImmDestroyIMCC(hPrivate);
  936. return fRet;
  937. }
  938. break;
  939. default:
  940. return (0);
  941. break;
  942. }
  943. }
  944. /**********************************************************************/
  945. /* ImeDestroy() */
  946. /* Return Value: */
  947. /* TRUE - successful, FALSE - failure */
  948. /**********************************************************************/
  949. BOOL WINAPI ImeDestroy( // this dll is unloaded
  950. UINT uReserved)
  951. {
  952. if (uReserved) {
  953. return (FALSE);
  954. }
  955. return (TRUE);
  956. }
  957. /**********************************************************************/
  958. /* ImeEscape() */
  959. /* Return Value: */
  960. /* TRUE - successful, FALSE - failure */
  961. /**********************************************************************/
  962. #define IME_INPUTKEYTOSEQUENCE 0x22
  963. LRESULT WINAPI ImeEscape( // escape function of IMEs
  964. HIMC hIMC,
  965. UINT uSubFunc,
  966. LPVOID lpData)
  967. {
  968. LRESULT lRet;
  969. switch (uSubFunc) {
  970. case IME_ESC_QUERY_SUPPORT:
  971. if (lpData == NULL)
  972. return FALSE;
  973. switch (*(LPUINT)lpData) {
  974. case IME_ESC_QUERY_SUPPORT:
  975. #ifdef EUDC
  976. case IME_ESC_GET_EUDC_DICTIONARY:
  977. case IME_ESC_SET_EUDC_DICTIONARY:
  978. #endif //EUDC
  979. case IME_ESC_SEQUENCE_TO_INTERNAL:
  980. case IME_ESC_MAX_KEY:
  981. case IME_ESC_IME_NAME:
  982. case IME_ESC_GETHELPFILENAME:
  983. return (TRUE);
  984. default:
  985. return (FALSE);
  986. }
  987. break;
  988. case IME_ESC_SEQUENCE_TO_INTERNAL:
  989. if (!lpData || (*(LPBYTE)lpData) == '\0') {
  990. return (FALSE);
  991. }
  992. lRet = *(LPWORD)lpData;
  993. return (lRet);
  994. #ifdef EUDC
  995. case IME_ESC_GET_EUDC_DICTIONARY:
  996. if (!lpData) {
  997. return (FALSE);
  998. }
  999. if (MBIndex.EUDCData.szEudcDictName[0] == TEXT('\0')) {
  1000. *(LPTSTR)lpData = TEXT('\0');
  1001. return(TRUE);
  1002. } else {
  1003. lstrcpy((LPTSTR)lpData,MBIndex.EUDCData.szEudcDictName);
  1004. return TRUE;
  1005. }
  1006. case IME_ESC_SET_EUDC_DICTIONARY:
  1007. return TRUE;
  1008. #endif //EUDC
  1009. case IME_ESC_MAX_KEY:
  1010. #ifdef EUDC
  1011. {
  1012. TCHAR szFullFileName[MAX_PATH], szFileName[MAX_PATH];
  1013. unsigned int cb;
  1014. cb = MAX_PATH;
  1015. if (lpImeL->nMaxKey > EUDC_MAX_READING) {
  1016. GetModuleFileName(NULL,szFullFileName ,cb);
  1017. GetFileTitle(szFullFileName, szFileName, (WORD)cb);
  1018. #ifdef UNICODE
  1019. // Compare first 8 chars only
  1020. if (_wcsnicmp(szFileName,TEXT("EUDCEDIT.EXE"),8))
  1021. #else
  1022. if (_strnicmp(szFileName,"EUDCEDIT.EXE",8))
  1023. #endif
  1024. return (lpImeL->nMaxKey);
  1025. else
  1026. return EUDC_MAX_READING;
  1027. } else {
  1028. return (lpImeL->nMaxKey);
  1029. }
  1030. }
  1031. #else
  1032. return (lpImeL->nMaxKey);
  1033. #endif //EUDC
  1034. case IME_ESC_IME_NAME:
  1035. if ( lpData == NULL )
  1036. return FALSE;
  1037. lstrcpy(lpData,MBIndex.MBDesc[0].szName);
  1038. return (TRUE);
  1039. case IME_ESC_GETHELPFILENAME :
  1040. {
  1041. TCHAR szIMEGUDHlpName[MAX_PATH];
  1042. int iLen;
  1043. if (lpData == NULL )
  1044. return FALSE;
  1045. szIMEGUDHlpName[0] = 0;
  1046. if (0 == GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAX_PATH))
  1047. return FALSE;
  1048. StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT("\\HELP\\"));
  1049. StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName),(LPTSTR)szImeMBFileName);
  1050. iLen = lstrlen(szIMEGUDHlpName);
  1051. szIMEGUDHlpName[iLen-3] = 0;
  1052. StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT(".CHM"));
  1053. lstrcpy(lpData, szIMEGUDHlpName);
  1054. return TRUE;
  1055. }
  1056. default:
  1057. return (FALSE);
  1058. }
  1059. return (lRet);
  1060. }
  1061. /**********************************************************************/
  1062. /* InitCompStr() */
  1063. /**********************************************************************/
  1064. void PASCAL InitCompStr( // init setting for composing string
  1065. LPCOMPOSITIONSTRING lpCompStr)
  1066. {
  1067. if (!lpCompStr) {
  1068. return;
  1069. }
  1070. lpCompStr->dwCompReadAttrLen = 0;
  1071. lpCompStr->dwCompReadClauseLen = 0;
  1072. lpCompStr->dwCompReadStrLen = 0;
  1073. lpCompStr->dwCompAttrLen = 0;
  1074. lpCompStr->dwCompClauseLen = 0;
  1075. lpCompStr->dwCompStrLen = 0;
  1076. lpCompStr->dwCursorPos = 0;
  1077. lpCompStr->dwDeltaStart = 0;
  1078. lpCompStr->dwResultReadClauseLen = 0;
  1079. lpCompStr->dwResultReadStrLen = 0;
  1080. lpCompStr->dwResultClauseLen = 0;
  1081. lpCompStr->dwResultStrLen = 0;
  1082. return;
  1083. }
  1084. /**********************************************************************/
  1085. /* ClearCompStr() */
  1086. /* Return Value: */
  1087. /* TRUE - successful, FALSE - failure */
  1088. /**********************************************************************/
  1089. BOOL PASCAL ClearCompStr(
  1090. LPINPUTCONTEXT lpIMC)
  1091. {
  1092. HIMCC hMem;
  1093. LPCOMPOSITIONSTRING lpCompStr;
  1094. DWORD dwSize;
  1095. if(!lpIMC) {
  1096. return (FALSE);
  1097. }
  1098. dwSize =
  1099. // header length
  1100. sizeof(COMPOSITIONSTRING) +
  1101. // composition reading attribute plus NULL terminator
  1102. lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE) +
  1103. // composition reading clause
  1104. sizeof(DWORD) + sizeof(DWORD) +
  1105. // composition reading string plus NULL terminator
  1106. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
  1107. // result reading clause
  1108. sizeof(DWORD) + sizeof(DWORD) +
  1109. // result reading string plus NULL terminateor
  1110. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
  1111. // result clause
  1112. sizeof(DWORD) + sizeof(DWORD) +
  1113. // result string plus NULL terminateor
  1114. MAXSTRLEN * sizeof(WORD) + sizeof(WORD);
  1115. if (!lpIMC->hCompStr) {
  1116. // it maybe free by other IME, init it
  1117. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  1118. } else if (hMem = ImmReSizeIMCC(lpIMC->hCompStr, dwSize)) {
  1119. lpIMC->hCompStr = hMem;
  1120. } else {
  1121. ImmDestroyIMCC(lpIMC->hCompStr);
  1122. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  1123. return (FALSE);
  1124. }
  1125. if (!lpIMC->hCompStr) {
  1126. return (FALSE);
  1127. }
  1128. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  1129. if (!lpCompStr) {
  1130. ImmDestroyIMCC(lpIMC->hCompStr);
  1131. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  1132. return (FALSE);
  1133. }
  1134. lpCompStr->dwSize = dwSize;
  1135. // 1. composition (reading) string - simple IME
  1136. // 2. result reading string
  1137. // 3. result string
  1138. lpCompStr->dwCompReadAttrLen = 0;
  1139. lpCompStr->dwCompReadAttrOffset = sizeof(COMPOSITIONSTRING);
  1140. lpCompStr->dwCompReadClauseLen = 0;
  1141. lpCompStr->dwCompReadClauseOffset = lpCompStr->dwCompReadAttrOffset +
  1142. lpImeL->nMaxKey * sizeof(TCHAR) + sizeof(TCHAR);
  1143. lpCompStr->dwCompReadStrLen = 0;
  1144. lpCompStr->dwCompReadStrOffset = lpCompStr->dwCompReadClauseOffset +
  1145. sizeof(DWORD) + sizeof(DWORD);
  1146. // composition string is the same with composition reading string
  1147. // for simple IMEs
  1148. lpCompStr->dwCompAttrLen = 0;
  1149. lpCompStr->dwCompAttrOffset = lpCompStr->dwCompReadAttrOffset;
  1150. lpCompStr->dwCompClauseLen = 0;
  1151. lpCompStr->dwCompClauseOffset = lpCompStr->dwCompReadClauseOffset;
  1152. lpCompStr->dwCompStrLen = 0;
  1153. lpCompStr->dwCompStrOffset = lpCompStr->dwCompReadStrOffset;
  1154. lpCompStr->dwCursorPos = 0;
  1155. lpCompStr->dwDeltaStart = 0;
  1156. lpCompStr->dwResultReadClauseLen = 0;
  1157. lpCompStr->dwResultReadClauseOffset = lpCompStr->dwCompStrOffset +
  1158. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
  1159. lpCompStr->dwResultReadStrLen = 0;
  1160. lpCompStr->dwResultReadStrOffset = lpCompStr->dwResultReadClauseOffset +
  1161. sizeof(DWORD) + sizeof(DWORD);
  1162. lpCompStr->dwResultClauseLen = 0;
  1163. lpCompStr->dwResultClauseOffset = lpCompStr->dwResultReadStrOffset +
  1164. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
  1165. lpCompStr->dwResultStrOffset = 0;
  1166. lpCompStr->dwResultStrOffset = lpCompStr->dwResultClauseOffset +
  1167. sizeof(DWORD) + sizeof(DWORD);
  1168. GlobalUnlock((HGLOBAL)lpIMC->hCompStr);
  1169. return (TRUE);
  1170. }
  1171. /**********************************************************************/
  1172. /* ClearCand() */
  1173. /* Return Value: */
  1174. /* TRUE - successful, FALSE - failure */
  1175. /**********************************************************************/
  1176. BOOL PASCAL ClearCand(
  1177. LPINPUTCONTEXT lpIMC)
  1178. {
  1179. HIMCC hMem;
  1180. LPCANDIDATEINFO lpCandInfo;
  1181. LPCANDIDATELIST lpCandList;
  1182. DWORD dwSize =
  1183. // header length
  1184. sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST) +
  1185. // candidate string pointers
  1186. sizeof(DWORD) * (MAXCAND) +
  1187. // string plus NULL terminator
  1188. (sizeof(WORD) * MAXSTRLEN + sizeof(WORD)) * MAXCAND;
  1189. if (!lpIMC) {
  1190. return (FALSE);
  1191. }
  1192. if (!lpIMC->hCandInfo) {
  1193. // it maybe free by other IME, init it
  1194. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  1195. } else if (hMem = ImmReSizeIMCC(lpIMC->hCandInfo, dwSize)) {
  1196. lpIMC->hCandInfo = hMem;
  1197. } else {
  1198. ImmDestroyIMCC(lpIMC->hCandInfo);
  1199. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  1200. return (FALSE);
  1201. }
  1202. if (!lpIMC->hCandInfo) {
  1203. return (FALSE);
  1204. }
  1205. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  1206. if (!lpCandInfo) {
  1207. ImmDestroyIMCC(lpIMC->hCandInfo);
  1208. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  1209. return (FALSE);
  1210. }
  1211. // ordering of strings are
  1212. // buffer size
  1213. lpCandInfo->dwSize = dwSize;
  1214. lpCandInfo->dwCount = 0;
  1215. lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
  1216. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  1217. lpCandInfo->dwOffset[0]);
  1218. // whole candidate info size - header
  1219. lpCandList->dwSize = lpCandInfo->dwSize - sizeof(CANDIDATEINFO);
  1220. lpCandList->dwStyle = IME_CAND_READ;
  1221. lpCandList->dwCount = 0;
  1222. lpCandList->dwSelection = 0;
  1223. lpCandList->dwPageSize = CANDPERPAGE;
  1224. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) +
  1225. sizeof(DWORD) * (MAXCAND - 1);
  1226. ImmUnlockIMCC(lpIMC->hCandInfo);
  1227. return (TRUE);
  1228. }
  1229. /**********************************************************************/
  1230. /* ClearGuideLine() */
  1231. /* Return Value: */
  1232. /* TRUE - successful, FALSE - failure */
  1233. /**********************************************************************/
  1234. BOOL PASCAL ClearGuideLine(
  1235. LPINPUTCONTEXT lpIMC)
  1236. {
  1237. HIMCC hMem;
  1238. LPGUIDELINE lpGuideLine;
  1239. DWORD dwSize = sizeof(GUIDELINE) + sImeG.cbStatusErr;
  1240. if (!lpIMC->hGuideLine) {
  1241. // it maybe free by IME
  1242. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  1243. } else if (hMem = ImmReSizeIMCC(lpIMC->hGuideLine, dwSize)) {
  1244. lpIMC->hGuideLine = hMem;
  1245. } else {
  1246. ImmDestroyIMCC(lpIMC->hGuideLine);
  1247. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  1248. }
  1249. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  1250. if (!lpGuideLine) {
  1251. return (FALSE);
  1252. }
  1253. lpGuideLine->dwSize = dwSize;
  1254. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  1255. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  1256. lpGuideLine->dwStrLen = 0;
  1257. lpGuideLine->dwStrOffset = sizeof(GUIDELINE);
  1258. CopyMemory((LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset,
  1259. sImeG.szStatusErr, sImeG.cbStatusErr);
  1260. ImmUnlockIMCC(lpIMC->hGuideLine);
  1261. return (TRUE);
  1262. }
  1263. /**********************************************************************/
  1264. /* InitContext() */
  1265. /**********************************************************************/
  1266. void PASCAL InitContext(
  1267. LPINPUTCONTEXT lpIMC)
  1268. {
  1269. if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
  1270. } else if (!lpIMC->hWnd) {
  1271. } else {
  1272. #if 0 // MultiMonitor support
  1273. POINT ptWnd;
  1274. // 10.10 modify
  1275. //ptWnd.x = sImeG.rcWorkArea.left;
  1276. //ptWnd.y = sImeG.rcWorkArea.top;
  1277. ptWnd.x = 0;
  1278. ptWnd.y = 0;
  1279. ClientToScreen(lpIMC->hWnd, &ptWnd);
  1280. if (ptWnd.x < sImeG.rcWorkArea.left) {
  1281. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
  1282. } else if (ptWnd.x + sImeG.xStatusWi > sImeG.rcWorkArea.right) {
  1283. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
  1284. sImeG.xStatusWi;
  1285. } else {
  1286. lpIMC->ptStatusWndPos.x = ptWnd.x;
  1287. }
  1288. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
  1289. sImeG.yStatusHi;
  1290. #else
  1291. RECT rcWorkArea;
  1292. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  1293. lpIMC->ptStatusWndPos.x = rcWorkArea.left;
  1294. lpIMC->ptStatusWndPos.y = rcWorkArea.bottom -
  1295. sImeG.yStatusHi;
  1296. #endif
  1297. lpIMC->fdwInit |= INIT_STATUSWNDPOS;
  1298. }
  1299. if (!(lpIMC->fdwInit & INIT_COMPFORM)) {
  1300. lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
  1301. }
  1302. if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) {
  1303. } else if (!lpIMC->hWnd) {
  1304. } else {
  1305. POINT ptWnd;
  1306. ptWnd = lpImeL->ptDefComp;
  1307. ScreenToClient(lpIMC->hWnd, &ptWnd);
  1308. lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
  1309. lpIMC->cfCompForm.ptCurrentPos = ptWnd;
  1310. lpIMC->fdwInit |= INIT_COMPFORM;
  1311. }
  1312. return;
  1313. }
  1314. /**********************************************************************/
  1315. /* Select() */
  1316. /* Return Value: */
  1317. /* TRUE - successful, FALSE - failure */
  1318. /**********************************************************************/
  1319. BOOL PASCAL Select(
  1320. HIMC hIMC,
  1321. LPINPUTCONTEXT lpIMC,
  1322. BOOL fSelect)
  1323. {
  1324. LPPRIVCONTEXT lpImcP;
  1325. if (fSelect) {
  1326. if (!ClearCompStr(lpIMC))
  1327. return FALSE;
  1328. if (!ClearCand(lpIMC))
  1329. return FALSE;
  1330. ClearGuideLine(lpIMC);
  1331. }
  1332. if (lpIMC->cfCandForm[0].dwIndex != 0)
  1333. lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
  1334. // We add this hack for switching from other IMEs, this IME has a bug.
  1335. // Before this bug fixed in this IME, it depends on this hack.
  1336. if (lpIMC->cfCandForm[0].dwStyle == CFS_DEFAULT) {
  1337. lpIMC->cfCandForm[0].dwIndex = (DWORD)-1;
  1338. }
  1339. if (!lpIMC->hPrivate)
  1340. return FALSE;
  1341. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  1342. if (!lpImcP)
  1343. return FALSE;
  1344. if (fSelect) {
  1345. static BOOL bFirstTimeCallHere = TRUE;
  1346. //
  1347. // Init. ime character
  1348. //
  1349. InitImeCharac(0);
  1350. InterlockedIncrement( &lLock );
  1351. if ( bFirstTimeCallHere == TRUE ) {
  1352. GetCurrentUserEMBPath( );
  1353. bFirstTimeCallHere = FALSE;
  1354. }
  1355. InterlockedDecrement( &lLock );
  1356. //
  1357. // init fields of hPrivate
  1358. //
  1359. lpImcP->iImeState = CST_INIT;
  1360. lpImcP->fdwImeMsg = (DWORD) 0;
  1361. lpImcP->dwCompChar = (DWORD) 0;
  1362. lpImcP->fdwGcsFlag = (DWORD) 0;
  1363. lpImcP->uSYHFlg = 0x00000000;
  1364. lpImcP->uDYHFlg = 0x00000000;
  1365. lpImcP->uDSMHCount = 0x00000000;
  1366. lpImcP->uDSMHFlg = 0x00000000;
  1367. lpImcP->iActMBIndex = 0;
  1368. lstrcpy(lpImcP->MB_Name, HMapTab[0].MB_Name);
  1369. lpImcP->PrivateArea.Comp_Status.dwSTLX = 0;
  1370. lpImcP->PrivateArea.Comp_Status.dwSTMULCODE = 0;
  1371. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  1372. lpImcP->PrivateArea.Comp_Status.OnLineCreWord = 0;
  1373. //
  1374. // Set IME properties
  1375. //
  1376. lpImcP->PrivateArea.Comp_Status.dwPPTLX = MBIndex.IMEChara[lpImcP->iActMBIndex].IC_LX;
  1377. lpImcP->PrivateArea.Comp_Status.dwPPCZ = MBIndex.IMEChara[lpImcP->iActMBIndex].IC_CZ;
  1378. lpImcP->PrivateArea.Comp_Status.dwPPTS = MBIndex.IMEChara[lpImcP->iActMBIndex].IC_TS;
  1379. lpImcP->PrivateArea.Comp_Status.dwPPCTS = MBIndex.IMEChara[lpImcP->iActMBIndex].IC_CTC;
  1380. lpImcP->PrivateArea.Comp_Status.dwTraceCusr = MBIndex.IMEChara[lpImcP->iActMBIndex].IC_Trace;
  1381. CWCodeStr[0] = 0;
  1382. CWDBCSStr[0] = 0;
  1383. lpIMC->fOpen = TRUE;
  1384. if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
  1385. lpIMC->fdwConversion = (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) |
  1386. IME_CMODE_NATIVE;
  1387. lpIMC->fdwInit |= INIT_CONVERSION;
  1388. }
  1389. if (!(lpIMC->fdwInit & INIT_LOGFONT)) {
  1390. HDC hDC;
  1391. HGDIOBJ hSysFont;
  1392. //hSysFont = GetStockObject(SYSTEM_FONT);
  1393. hDC = GetDC(NULL);
  1394. hSysFont = GetCurrentObject(hDC, OBJ_FONT);
  1395. GetObject(hSysFont, sizeof(LOGFONT), &lpIMC->lfFont.A);
  1396. ReleaseDC(NULL, hDC);
  1397. lpIMC->fdwInit |= INIT_LOGFONT;
  1398. }
  1399. InitContext(lpIMC);
  1400. //
  1401. // Set Caps status
  1402. //
  1403. {
  1404. DWORD fdwConversion;
  1405. if (GetKeyState(VK_CAPITAL) & 0x01) {
  1406. //
  1407. // Change to alphanumeric mode.
  1408. //
  1409. fdwConversion = lpIMC->fdwConversion &
  1410. ~(IME_CMODE_NATIVE | IME_CMODE_CHARCODE | IME_CMODE_EUDC);
  1411. } else {
  1412. //
  1413. // Change to native mode
  1414. //
  1415. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  1416. ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC );
  1417. }
  1418. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  1419. }
  1420. } else {
  1421. if (lpImeL->hSKMenu) {
  1422. DestroyMenu(lpImeL->hSKMenu);
  1423. lpImeL->hSKMenu = NULL;
  1424. }
  1425. if (lpImeL->hPropMenu) {
  1426. DestroyMenu(lpImeL->hPropMenu);
  1427. lpImeL->hPropMenu = NULL;
  1428. }
  1429. if (lpImeL->hObjImeMenu) {
  1430. DestroyMenu(lpImeL->hObjImeMenu);
  1431. lpImeL->hObjImeMenu = NULL;
  1432. }
  1433. if (hCrtDlg) {
  1434. SendMessage(hCrtDlg, WM_CLOSE, (WPARAM)NULL, (LPARAM)NULL);
  1435. hCrtDlg = NULL;
  1436. }
  1437. }
  1438. //
  1439. // Start or end MB engine
  1440. //
  1441. if (fSelect) {
  1442. StartEngine(lpIMC->hPrivate);
  1443. SaTC_Trace = MBIndex.IMEChara[0].IC_Trace;
  1444. } else {
  1445. EndEngine(lpIMC->hPrivate);
  1446. }
  1447. ImmUnlockIMCC(lpIMC->hPrivate);
  1448. return (TRUE);
  1449. }
  1450. /**********************************************************************/
  1451. /* ImeSelect() */
  1452. /* Return Value: */
  1453. /* TRUE - successful, FALSE - failure */
  1454. /**********************************************************************/
  1455. BOOL WINAPI ImeSelect(
  1456. HIMC hIMC,
  1457. BOOL fSelect)
  1458. {
  1459. LPINPUTCONTEXT lpIMC;
  1460. BOOL fRet;
  1461. if (!hIMC) {
  1462. return (FALSE);
  1463. }
  1464. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1465. if (!lpIMC) {
  1466. return (FALSE);
  1467. }
  1468. fRet = Select(hIMC, lpIMC, fSelect);
  1469. ImmUnlockIMC(hIMC);
  1470. return (fRet);
  1471. }
  1472. /**********************************************************************/
  1473. /* ImeSetActiveContext() */
  1474. /* Return Value: */
  1475. /* TRUE - successful, FALSE - failure */
  1476. /**********************************************************************/
  1477. BOOL WINAPI ImeSetActiveContext(
  1478. HIMC hIMC,
  1479. BOOL fOn)
  1480. {
  1481. if (!fOn) {
  1482. } else if (!hIMC) {
  1483. } else {
  1484. LPINPUTCONTEXT lpIMC;
  1485. LPPRIVCONTEXT lpImcP;
  1486. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1487. if (!lpIMC) {
  1488. goto SetActEnd;
  1489. }
  1490. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  1491. if (!lpImcP) {
  1492. goto SetActUnlockIMC;
  1493. }
  1494. InitContext(lpIMC);
  1495. ImmUnlockIMCC(lpIMC->hPrivate);
  1496. SetActUnlockIMC:
  1497. ImmUnlockIMC(hIMC);
  1498. SetActEnd:
  1499. return (TRUE);
  1500. }
  1501. return (TRUE);
  1502. }
  1503. /**********************************************************************/
  1504. //OpenReg_PathSetup(HKEY *phKey);
  1505. /**********************************************************************/
  1506. LONG OpenReg_PathSetup(HKEY *phKey)
  1507. {
  1508. return RegOpenKeyEx (HKEY_CURRENT_USER,
  1509. REGSTR_PATH_SETUP,
  1510. 0,
  1511. KEY_ENUMERATE_SUB_KEYS |
  1512. KEY_EXECUTE |
  1513. KEY_QUERY_VALUE,
  1514. phKey);
  1515. }
  1516. /**********************************************************************/
  1517. //LONG OpenReg_User(HKEY hKey, // handle of open key
  1518. // LPCTSTR lpszSubKey, // address of name of subkey to open
  1519. // PHKEY phkResult); // address of handle of open key
  1520. /**********************************************************************/
  1521. LONG OpenReg_User(HKEY hKey, // handle of open key
  1522. LPCTSTR lpszSubKey, // address of name of subkey to open
  1523. PHKEY phkResult) // address of handle of open key
  1524. {
  1525. return RegOpenKeyEx (hKey,
  1526. lpszSubKey,
  1527. 0,
  1528. KEY_ENUMERATE_SUB_KEYS |
  1529. KEY_EXECUTE |
  1530. KEY_QUERY_VALUE|KEY_SET_VALUE,
  1531. phkResult);
  1532. }
  1533. VOID InfoMessage(HANDLE hWnd,WORD wMsgID)
  1534. {
  1535. TCHAR szStr[256];
  1536. LoadString(hInst,wMsgID,szStr, sizeof(szStr)/sizeof(TCHAR));
  1537. MessageBox(hWnd,szStr,szWarnTitle,MB_ICONINFORMATION|MB_OK);
  1538. }
  1539. VOID FatalMessage(HANDLE hWnd,WORD wMsgID)
  1540. {
  1541. TCHAR szStr[256];
  1542. LoadString(hInst,wMsgID,szStr, sizeof(szStr)/sizeof(TCHAR));
  1543. MessageBox(hWnd,szStr,szErrorTitle,MB_ICONSTOP|MB_OK);
  1544. }