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.

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