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

1634 lines
49 KiB

  1. /*++
  2. Copyright (c) 1990-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. #include <immdev.h>
  10. #include <imedefs.h>
  11. #include <resource.h>
  12. #include <regstr.h>
  13. #include <winuser.h>
  14. HWND hCrtDlg = NULL;
  15. /**********************************************************************/
  16. /* ImeInquire() */
  17. /* Return Value: */
  18. /* TRUE - successful, FALSE - failure */
  19. /**********************************************************************/
  20. BOOL WINAPI ImeInquire( // initialized data structure of IME
  21. LPIMEINFO lpImeInfo, // IME specific data report to IMM
  22. LPTSTR lpszWndCls, // the class name of UI
  23. DWORD dwSystemInfoFlags)
  24. {
  25. if (!lpImeInfo) {
  26. return (FALSE);
  27. }
  28. lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT);
  29. lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST|
  30. #ifdef UNICODE
  31. IME_PROP_UNICODE|
  32. #endif
  33. IME_PROP_CANDLIST_START_FROM_1|
  34. IME_PROP_IGNORE_UPKEYS;
  35. lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|
  36. IME_CMODE_CHARCODE|IME_CMODE_SOFTKBD|IME_CMODE_NOCONVERSION;
  37. lpImeInfo->fdwSentenceCaps = 0;
  38. // IME will have different distance base multiple of 900 escapement
  39. lpImeInfo->fdwUICaps = UI_CAP_ROT90|UI_CAP_SOFTKBD;
  40. // composition string is the reading string for simple IME
  41. lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR|SCS_CAP_MAKEREAD;
  42. // IME want to decide conversion mode on ImeSelect
  43. lpImeInfo->fdwSelectCaps = (DWORD)0;
  44. lstrcpy(lpszWndCls, (LPTSTR)szUIClassName);
  45. if ( lpImeL )
  46. {
  47. if ( dwSystemInfoFlags & IME_SYSINFO_WINLOGON )
  48. {
  49. // the client app is running in logon mode.
  50. lpImeL->fWinLogon = TRUE;
  51. }
  52. else
  53. lpImeL->fWinLogon = FALSE;
  54. }
  55. return (TRUE);
  56. }
  57. #if defined(CROSSREF)
  58. /**********************************************************************/
  59. /* ReverseConversionList() */
  60. /**********************************************************************/
  61. void PASCAL ReverseConversionList(HWND hLayoutListBox)
  62. {
  63. int nLayouts, i, nIMEs;
  64. TCHAR szTmpImeName[24];
  65. HKL FAR *lpKLMem;
  66. LoadString(hInst, IDS_NONE, szTmpImeName, sizeof(szTmpImeName)/sizeof(TCHAR));
  67. SendMessage(hLayoutListBox, LB_INSERTSTRING,
  68. 0, (LPARAM)szTmpImeName);
  69. SendMessage(hLayoutListBox, LB_SELECTSTRING,
  70. 0, (LPARAM)szTmpImeName);
  71. SendMessage(hLayoutListBox, LB_SETITEMDATA,
  72. 0, (LPARAM)(HKL)NULL);
  73. nLayouts = GetKeyboardLayoutList(0, NULL);
  74. lpKLMem = GlobalAlloc(GPTR, sizeof(HKL) * nLayouts);
  75. if (!lpKLMem) {
  76. return;
  77. }
  78. GetKeyboardLayoutList(nLayouts, lpKLMem);
  79. for (i = 0, nIMEs = 0; i < nLayouts; i++) {
  80. HKL hKL;
  81. hKL = *(lpKLMem + i);
  82. if (LOWORD(hKL) != NATIVE_LANGUAGE) {
  83. // not support other language
  84. continue;
  85. }
  86. if (!ImmGetConversionList(hKL, (HIMC)NULL, NULL,
  87. NULL, 0, GCL_REVERSECONVERSION)) {
  88. // this IME not support reverse conversion
  89. continue;
  90. }
  91. if (!ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME,
  92. szTmpImeName)) {
  93. // this IME does not report the IME name
  94. continue;
  95. }
  96. if( lstrcmp(szTmpImeName, szImeName) == 0)
  97. continue;
  98. nIMEs++;
  99. SendMessage(hLayoutListBox, LB_INSERTSTRING,
  100. nIMEs, (LPARAM)szTmpImeName);
  101. if (hKL == sImeG.hRevKL) {
  102. SendMessage(hLayoutListBox, LB_SELECTSTRING, nIMEs,
  103. (LPARAM)szTmpImeName);
  104. }
  105. SendMessage(hLayoutListBox, LB_SETITEMDATA,
  106. nIMEs, (LPARAM)hKL);
  107. }
  108. GlobalFree((HGLOBAL)lpKLMem);
  109. return;
  110. }
  111. #endif //CROSSREF
  112. /**********************************************************************/
  113. /* ImeSetDlgProc() */
  114. /* Return Value: */
  115. /* TRUE - successful, FALSE - failure */
  116. /**********************************************************************/
  117. BOOL FAR PASCAL ImeSetDlgProc( // dialog procedure of configuration
  118. HWND hDlg,
  119. UINT uMessage,
  120. WORD wParam,
  121. LONG lParam)
  122. {
  123. RECT rc;
  124. LONG DlgWidth, DlgHeight;
  125. static DWORD TempParam;
  126. #ifdef CROSSREF
  127. HIMC hIMC;
  128. LPINPUTCONTEXT lpIMC;
  129. HWND hLayoutListBox;
  130. static HIMC hOldIMC;
  131. #endif //CROSSREF
  132. switch (uMessage) {
  133. case WM_INITDIALOG:
  134. hCrtDlg = hDlg;
  135. // reset position
  136. GetWindowRect(hDlg, &rc);
  137. DlgWidth = rc.right - rc.left;
  138. DlgHeight = rc.bottom - rc.top;
  139. SetWindowPos(hDlg, HWND_TOP,
  140. (int)(sImeG.rcWorkArea.right - DlgWidth)/2,
  141. (int)(sImeG.rcWorkArea.bottom - DlgHeight)/2,
  142. (int)0, (int)0, SWP_NOSIZE);
  143. TempParam = sImeG.IC_Trace;
  144. CheckDlgButton (hDlg, IDC_TRACE, sImeG.IC_Trace);
  145. #ifdef CROSSREF
  146. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  147. hIMC = ImmGetContext(hLayoutListBox);
  148. if(hIMC){
  149. ImmSetOpenStatus(hIMC, FALSE);
  150. }
  151. ImmReleaseContext(hLayoutListBox, hIMC);
  152. // put all reverse conversion hKL into this list
  153. ReverseConversionList(hLayoutListBox);
  154. #endif //CROSSREF
  155. return (TRUE); // don't want to set focus to special control
  156. case WM_COMMAND:
  157. switch (wParam) {
  158. case IDOK:
  159. {
  160. HKEY hKeyCurrVersion;
  161. HKEY hKeyGB;
  162. DWORD retCode;
  163. //CHAR Buf[LINE_LEN];
  164. sImeG.IC_Trace = TempParam;
  165. retCode = OpenReg_PathSetup(&hKeyCurrVersion);
  166. if (retCode) {
  167. RegCreateKey(HKEY_CURRENT_USER,
  168. REGSTR_PATH_SETUP,
  169. &hKeyCurrVersion);
  170. }
  171. #if defined(COMBO_IME)
  172. if ( hKeyCurrVersion != NULL )
  173. {
  174. retCode = RegCreateKeyEx(hKeyCurrVersion,
  175. szImeRegName,
  176. 0,
  177. NULL,
  178. REG_OPTION_NON_VOLATILE,
  179. KEY_ALL_ACCESS,
  180. NULL,
  181. &hKeyGB,
  182. NULL);
  183. }
  184. #else
  185. if ( hKeyCurrVersion != NULL )
  186. {
  187. retCode = RegCreateKeyEx(hKeyCurrVersion,
  188. szImeName,
  189. 0,
  190. NULL,
  191. REG_OPTION_NON_VOLATILE,
  192. KEY_ALL_ACCESS,
  193. NULL,
  194. &hKeyGB,
  195. NULL);
  196. }
  197. #endif //COMBO_IME
  198. if (hKeyGB != NULL){
  199. RegSetValueEx (hKeyGB,
  200. szTrace,
  201. (DWORD)0,
  202. REG_DWORD,
  203. (LPBYTE)&sImeG.IC_Trace,
  204. sizeof(DWORD));
  205. RegCloseKey(hKeyGB);
  206. }
  207. if ( hKeyCurrVersion )
  208. RegCloseKey(hKeyCurrVersion);
  209. #ifdef CROSSREF
  210. {
  211. HWND hLayoutListBox;
  212. int iCurSel;
  213. HKL hKL;
  214. DWORD retCode;
  215. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  216. iCurSel = (int)SendMessage(hLayoutListBox, LB_GETCURSEL, 0, 0);
  217. hKL = (HKL)SendMessage(hLayoutListBox, LB_GETITEMDATA,
  218. iCurSel, 0);
  219. if (sImeG.hRevKL != hKL) {
  220. WORD nRevMaxKey;
  221. HKEY hKeyAppUser, hKeyIMEUser;
  222. LPPRIVCONTEXT lpImcP;
  223. sImeG.hRevKL = hKL;
  224. //set reverse layout to registry
  225. retCode = OpenReg_PathSetup(&hKeyAppUser);
  226. if (retCode) {
  227. RegCreateKey(HKEY_CURRENT_USER, REGSTR_PATH_SETUP, &hKeyCurrVersion);
  228. }
  229. #if defined(COMBO_IME)
  230. retCode = RegCreateKeyEx(hKeyAppUser, szImeRegName, 0,
  231. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKeyIMEUser, NULL);
  232. if (retCode) {
  233. DWORD dwDisposition;
  234. retCode = RegCreateKeyEx (hKeyCurrVersion,
  235. szImeRegName,
  236. 0,
  237. 0,
  238. REG_OPTION_NON_VOLATILE,
  239. KEY_ALL_ACCESS,
  240. NULL,
  241. &hKeyGB,
  242. &dwDisposition);
  243. }
  244. #else
  245. retCode = RegCreateKeyEx(hKeyAppUser, szImeName, 0,
  246. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKeyIMEUser, NULL);
  247. if (retCode) {
  248. DWORD dwDisposition;
  249. retCode = RegCreateKeyEx (hKeyCurrVersion,
  250. szImeName,
  251. 0,
  252. 0,
  253. REG_OPTION_NON_VOLATILE,
  254. KEY_ALL_ACCESS,
  255. NULL,
  256. &hKeyGB,
  257. &dwDisposition);
  258. }
  259. #endif //COMBO_IME
  260. RegSetValueEx(hKeyIMEUser, szRegRevKL, 0, REG_DWORD, (LPBYTE)&hKL,sizeof(hKL));
  261. // get the new size
  262. nRevMaxKey = (WORD)ImmEscape(hKL, (HIMC)NULL, IME_ESC_MAX_KEY,
  263. NULL);
  264. if (lpImeL->nMaxKey != nRevMaxKey) {
  265. if(lpImeL->nMaxKey < nRevMaxKey)
  266. lpImeL->nMaxKey = nRevMaxKey;
  267. // set the width & height for composition window
  268. lpImeL->rcCompText.right = lpImeL->rcCompText.left +
  269. sImeG.xChiCharWi * ((lpImeL->nMaxKey+2)/2);
  270. lpImeL->xCompWi = lpImeL->rcCompText.right + lpImeL->cxCompBorder * (2 + 4);
  271. //generate message to broadcast change comp win size
  272. hIMC = (HIMC)ImmGetContext(hDlg);
  273. if (!hIMC) {
  274. return TRUE;
  275. }
  276. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  277. if (!lpIMC) {
  278. return TRUE;
  279. }
  280. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  281. if (!lpImcP) {
  282. goto ChgConfigUnlockIMC;
  283. }
  284. lpImcP->fdwImeMsg |= MSG_IMN_COMPOSITIONPOS;
  285. GenerateMessage(hIMC, lpIMC, lpImcP);
  286. ImmUnlockIMCC(lpIMC->hPrivate);
  287. ChgConfigUnlockIMC:
  288. ImmUnlockIMC(hIMC);
  289. } //end of change nMaxKey
  290. RegSetValueEx(hKeyIMEUser, szRegRevMaxKey, 0, REG_DWORD, (LPBYTE)&lpImeL->nMaxKey,sizeof(DWORD));
  291. RegCloseKey(hKeyAppUser);
  292. RegCloseKey(hKeyIMEUser);
  293. } //end of change RegRevKL
  294. }
  295. #endif //CROSSREF
  296. }
  297. #ifdef CROSSREF
  298. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  299. hIMC = ImmGetContext(hLayoutListBox);
  300. if(hIMC) {
  301. ImmSetOpenStatus(hIMC, TRUE);
  302. }
  303. ImmReleaseContext(hLayoutListBox, hIMC);
  304. #endif //CROSSREF
  305. EndDialog(hDlg, FALSE);
  306. break;
  307. case IDCANCEL:
  308. #ifdef CROSSREF
  309. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  310. hIMC = ImmGetContext(hLayoutListBox);
  311. if(hIMC) {
  312. ImmSetOpenStatus(hIMC, TRUE);
  313. }
  314. ImmReleaseContext(hLayoutListBox, hIMC);
  315. #endif //CROSSREF
  316. EndDialog(hDlg, FALSE);
  317. break;
  318. case IDC_TRACE:
  319. // Set Current InputMode Param(temp)
  320. TempParam = (TempParam ^ 0x00000001) & 0x00000001;
  321. break;
  322. default:
  323. return (FALSE);
  324. }
  325. return (TRUE);
  326. case WM_PAINT:
  327. {
  328. RECT rc;
  329. GetClientRect(hDlg, &rc);
  330. DrawConvexRect(GetDC(hDlg),
  331. rc.left + 7,
  332. rc.top + 7,
  333. rc.right - 7 - 1,
  334. rc.bottom - 40 - 1);
  335. DrawConvexRectP(GetDC(hDlg),
  336. rc.left + 7,
  337. rc.top + 7,
  338. rc.right - 7,
  339. rc.bottom - 40);
  340. }
  341. return (FALSE);
  342. case WM_CLOSE:
  343. #ifdef CROSSREF
  344. hLayoutListBox = GetDlgItem(hDlg, IDD_LAYOUT_LIST);
  345. hIMC = ImmGetContext(hLayoutListBox);
  346. if(hIMC) {
  347. ImmSetOpenStatus(hIMC, TRUE);
  348. }
  349. ImmReleaseContext(hLayoutListBox, hIMC);
  350. #endif //CROSSREF
  351. EndDialog(hDlg, FALSE);
  352. return (TRUE);
  353. default:
  354. return (FALSE);
  355. }
  356. return (TRUE);
  357. }
  358. /**********************************************************************/
  359. /* ImeConfigure() */
  360. /* Return Value: */
  361. /* TRUE - successful, FALSE - failure */
  362. /**********************************************************************/
  363. /*BOOL WINAPI ImeConfigure( // configurate the IME setting
  364. HKL hKL, // hKL of this IME
  365. HWND hAppWnd, // the owner window
  366. DWORD dwMode) // mode of dialog
  367. {*/
  368. BOOL WINAPI ImeConfigure( // configurate the IME setting
  369. HKL hKL, // hKL of this IME
  370. HWND hAppWnd, // the owner window
  371. DWORD dwMode,
  372. LPVOID lpData) // mode of dialog
  373. {
  374. switch (dwMode) {
  375. case IME_CONFIG_GENERAL:
  376. DialogBox(hInst, TEXT("ImeSet"), (HWND)hAppWnd, (DLGPROC)ImeSetDlgProc);
  377. break;
  378. default:
  379. return (FALSE);
  380. break;
  381. }
  382. return (TRUE);
  383. }
  384. /**********************************************************************/
  385. /* XGBConversion() */
  386. /**********************************************************************/
  387. DWORD PASCAL XGBConversion(
  388. LPCTSTR lpszReading,
  389. LPCANDIDATELIST lpCandList,
  390. UINT uBufLen)
  391. {
  392. UINT MAX_COMP;
  393. UINT uMaxCand;
  394. UINT iRet;
  395. WORD wCode;
  396. LPPRIVCONTEXT lpImcP;
  397. HGLOBAL hImcP;
  398. int i;
  399. DWORD dwSize;
  400. if (!(lstrlen (lpszReading) == 4)) {
  401. return (0);
  402. }
  403. hImcP = GlobalAlloc (GMEM_MOVEABLE,sizeof (PRIVCONTEXT));
  404. if(!hImcP){
  405. return(0);
  406. }
  407. lpImcP= GlobalLock (hImcP);
  408. if(!lpImcP){
  409. GlobalFree(hImcP);
  410. return(0);
  411. }
  412. lstrcpy (lpImcP->bSeq,lpszReading);
  413. if(lpImcP->bSeq[3] == TEXT('?')){
  414. MAX_COMP = 178;
  415. } else {
  416. MAX_COMP = 1;
  417. }
  418. dwSize = // similar to ClearCand
  419. // header length
  420. sizeof(CANDIDATELIST) +
  421. // candidate string pointers
  422. sizeof(DWORD) * MAX_COMP +
  423. // string plus NULL terminator
  424. (sizeof(WORD) + sizeof(TCHAR)) * MAX_COMP;
  425. if (!uBufLen) {
  426. return (dwSize);
  427. }
  428. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  429. uMaxCand /= sizeof(DWORD) + sizeof(WORD) + sizeof(TCHAR);
  430. if (!uMaxCand) {
  431. // can not even put one string
  432. return (0);
  433. }
  434. lpCandList->dwSize = dwSize;
  435. lpCandList->dwStyle = IME_CAND_READ; // candidate having same reading
  436. lpCandList->dwCount = 0;
  437. lpCandList->dwSelection = 0;
  438. lpCandList->dwPageSize = CANDPERPAGE;
  439. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
  440. (uMaxCand - 1);
  441. lpImcP->bSeq[0] = 0;
  442. lpImcP->bSeq[1] = 0;
  443. lpImcP->bSeq[2] = 0;
  444. lpImcP->bSeq[3] = 0;
  445. for (i=0;i<4;i++) {
  446. iRet = XGBProcessKey(*(LPBYTE)((LPBYTE)lpszReading+i),lpImcP);
  447. if (iRet == CST_INPUT) {
  448. lpImcP->bSeq[i] = *(LPBYTE)((LPBYTE)lpszReading+i);
  449. } else {
  450. return (DWORD)0;
  451. }
  452. }
  453. wCode = XGBEngine(lpImcP);
  454. wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
  455. for (i = 0; i < (0x7e-0x40+1); i++, wCode++) {
  456. XGBAddCodeIntoCand(lpCandList, wCode);
  457. }
  458. wCode ++;
  459. for (i = 0; i < (0xfe-0x80+1); i++, wCode++) {
  460. XGBAddCodeIntoCand(lpCandList, wCode);
  461. }
  462. GlobalUnlock (hImcP);
  463. GlobalFree (hImcP);
  464. return (dwSize);
  465. }
  466. /**********************************************************************/
  467. /* Conversion() */
  468. /**********************************************************************/
  469. DWORD PASCAL Conversion(
  470. LPCTSTR lpszReading,
  471. LPCANDIDATELIST lpCandList,
  472. UINT uBufLen)
  473. {
  474. UINT MAX_COMP,i;
  475. UINT uMaxCand;
  476. UINT iRet;
  477. WORD wCode;
  478. LPPRIVCONTEXT lpImcP;
  479. HGLOBAL hImcP;
  480. DWORD dwSize;
  481. if (!(lstrlen (lpszReading) == 4)) {
  482. return (0);
  483. }
  484. hImcP = GlobalAlloc (GMEM_MOVEABLE,sizeof (PRIVCONTEXT));
  485. if(!hImcP){
  486. return(0);
  487. }
  488. lpImcP= GlobalLock (hImcP);
  489. if(!lpImcP){
  490. GlobalFree(hImcP);
  491. return(0);
  492. }
  493. lstrcpy (lpImcP->bSeq,lpszReading);
  494. if(lpImcP->bSeq[3] == TEXT('?')){
  495. MAX_COMP = 94;
  496. } else {
  497. MAX_COMP = 1;
  498. }
  499. dwSize = // similar to ClearCand
  500. // header length
  501. sizeof(CANDIDATELIST) +
  502. // candidate string pointers
  503. sizeof(DWORD) * MAX_COMP +
  504. // string plus NULL terminator
  505. (sizeof(WORD) + sizeof(TCHAR)) * MAX_COMP;
  506. if (!uBufLen) {
  507. return (dwSize);
  508. }
  509. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  510. uMaxCand /= sizeof(DWORD) + sizeof(WORD) + sizeof(TCHAR);
  511. if (!uMaxCand) {
  512. // can not even put one string
  513. return (0);
  514. }
  515. lpCandList->dwSize = dwSize;
  516. lpCandList->dwStyle = IME_CAND_READ; // candidate having same reading
  517. lpCandList->dwCount = 0;
  518. lpCandList->dwSelection = 0;
  519. lpCandList->dwPageSize = CANDPERPAGE;
  520. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
  521. (uMaxCand - 1);
  522. lpImcP->bSeq[0] = 0;
  523. lpImcP->bSeq[1] = 0;
  524. lpImcP->bSeq[2] = 0;
  525. lpImcP->bSeq[3] = 0;
  526. for (i=0;i<4;i++) {
  527. iRet = GBProcessKey(*(LPBYTE)((LPBYTE)lpszReading+i),lpImcP);
  528. if (iRet == CST_INPUT) {
  529. lpImcP->bSeq[i] = *(LPBYTE)((LPBYTE)lpszReading+i);
  530. } else {
  531. return (DWORD)0;
  532. }
  533. }
  534. wCode = GBEngine (lpImcP);
  535. wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
  536. for (i = 0; i < MAX_COMP;i++, wCode++) {
  537. AddCodeIntoCand(lpCandList, wCode);
  538. }
  539. GlobalUnlock (hImcP);
  540. GlobalFree (hImcP);
  541. return (dwSize);
  542. }
  543. /**************************************************************************
  544. BOOL DBCSToGBCode ( WORD wCode, BYTE AbSeq[5])
  545. ***************************************************************************/
  546. BOOL DBCSToGBCode (
  547. WORD wCode,
  548. TCHAR AbSeq[5])
  549. {
  550. WORD AreaCode;
  551. #ifdef UNICODE
  552. //Converte Unicode to GBK
  553. // change CP_ACP to 936, so that it can work under Multilingul Env.
  554. WideCharToMultiByte(NATIVE_ANSI_CP, WC_COMPOSITECHECK, &wCode, 1, (char *)&AreaCode, 2, NULL, NULL);
  555. wCode = AreaCode;
  556. #endif
  557. //check valid GB range code first
  558. #if defined(COMBO_IME)
  559. if(sImeL.dwRegImeIndex==INDEX_GB){
  560. if(LOBYTE(wCode) < 0xa1 || LOBYTE(wCode) > 0xfe
  561. || HIBYTE(wCode) < 0xa1 || HIBYTE(wCode) > 0xfe)
  562. return FALSE;
  563. AbSeq[1] = ((wCode -0xa0) % 256) % 10;
  564. AbSeq[0] = ((wCode -0xa0) % 256) / 10;
  565. AreaCode = (wCode - 0xa0 -AbSeq[0] * 10 -AbSeq[1])/256;
  566. AbSeq[3] = ((AreaCode -0xa0) % 256) % 10;
  567. AbSeq[2] = ((AreaCode -0xa0) % 256) / 10;
  568. AbSeq[4] = TEXT('\0';)
  569. }else if(sImeL.dwRegImeIndex==INDEX_GBK || sImeL.dwRegImeIndex==INDEX_UNICODE){
  570. WORD tmp;
  571. tmp = HIBYTE(wCode) | (LOBYTE(wCode)<<8);
  572. wsprintf(AbSeq,TEXT("%04x"), tmp);
  573. }
  574. else
  575. return FALSE;
  576. #else //COMBO_IME
  577. #ifdef GB
  578. if(LOBYTE(wCode) < 0xa1 || LOBYTE(wCode) > 0xfe
  579. || HIBYTE(wCode) < 0xa1 || HIBYTE(wCode) > 0xfe)
  580. return FALSE;
  581. AbSeq[1] = ((wCode -0xa0) % 256) % 10;
  582. AbSeq[0] = ((wCode -0xa0) % 256) / 10;
  583. AreaCode = (wCode - 0xa0 -AbSeq[0] * 10 -AbSeq[1])/256;
  584. AbSeq[3] = ((AreaCode -0xa0) % 256) % 10;
  585. AbSeq[2] = ((AreaCode -0xa0) % 256) / 10;
  586. AbSeq[4] = TEXT('\0');
  587. #else
  588. {
  589. WORD tmp;
  590. tmp = HIBYTE(wCode) | (LOBYTE(wCode)<<8);
  591. wsprintf(AbSeq,TEXT("%04x"), tmp);
  592. }
  593. #endif //GB
  594. #endif //COMBO_IME
  595. return TRUE;
  596. }
  597. /***************************************************************************
  598. BOOL AreaToGB ( BYTE AbSeq[5],BYTE GbSeq[5])
  599. ***************************************************************************/
  600. BOOL AreaToGB (
  601. TCHAR AbSeq[5],
  602. TCHAR GbSeq[5])
  603. {
  604. TCHAR MbSeq[3]; // Temp string
  605. // Area turn
  606. wsprintf (MbSeq,TEXT("%lx"),(AbSeq[0] * 10 + AbSeq[1]+0xa0));
  607. GbSeq[0] = MbSeq[0];
  608. GbSeq[1] = MbSeq[1];
  609. //position turn
  610. wsprintf (MbSeq,TEXT("%lx"),(AbSeq[2] * 10 + AbSeq[3]+0xa0));
  611. GbSeq[2] = MbSeq[0];
  612. GbSeq[3] = MbSeq[1];
  613. GbSeq[4] = TEXT('\0');
  614. return TRUE;
  615. }
  616. #if defined(COMBO_IME)
  617. /**********************************************************************/
  618. /* UnicodeReverseConversion() */
  619. /**********************************************************************/
  620. DWORD PASCAL UnicodeReverseConversion(
  621. WORD wCode,
  622. LPCANDIDATELIST lpCandList,
  623. UINT uBufLen)
  624. {
  625. UINT MAX_COMP = 1;
  626. UINT nMaxKey = 4;
  627. TCHAR AbSeq[5];
  628. UINT uMaxCand;
  629. DWORD dwSize = // similar to ClearCand
  630. // header length
  631. sizeof(CANDIDATELIST) +
  632. // candidate string pointers
  633. sizeof(DWORD) * MAX_COMP +
  634. // string plus NULL terminator
  635. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  636. if (!uBufLen) {
  637. return (dwSize);
  638. }
  639. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  640. uMaxCand /= sizeof(DWORD) +
  641. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  642. if (uMaxCand == 0) {
  643. // can not put one string
  644. return (0);
  645. }
  646. lpCandList->dwSize = sizeof(CANDIDATELIST) +
  647. sizeof(DWORD) * uMaxCand +
  648. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  649. lpCandList->dwStyle = IME_CAND_READ;
  650. lpCandList->dwCount = 0;
  651. lpCandList->dwSelection = 0;
  652. //lpCandList->dwPageSize = CANDPERPAGE; New Spac
  653. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) ;
  654. #ifndef UNICODE
  655. {
  656. WCHAR szWideStr[2];
  657. int i;
  658. memset(szWideStr, 0, sizeof(szWideStr));
  659. // change CP_ACP to 936, so that it can work under Multilingul Env.
  660. MultiByteToWideChar(NATIVE_ANSI_CP, 0, (LPCSTR)&wCode, sizeof(WORD), szWideStr, sizeof(szWideStr));
  661. wCode = HIBYTE((WORD)szWideStr[0]) | (LOBYTE((WORD)szWideStr[0]) << 8 );
  662. }
  663. if(!DBCSToGBCode (wCode, AbSeq))
  664. return 0; //actual is DBCSToGBInternalCode
  665. #endif
  666. wsprintf(AbSeq,TEXT("%04x"), wCode);
  667. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),AbSeq);
  668. // string count ++
  669. lpCandList->dwCount = 1;
  670. return (dwSize);
  671. }
  672. #endif //COMBO_IME
  673. /**********************************************************************/
  674. /* XGBReverseConversion() */
  675. /**********************************************************************/
  676. DWORD PASCAL XGBReverseConversion(
  677. WORD wCode,
  678. LPCANDIDATELIST lpCandList,
  679. UINT uBufLen)
  680. {
  681. UINT MAX_COMP = 1;
  682. UINT nMaxKey = 4;
  683. TCHAR AbSeq[5];
  684. UINT uMaxCand;
  685. DWORD dwSize = // similar to ClearCand
  686. // header length
  687. sizeof(CANDIDATELIST) +
  688. // candidate string pointers
  689. sizeof(DWORD) * MAX_COMP +
  690. // string plus NULL terminator
  691. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  692. if (!uBufLen) {
  693. return (dwSize);
  694. }
  695. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  696. uMaxCand /= sizeof(DWORD) +
  697. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  698. if (uMaxCand == 0) {
  699. // can not put one string
  700. return (0);
  701. }
  702. lpCandList->dwSize = sizeof(CANDIDATELIST) +
  703. sizeof(DWORD) * uMaxCand +
  704. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  705. lpCandList->dwStyle = IME_CAND_READ;
  706. lpCandList->dwCount = 0;
  707. lpCandList->dwSelection = 0;
  708. //lpCandList->dwPageSize = CANDPERPAGE; New Spac
  709. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) ;
  710. if(!DBCSToGBCode (wCode, AbSeq))
  711. return 0; //actual is DBCSToGBInternalCode
  712. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),AbSeq);
  713. // string count ++
  714. lpCandList->dwCount = 1;
  715. return (dwSize);
  716. }
  717. /**********************************************************************/
  718. /* ReverseConversion() */
  719. /**********************************************************************/
  720. DWORD PASCAL ReverseConversion(
  721. WORD wCode,
  722. LPCANDIDATELIST lpCandList,
  723. UINT uBufLen)
  724. {
  725. UINT MAX_COMP = 2;
  726. UINT nMaxKey = 4;
  727. TCHAR AbSeq[5];
  728. TCHAR GbSeq[5];
  729. UINT uMaxCand;
  730. DWORD dwSize = // similar to ClearCand
  731. // header length
  732. sizeof(CANDIDATELIST) +
  733. // candidate string pointers
  734. sizeof(DWORD) * MAX_COMP +
  735. // string plus NULL terminator
  736. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  737. if (!uBufLen) {
  738. return (dwSize);
  739. }
  740. uMaxCand = uBufLen - sizeof(CANDIDATELIST);
  741. uMaxCand /= sizeof(DWORD) +
  742. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  743. if (uMaxCand == 0) {
  744. // can not put one string
  745. return (0);
  746. }
  747. lpCandList->dwSize = sizeof(CANDIDATELIST) +
  748. sizeof(DWORD) * uMaxCand +
  749. (sizeof(TCHAR) * nMaxKey + sizeof(TCHAR));
  750. lpCandList->dwStyle = IME_CAND_READ;
  751. lpCandList->dwCount = 0;
  752. lpCandList->dwSelection = 0;
  753. //lpCandList->dwPageSize = CANDPERPAGE; New Spac
  754. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) ;
  755. if(!DBCSToGBCode (wCode, AbSeq))
  756. return 0;
  757. AreaToGB (AbSeq, GbSeq);
  758. AbSeq[1] +=TEXT('0');
  759. AbSeq[0] +=TEXT('0');
  760. AbSeq[3] +=TEXT('0');
  761. AbSeq[2] +=TEXT('0');
  762. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),AbSeq);
  763. lpCandList->dwOffset[1] =
  764. lpCandList->dwOffset[0] + 4*sizeof(TCHAR) + sizeof(TCHAR);
  765. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[1]),GbSeq);
  766. // string count ++
  767. lpCandList->dwCount = 2;
  768. return (dwSize);
  769. }
  770. /**********************************************************************/
  771. /* ImeConversionList() */
  772. /**********************************************************************/
  773. DWORD WINAPI ImeConversionList(
  774. HIMC hIMC,
  775. LPCTSTR lpszSrc,
  776. LPCANDIDATELIST lpCandList,
  777. DWORD uBufLen,
  778. UINT uFlag)
  779. {
  780. WORD wCode;
  781. LPINPUTCONTEXT lpIMC;
  782. LPPRIVCONTEXT lpImcP;
  783. if (!uBufLen) {
  784. } else if (!lpszSrc) {
  785. return (0);
  786. } else if (!*lpszSrc) {
  787. return (0);
  788. } else if (!lpCandList) {
  789. return (0);
  790. } else if (uBufLen <= sizeof(CANDIDATELIST)) {
  791. // buffer size can not even put the header information
  792. return (0);
  793. }
  794. switch (uFlag) {
  795. case GCL_CONVERSION:
  796. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  797. if (!lpIMC) {
  798. return (FALSE);
  799. }
  800. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  801. if (!lpImcP) {
  802. ImmUnlockIMC(hIMC);
  803. return (FALSE);
  804. }
  805. #if defined(COMBO_IME)
  806. if(sImeL.dwRegImeIndex==INDEX_GB)
  807. return (Conversion(lpszSrc, lpCandList, uBufLen));
  808. else if(sImeL.dwRegImeIndex==INDEX_GBK)
  809. return (XGBConversion(lpszSrc, lpCandList, uBufLen));
  810. else if(sImeL.dwRegImeIndex==INDEX_UNICODE)
  811. return (XGBConversion(lpszSrc, lpCandList, uBufLen));
  812. #else //COMBO_IME
  813. #ifdef GB
  814. return (Conversion(lpszSrc, lpCandList, uBufLen));
  815. #else
  816. return (XGBConversion(lpszSrc, lpCandList, uBufLen));
  817. #endif //GB
  818. #endif //COMBO_IME
  819. break;
  820. case GCL_REVERSECONVERSION:
  821. if (!uBufLen) {
  822. #if defined(COMBO_IME)
  823. return 1;
  824. #else //COMBO_IME
  825. #ifdef GB
  826. return 1;
  827. #else
  828. return 1;
  829. #endif //GB
  830. #endif //COMBO_IME
  831. }
  832. // only support one DBCS char reverse conversion
  833. if (*(LPTSTR)((LPBYTE)lpszSrc + sizeof(WORD)) != TEXT('\0')) {
  834. return (0);
  835. }
  836. wCode = *(LPWORD)lpszSrc;
  837. // swap lead byte & second byte, UNICODE don't need it
  838. // wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); For Big5
  839. #if defined(COMBO_IME)
  840. if(sImeL.dwRegImeIndex==INDEX_GB)
  841. return (ReverseConversion(wCode, lpCandList, uBufLen));
  842. else if(sImeL.dwRegImeIndex==INDEX_GBK)
  843. return (XGBReverseConversion(wCode, lpCandList, uBufLen));
  844. else if(sImeL.dwRegImeIndex==INDEX_UNICODE)
  845. return (UnicodeReverseConversion(wCode, lpCandList, uBufLen));
  846. #else //COMBO_IME
  847. #ifdef GB
  848. return (ReverseConversion(wCode, lpCandList, uBufLen));
  849. #else
  850. return (XGBReverseConversion(wCode, lpCandList, uBufLen));
  851. #endif //GB
  852. #endif //COMBO_IME
  853. break;
  854. default:
  855. return (0);
  856. break;
  857. }
  858. return (0);
  859. }
  860. /**********************************************************************/
  861. /* ImeDestroy() */
  862. /* Return Value: */
  863. /* TRUE - successful, FALSE - failure */
  864. /**********************************************************************/
  865. BOOL WINAPI ImeDestroy( // this dll is unloaded
  866. UINT uReserved)
  867. {
  868. if (uReserved) {
  869. return (FALSE);
  870. }
  871. return (TRUE);
  872. }
  873. /**********************************************************************/
  874. /* ImeEscape() */
  875. /* Return Value: */
  876. /* TRUE - successful, FALSE - failure */
  877. /**********************************************************************/
  878. #define IME_INPUTKEYTOSEQUENCE 0x22
  879. LRESULT WINAPI ImeEscape( // escape function of IMEs
  880. HIMC hIMC,
  881. UINT uSubFunc,
  882. LPVOID lpData)
  883. {
  884. LRESULT lRet;
  885. switch (uSubFunc) {
  886. case IME_ESC_QUERY_SUPPORT:
  887. if ( lpData == NULL )
  888. return FALSE;
  889. switch (*(LPUINT)lpData) {
  890. case IME_ESC_QUERY_SUPPORT:
  891. case IME_ESC_MAX_KEY:
  892. case IME_ESC_IME_NAME:
  893. case IME_ESC_GETHELPFILENAME:
  894. return (TRUE);
  895. case IME_ESC_SEQUENCE_TO_INTERNAL:
  896. case IME_ESC_GET_EUDC_DICTIONARY:
  897. case IME_ESC_SET_EUDC_DICTIONARY:
  898. case IME_INPUTKEYTOSEQUENCE: // will not supported in next version
  899. return (FALSE); // will not supported in GB IME
  900. default:
  901. return (FALSE);
  902. }
  903. break;
  904. case IME_ESC_SEQUENCE_TO_INTERNAL:
  905. case IME_ESC_GET_EUDC_DICTIONARY:
  906. case IME_ESC_SET_EUDC_DICTIONARY:
  907. case IME_INPUTKEYTOSEQUENCE:
  908. return (FALSE);
  909. case IME_ESC_MAX_KEY:
  910. return ((WORD) 4);
  911. case IME_ESC_IME_NAME:
  912. if ( lpData == NULL )
  913. return FALSE;
  914. lstrcpy(lpData, szImeName);
  915. return (TRUE);
  916. case IME_ESC_GETHELPFILENAME:
  917. {
  918. TCHAR szIMEGUDHlpName[MAX_PATH];
  919. if (lpData == NULL )
  920. return FALSE;
  921. szIMEGUDHlpName[0] = 0;
  922. GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAX_PATH);
  923. lstrcat((LPTSTR)szIMEGUDHlpName, TEXT("\\HELP\\WINGB.CHM"));
  924. lstrcpy(lpData, szIMEGUDHlpName);
  925. return TRUE;
  926. }
  927. default:
  928. return (FALSE);
  929. }
  930. return (lRet);
  931. }
  932. /**********************************************************************/
  933. /* InitCompStr() */
  934. /**********************************************************************/
  935. void PASCAL InitCompStr( // init setting for composing string
  936. LPCOMPOSITIONSTRING lpCompStr)
  937. {
  938. if (!lpCompStr) {
  939. return;
  940. }
  941. lpCompStr->dwCompReadAttrLen = 0;
  942. lpCompStr->dwCompReadClauseLen = 0;
  943. lpCompStr->dwCompReadStrLen = 0;
  944. lpCompStr->dwCompAttrLen = 0;
  945. lpCompStr->dwCompClauseLen = 0;
  946. lpCompStr->dwCompStrLen = 0;
  947. lpCompStr->dwCursorPos = 0;
  948. lpCompStr->dwDeltaStart = 0;
  949. lpCompStr->dwResultReadClauseLen = 0;
  950. lpCompStr->dwResultReadStrLen = 0;
  951. lpCompStr->dwResultClauseLen = 0;
  952. lpCompStr->dwResultStrLen = 0;
  953. return;
  954. }
  955. /**********************************************************************/
  956. /* ClearCompStr() */
  957. /* Return Value: */
  958. /* TRUE - successful, FALSE - failure */
  959. /**********************************************************************/
  960. BOOL PASCAL ClearCompStr(
  961. LPINPUTCONTEXT lpIMC)
  962. {
  963. HIMCC hMem;
  964. LPCOMPOSITIONSTRING lpCompStr;
  965. DWORD dwSize;
  966. if(!lpIMC) {
  967. return (FALSE);
  968. }
  969. dwSize =
  970. // header length
  971. sizeof(COMPOSITIONSTRING) +
  972. // composition reading attribute plus NULL terminator
  973. lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE) +
  974. // composition reading clause
  975. sizeof(DWORD) + sizeof(DWORD) +
  976. // composition reading string plus NULL terminator
  977. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
  978. // result reading clause
  979. sizeof(DWORD) + sizeof(DWORD) +
  980. // result reading string plus NULL terminateor
  981. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
  982. // result clause
  983. sizeof(DWORD) + sizeof(DWORD) +
  984. // result string plus NULL terminateor
  985. MAXSTRLEN * sizeof(WORD) + sizeof(WORD);
  986. if (!lpIMC->hCompStr) {
  987. // it maybe free by other IME, init it
  988. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  989. } else if (hMem = ImmReSizeIMCC(lpIMC->hCompStr, dwSize)) {
  990. lpIMC->hCompStr = hMem;
  991. } else {
  992. ImmDestroyIMCC(lpIMC->hCompStr);
  993. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  994. return (FALSE);
  995. }
  996. if (!lpIMC->hCompStr) {
  997. return (FALSE);
  998. }
  999. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  1000. if (!lpCompStr) {
  1001. ImmDestroyIMCC(lpIMC->hCompStr);
  1002. lpIMC->hCompStr = ImmCreateIMCC(dwSize);
  1003. return (FALSE);
  1004. }
  1005. lpCompStr->dwSize = dwSize;
  1006. // 1. composition (reading) string - simple IME
  1007. // 2. result reading string
  1008. // 3. result string
  1009. lpCompStr->dwCompReadAttrLen = 0;
  1010. lpCompStr->dwCompReadAttrOffset = sizeof(COMPOSITIONSTRING);
  1011. lpCompStr->dwCompReadClauseLen = 0;
  1012. lpCompStr->dwCompReadClauseOffset = lpCompStr->dwCompReadAttrOffset +
  1013. lpImeL->nMaxKey * sizeof(TCHAR) + sizeof(TCHAR);
  1014. lpCompStr->dwCompReadStrLen = 0;
  1015. lpCompStr->dwCompReadStrOffset = lpCompStr->dwCompReadClauseOffset +
  1016. sizeof(DWORD) + sizeof(DWORD);
  1017. // composition string is the same with composition reading string
  1018. // for simple IMEs
  1019. lpCompStr->dwCompAttrLen = 0;
  1020. lpCompStr->dwCompAttrOffset = lpCompStr->dwCompReadAttrOffset;
  1021. lpCompStr->dwCompClauseLen = 0;
  1022. lpCompStr->dwCompClauseOffset = lpCompStr->dwCompReadClauseOffset;
  1023. lpCompStr->dwCompStrLen = 0;
  1024. lpCompStr->dwCompStrOffset = lpCompStr->dwCompReadStrOffset;
  1025. lpCompStr->dwCursorPos = 0;
  1026. lpCompStr->dwDeltaStart = 0;
  1027. lpCompStr->dwResultReadClauseLen = 0;
  1028. lpCompStr->dwResultReadClauseOffset = lpCompStr->dwCompStrOffset +
  1029. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
  1030. lpCompStr->dwResultReadStrLen = 0;
  1031. lpCompStr->dwResultReadStrOffset = lpCompStr->dwResultReadClauseOffset +
  1032. sizeof(DWORD) + sizeof(DWORD);
  1033. lpCompStr->dwResultClauseLen = 0;
  1034. lpCompStr->dwResultClauseOffset = lpCompStr->dwResultReadStrOffset +
  1035. lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
  1036. lpCompStr->dwResultStrOffset = 0;
  1037. lpCompStr->dwResultStrOffset = lpCompStr->dwResultClauseOffset +
  1038. sizeof(DWORD) + sizeof(DWORD);
  1039. GlobalUnlock((HGLOBAL)lpIMC->hCompStr);
  1040. return (TRUE);
  1041. }
  1042. /**********************************************************************/
  1043. /* ClearCand() */
  1044. /* Return Value: */
  1045. /* TRUE - successful, FALSE - failure */
  1046. /**********************************************************************/
  1047. BOOL PASCAL ClearCand(
  1048. LPINPUTCONTEXT lpIMC)
  1049. {
  1050. HIMCC hMem;
  1051. LPCANDIDATEINFO lpCandInfo;
  1052. LPCANDIDATELIST lpCandList;
  1053. DWORD dwSize =
  1054. // header length
  1055. sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST) +
  1056. // candidate string pointers
  1057. sizeof(DWORD) * (MAXCAND + 1) +
  1058. // string plus NULL terminator
  1059. (sizeof(WORD) + sizeof(WORD)) * (MAXCAND + 1);
  1060. if (!lpIMC) {
  1061. return (FALSE);
  1062. }
  1063. if (!lpIMC->hCandInfo) {
  1064. // it maybe free by other IME, init it
  1065. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  1066. } else if (hMem = ImmReSizeIMCC(lpIMC->hCandInfo, dwSize)) {
  1067. lpIMC->hCandInfo = hMem;
  1068. } else {
  1069. ImmDestroyIMCC(lpIMC->hCandInfo);
  1070. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  1071. return (FALSE);
  1072. }
  1073. if (!lpIMC->hCandInfo) {
  1074. return (FALSE);
  1075. }
  1076. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  1077. if (!lpCandInfo) {
  1078. ImmDestroyIMCC(lpIMC->hCandInfo);
  1079. lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
  1080. return (FALSE);
  1081. }
  1082. // ordering of strings are
  1083. // buffer size
  1084. lpCandInfo->dwSize = dwSize;
  1085. lpCandInfo->dwCount = 0;
  1086. lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
  1087. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
  1088. lpCandInfo->dwOffset[0]);
  1089. // whole candidate info size - header
  1090. lpCandList->dwSize = lpCandInfo->dwSize - sizeof(CANDIDATEINFO);
  1091. lpCandList->dwStyle = IME_CAND_READ;
  1092. lpCandList->dwCount = 0;
  1093. lpCandList->dwSelection = 0;
  1094. lpCandList->dwPageSize = CANDPERPAGE;
  1095. lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) +
  1096. sizeof(DWORD) * (MAXCAND );
  1097. ImmUnlockIMCC(lpIMC->hCandInfo);
  1098. return (TRUE);
  1099. }
  1100. /**********************************************************************/
  1101. /* ClearGuideLine() */
  1102. /* Return Value: */
  1103. /* TRUE - successful, FALSE - failure */
  1104. /**********************************************************************/
  1105. BOOL PASCAL ClearGuideLine(
  1106. LPINPUTCONTEXT lpIMC)
  1107. {
  1108. HIMCC hMem;
  1109. LPGUIDELINE lpGuideLine;
  1110. DWORD dwSize = sizeof(GUIDELINE) + sImeG.cbStatusErr;
  1111. if (!lpIMC->hGuideLine) {
  1112. // it maybe free by IME
  1113. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  1114. } else if (hMem = ImmReSizeIMCC(lpIMC->hGuideLine, dwSize)) {
  1115. lpIMC->hGuideLine = hMem;
  1116. } else {
  1117. ImmDestroyIMCC(lpIMC->hGuideLine);
  1118. lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
  1119. }
  1120. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  1121. if (!lpGuideLine) {
  1122. return (FALSE);
  1123. }
  1124. lpGuideLine->dwSize = dwSize;
  1125. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  1126. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  1127. lpGuideLine->dwStrLen = 0;
  1128. lpGuideLine->dwStrOffset = sizeof(GUIDELINE);
  1129. CopyMemory((LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset,
  1130. sImeG.szStatusErr, sImeG.cbStatusErr);
  1131. ImmUnlockIMCC(lpIMC->hGuideLine);
  1132. return (TRUE);
  1133. }
  1134. /**********************************************************************/
  1135. /* InitContext() */
  1136. /**********************************************************************/
  1137. void PASCAL InitContext(
  1138. LPINPUTCONTEXT lpIMC)
  1139. {
  1140. if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
  1141. } else if (!lpIMC->hWnd) {
  1142. } else {
  1143. #ifdef MUL_MONITOR
  1144. RECT rcWorkArea;
  1145. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  1146. lpIMC->ptStatusWndPos.x = rcWorkArea.left;
  1147. lpIMC->ptStatusWndPos.y = rcWorkArea.bottom -
  1148. sImeG.yStatusHi;
  1149. #else
  1150. POINT ptWnd;
  1151. ptWnd.x = 0;
  1152. ptWnd.y = 0;
  1153. ClientToScreen(lpIMC->hWnd, &ptWnd);
  1154. if (ptWnd.x < sImeG.rcWorkArea.left) {
  1155. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
  1156. } else if (ptWnd.x + sImeG.xStatusWi > sImeG.rcWorkArea.right) {
  1157. lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
  1158. sImeG.xStatusWi;
  1159. } else {
  1160. lpIMC->ptStatusWndPos.x = ptWnd.x;
  1161. }
  1162. lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
  1163. sImeG.yStatusHi;
  1164. #endif
  1165. lpIMC->fdwInit |= INIT_STATUSWNDPOS;
  1166. }
  1167. if (lpIMC->fdwInit & INIT_COMPFORM) {
  1168. } else if (!lpIMC->hWnd) {
  1169. } else {
  1170. POINT ptWnd;
  1171. ptWnd = lpImeL->ptDefComp;
  1172. ScreenToClient(lpIMC->hWnd, &ptWnd);
  1173. lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
  1174. lpIMC->cfCompForm.ptCurrentPos = ptWnd;
  1175. lpIMC->fdwInit |= INIT_COMPFORM;
  1176. }
  1177. return;
  1178. }
  1179. /**********************************************************************/
  1180. /* Select() */
  1181. /* Return Value: */
  1182. /* TRUE - successful, FALSE - failure */
  1183. /**********************************************************************/
  1184. BOOL PASCAL Select(
  1185. HIMC hIMC,
  1186. LPINPUTCONTEXT lpIMC,
  1187. BOOL fSelect)
  1188. {
  1189. LPPRIVCONTEXT lpImcP;
  1190. UINT i;
  1191. if (fSelect) {
  1192. if (!ClearCompStr(lpIMC))
  1193. return FALSE;
  1194. if (!ClearCand(lpIMC))
  1195. return FALSE;
  1196. ClearGuideLine(lpIMC);
  1197. }
  1198. if (lpIMC->cfCandForm[0].dwIndex != 0)
  1199. lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
  1200. // We add this hack for switching from other IMEs, this IME has a bug.
  1201. // Before this bug fixed in this IME, it depends on this hack.
  1202. if (lpIMC->cfCandForm[0].dwStyle == CFS_DEFAULT) {
  1203. lpIMC->cfCandForm[0].dwIndex = (DWORD)-1;
  1204. }
  1205. if (!lpIMC->hPrivate)
  1206. return FALSE;
  1207. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  1208. if (!lpImcP)
  1209. return FALSE;
  1210. if (fSelect) {
  1211. //
  1212. // init fields of hPrivate
  1213. //
  1214. lpImcP->iImeState = CST_INIT;
  1215. lpImcP->fdwImeMsg = (DWORD)0;
  1216. lpImcP->dwCompChar = (DWORD)0;
  1217. lpImcP->fdwGcsFlag = (DWORD)0;
  1218. lpImcP->uSYHFlg = (UINT)0;
  1219. lpImcP->uDYHFlg = (UINT)0;
  1220. lpImcP->uDSMHCount = (UINT)0;
  1221. lpImcP->uDSMHFlg = (UINT)0;
  1222. //lpImcP->fdwSentence = (DWORD)NULL;
  1223. //
  1224. // reset SK State
  1225. //
  1226. *(LPDWORD)lpImcP->bSeq = 0;
  1227. #ifdef CROSSREF
  1228. lpImcP->hRevCandList = (HIMCC) NULL;
  1229. #endif //CROSSREF
  1230. lpIMC->fOpen = TRUE;
  1231. if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
  1232. lpIMC->fdwConversion = (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) |
  1233. IME_CMODE_NATIVE;
  1234. lpIMC->fdwInit |= INIT_CONVERSION;
  1235. }
  1236. if (lpIMC->fdwInit & INIT_SENTENCE) {
  1237. } else if (lpImeL->fModeConfig & MODE_CONFIG_PREDICT) {
  1238. lpIMC->fdwSentence = IME_SMODE_PHRASEPREDICT;
  1239. lpIMC->fdwInit |= INIT_SENTENCE;
  1240. }
  1241. if (!(lpIMC->fdwInit & INIT_LOGFONT)) {
  1242. HDC hDC;
  1243. HGDIOBJ hSysFont;
  1244. //hSysFont = GetStockObject(SYSTEM_FONT);
  1245. hDC = GetDC(NULL);
  1246. hSysFont = GetCurrentObject(hDC, OBJ_FONT);
  1247. GetObject(hSysFont, sizeof(LOGFONT), &lpIMC->lfFont.A);
  1248. ReleaseDC(NULL, hDC);
  1249. lpIMC->fdwInit |= INIT_LOGFONT;
  1250. }
  1251. InitContext(lpIMC);
  1252. //
  1253. // Set Caps status
  1254. //
  1255. {
  1256. DWORD fdwConversion;
  1257. if (GetKeyState(VK_CAPITAL) & 0x01) {
  1258. //
  1259. // Change to alphanumeric mode.
  1260. //
  1261. fdwConversion = lpIMC->fdwConversion &
  1262. ~(IME_CMODE_NATIVE | IME_CMODE_CHARCODE | IME_CMODE_EUDC);
  1263. } else {
  1264. //
  1265. // Change to native mode
  1266. //
  1267. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  1268. ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC );
  1269. }
  1270. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  1271. }
  1272. } else {
  1273. if (lpImeL->hSKMenu) {
  1274. DestroyMenu(lpImeL->hSKMenu);
  1275. lpImeL->hSKMenu = NULL;
  1276. }
  1277. if (lpImeL->hPropMenu) {
  1278. DestroyMenu(lpImeL->hPropMenu);
  1279. lpImeL->hPropMenu = NULL;
  1280. }
  1281. if (hCrtDlg) {
  1282. SendMessage(hCrtDlg, WM_CLOSE, (WPARAM)NULL, (LPARAM)NULL);
  1283. hCrtDlg = NULL;
  1284. }
  1285. }
  1286. ImmUnlockIMCC(lpIMC->hPrivate);
  1287. return (TRUE);
  1288. }
  1289. /**********************************************************************/
  1290. /* ImeSelect() */
  1291. /* Return Value: */
  1292. /* TRUE - successful, FALSE - failure */
  1293. /**********************************************************************/
  1294. BOOL WINAPI ImeSelect(
  1295. HIMC hIMC,
  1296. BOOL fSelect)
  1297. {
  1298. LPINPUTCONTEXT lpIMC;
  1299. BOOL fRet;
  1300. if (!hIMC) {
  1301. return (FALSE);
  1302. }
  1303. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1304. if (!lpIMC) {
  1305. return (FALSE);
  1306. }
  1307. fRet = Select(hIMC, lpIMC, fSelect);
  1308. ImmUnlockIMC(hIMC);
  1309. return (fRet);
  1310. }
  1311. /**********************************************************************/
  1312. /* ImeSetActiveContext() */
  1313. /* Return Value: */
  1314. /* TRUE - successful, FALSE - failure */
  1315. /**********************************************************************/
  1316. BOOL WINAPI ImeSetActiveContext(
  1317. HIMC hIMC,
  1318. BOOL fOn)
  1319. {
  1320. if (!fOn) {
  1321. } else if (!hIMC) {
  1322. } else {
  1323. LPINPUTCONTEXT lpIMC;
  1324. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1325. if (!lpIMC) {
  1326. return (FALSE);
  1327. }
  1328. InitContext(lpIMC);
  1329. ImmUnlockIMC(hIMC);
  1330. }
  1331. return (TRUE);
  1332. }
  1333. /**********************************************************************/
  1334. //OpenReg_PathSetup(HKEY *phKey);
  1335. /**********************************************************************/
  1336. LONG OpenReg_PathSetup(HKEY *phKey)
  1337. {
  1338. return RegOpenKeyEx (HKEY_CURRENT_USER,
  1339. REGSTR_PATH_SETUP,
  1340. 0,
  1341. KEY_ENUMERATE_SUB_KEYS |
  1342. KEY_EXECUTE |
  1343. KEY_QUERY_VALUE,
  1344. phKey);
  1345. }
  1346. /**********************************************************************/
  1347. //LONG OpenReg_User(HKEY hKey, // handle of open key
  1348. // LPCTSTR lpszSubKey, // address of name of subkey to open
  1349. // PHKEY phkResult); // address of handle of open key
  1350. /**********************************************************************/
  1351. LONG OpenReg_User(HKEY hKey, // handle of open key
  1352. LPCTSTR lpszSubKey, // address of name of subkey to open
  1353. PHKEY phkResult) // address of handle of open key
  1354. {
  1355. return RegOpenKeyEx (hKey,
  1356. lpszSubKey,
  1357. 0,
  1358. KEY_ALL_ACCESS,
  1359. phkResult);
  1360. }
  1361. VOID InfoMessage(HANDLE hWnd,WORD wMsgID)
  1362. {
  1363. TCHAR szStr[256];
  1364. LoadString(NULL,wMsgID,szStr, sizeof(szStr)/sizeof(TCHAR));
  1365. MessageBox(hWnd,szStr,szWarnTitle,MB_ICONINFORMATION|MB_OK);
  1366. }
  1367. VOID FatalMessage(HANDLE hWnd,WORD wMsgID)
  1368. {
  1369. TCHAR szStr[256];
  1370. LoadString(NULL,wMsgID,szStr, sizeof(szStr)/sizeof(TCHAR));
  1371. MessageBox(hWnd,szStr,szErrorTitle,MB_ICONSTOP|MB_OK);
  1372. }