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.

1288 lines
41 KiB

  1. /*++
  2. Copyright (c) 1995-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. TOASCII.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include <imedefs.h>
  9. /**********************************************************************/
  10. /* IsUsedCode() */
  11. /* Return Value: */
  12. /* TURE: is UsedCode; FALSE: is'nt UsedCode; */
  13. /**********************************************************************/
  14. BOOL IsUsedCode(
  15. WORD wCharCode,
  16. LPPRIVCONTEXT lpImcP)
  17. {
  18. WORD wFlg;
  19. for(wFlg=0; wFlg<MBIndex.MBDesc[0].wNumCodes; wFlg++)
  20. if (wCharCode == MBIndex.MBDesc[0].szUsedCode[wFlg])
  21. break;
  22. if(wFlg < MBIndex.MBDesc[0].wNumCodes)
  23. return (TRUE);
  24. return (FALSE);
  25. }
  26. /**********************************************************************/
  27. /* ProcessKey() */
  28. /* Return Value: */
  29. /* different state which input key will change IME to (CST_) */
  30. /**********************************************************************/
  31. UINT PASCAL ProcessKey( // this key will cause the IME go to what state
  32. WORD wCharCode,
  33. UINT uVirtKey,
  34. UINT uScanCode,
  35. LPBYTE lpbKeyState,
  36. LPINPUTCONTEXT lpIMC,
  37. LPPRIVCONTEXT lpImcP)
  38. {
  39. LPCOMPOSITIONSTRING lpCompStr;
  40. if (!lpIMC) {
  41. return (CST_INVALID);
  42. }
  43. if (!lpImcP) {
  44. return (CST_INVALID);
  45. }
  46. // filter system key (alt,alt+,ctrl,shift)
  47. // and fOpen, IME_CMODE_NOCONVERSION
  48. if (uVirtKey == VK_MENU) { // ALT key
  49. return (CST_INVALID);
  50. } else if (uScanCode & KF_ALTDOWN) { // ALT-xx key
  51. return (CST_INVALID);
  52. } else if (uVirtKey == VK_CONTROL) { // CTRL key
  53. return (CST_INVALID);
  54. } else if (uVirtKey == VK_SHIFT) { // SHIFT key
  55. return (CST_INVALID);
  56. } else if (!lpIMC->fOpen) { // don't compose in
  57. // close status
  58. return (CST_INVALID);
  59. } else if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
  60. // Caps on/off
  61. if(uVirtKey == VK_CAPITAL) {
  62. return (CST_CAPITAL);
  63. }else
  64. return (CST_INVALID);
  65. } else {
  66. // need more check
  67. }
  68. // Caps on/off
  69. if(uVirtKey == VK_CAPITAL) {
  70. return (CST_CAPITAL);
  71. }
  72. // SoftKBD
  73. if ((lpIMC->fdwConversion & IME_CMODE_SOFTKBD)
  74. && (lpImeL->dwSKWant != 0)){
  75. if (wCharCode >= TEXT(' ') && wCharCode <= TEXT('~')) {
  76. return (CST_SOFTKB);
  77. } else {
  78. return (CST_INVALID);
  79. }
  80. }
  81. // Online create word Hot Key
  82. if (lpbKeyState[VK_CONTROL] & 0x80) {
  83. if((uVirtKey == 0xc0) && (MBIndex.MBDesc[0].wNumRulers)) {
  84. return (CST_ONLINE_CZ);
  85. } else {
  86. return (CST_INVALID);
  87. }
  88. }
  89. // candidate alaredy open, Choose State
  90. // PagUp, PagDown, -, =, Home, End,ECS,key
  91. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  92. if (uVirtKey == VK_PRIOR) { // PageUp
  93. return (CST_CHOOSE);
  94. } else if (uVirtKey == VK_NEXT) { // PageDown
  95. return (CST_CHOOSE);
  96. } else if (uVirtKey == VK_HOME) { // Home
  97. return (CST_CHOOSE);
  98. } else if (uVirtKey == VK_END) { // End
  99. return (CST_CHOOSE);
  100. } else if ((wCharCode == TEXT('-')) && (!IsUsedCode(TEXT('-'), lpImcP))) {
  101. return (CST_CHOOSE);
  102. } else if ((wCharCode == TEXT('=')) && (!IsUsedCode(TEXT('='), lpImcP))) {
  103. return (CST_CHOOSE);
  104. } else if (uVirtKey == VK_ESCAPE) { // Esc
  105. return (CST_CHOOSE);
  106. } else if (uVirtKey == VK_RETURN) {
  107. if(MBIndex.IMEChara[0].IC_Enter) {
  108. return (CST_CHOOSE);
  109. }
  110. } else {
  111. // need more check
  112. }
  113. }
  114. // candidate alaredy open, shift + num key
  115. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  116. WORD NumCode, wFlg;
  117. if(uVirtKey == TEXT(' ')) {
  118. if(MBIndex.IMEChara[0].IC_Space) {
  119. return (CST_CHOOSE);
  120. }
  121. }
  122. NumCode = 0x0030;
  123. for(wFlg=0; wFlg<10; wFlg++, NumCode++)
  124. if(IsUsedCode(NumCode, lpImcP)) break;
  125. if(wFlg == 10) {
  126. if (uVirtKey >= TEXT('0') && uVirtKey <= TEXT('9')
  127. && !(lpbKeyState[VK_SHIFT] & 0x80))
  128. return (CST_CHOOSE);
  129. } else {
  130. if (lpbKeyState[VK_SHIFT] & 0x80) {
  131. if ((uVirtKey >= TEXT('0')) && uVirtKey <= TEXT('9'))
  132. return (CST_CHOOSE);
  133. }
  134. }
  135. }
  136. // IME_CMODE_CHARCODE
  137. if (lpIMC->fdwConversion & IME_CMODE_CHARCODE) { //Code Input Mode
  138. return (CST_INVALID);
  139. }
  140. if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  141. // alphanumeric mode
  142. if (wCharCode >= TEXT(' ') && wCharCode <= TEXT('~')) {
  143. return (CST_ALPHANUMERIC);
  144. } else {
  145. return (CST_INVALID);
  146. }
  147. } else if(wCharCode == MBIndex.MBDesc[0].cWildChar) {
  148. if (lpImcP->iImeState != CST_INIT) {
  149. } else {
  150. return (CST_ALPHANUMERIC);
  151. }
  152. } else if (wCharCode == TEXT(' ')){
  153. if ((lpImcP->iImeState == CST_INIT)
  154. && !(lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  155. return (CST_ALPHANUMERIC);
  156. }
  157. } else if(wCharCode >= TEXT(' ') && wCharCode <= TEXT('~')) {
  158. if(!IsUsedCode(wCharCode, lpImcP)
  159. && lpImcP->iImeState != CST_INIT)
  160. return (CST_INVALID_INPUT);
  161. }
  162. // Esc key
  163. if ((uVirtKey == VK_ESCAPE)
  164. || ((uVirtKey == VK_RETURN)
  165. && (MBIndex.IMEChara[0].IC_Enter))) {
  166. register LPGUIDELINE lpGuideLine;
  167. register UINT iImeState;
  168. lpGuideLine = ImmLockIMCC(lpIMC->hGuideLine);
  169. if(!lpGuideLine){
  170. return(CST_INVALID);
  171. }
  172. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  173. iImeState = CST_INPUT;
  174. } else if(lpImcP->PrivateArea.Comp_Status.OnLineCreWord) {
  175. iImeState = CST_ONLINE_CZ;
  176. } else if (!lpGuideLine) {
  177. iImeState = CST_INVALID;
  178. } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
  179. iImeState = CST_INVALID;
  180. } else {
  181. iImeState = CST_INVALID;
  182. }
  183. ImmUnlockIMCC(lpIMC->hGuideLine);
  184. return (iImeState);
  185. }
  186. // BackSpace Key
  187. else if (uVirtKey == VK_BACK) {
  188. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  189. return (CST_INPUT);
  190. } else {
  191. return (CST_INVALID);
  192. }
  193. }
  194. else if (uVirtKey >= VK_NUMPAD0 && uVirtKey <= VK_DIVIDE) {
  195. if (lpImcP->iImeState != CST_INIT) {
  196. return (CST_INVALID_INPUT);
  197. } else {
  198. return (CST_ALPHANUMERIC);
  199. }
  200. }
  201. {
  202. register UINT iImeState;
  203. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  204. if (!lpCompStr) {
  205. return (CST_INVALID);
  206. }
  207. // check finalize char
  208. if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  209. if((IsUsedCode(wCharCode, lpImcP))
  210. || (wCharCode == MBIndex.MBDesc[0].cWildChar)) {
  211. if ((wCharCode == MBIndex.MBDesc[0].cWildChar)
  212. && (lpImcP->PrivateArea.Comp_Status.dwSTMULCODE)) {
  213. iImeState = CST_INVALID_INPUT;
  214. } else if((!lpImcP->PrivateArea.Comp_Status.dwInvalid)
  215. && (lpCompStr->dwCursorPos < MBIndex.MBDesc[0].wMaxCodes)){
  216. iImeState = CST_INPUT;
  217. } else if((lpCompStr->dwCursorPos == MBIndex.MBDesc[0].wMaxCodes)
  218. && (lpImcP->PrivateArea.Comp_Status.dwSTMULCODE)) {
  219. iImeState = CST_INPUT;
  220. } else {
  221. iImeState = CST_INVALID_INPUT;
  222. }
  223. } else if(wCharCode == TEXT(' ')) {
  224. iImeState = CST_INPUT;
  225. } else if (wCharCode >= TEXT(' ') && wCharCode <= TEXT('~')) {
  226. iImeState = CST_ALPHANUMERIC;
  227. } else {
  228. iImeState = CST_INVALID;
  229. }
  230. } else {
  231. iImeState = CST_INVALID;
  232. }
  233. ImmUnlockIMCC(lpIMC->hCompStr);
  234. return (iImeState);
  235. }
  236. }
  237. /**********************************************************************/
  238. /* ImeProcessKey() */
  239. /* Return Value: */
  240. /* TRUE - successful, FALSE - failure */
  241. /**********************************************************************/
  242. BOOL WINAPI ImeProcessKey( // if this key is need by IME?
  243. HIMC hIMC,
  244. UINT uVirtKey,
  245. LPARAM lParam,
  246. CONST LPBYTE lpbKeyState)
  247. {
  248. LPINPUTCONTEXT lpIMC;
  249. LPPRIVCONTEXT lpImcP;
  250. BYTE szAscii[4];
  251. int nChars;
  252. int iRet;
  253. BOOL fRet;
  254. // can't compose in NULL hIMC
  255. if (!hIMC) {
  256. return (FALSE);
  257. }
  258. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  259. if (!lpIMC) {
  260. return (FALSE);
  261. }
  262. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  263. if (!lpImcP) {
  264. ImmUnlockIMC(hIMC);
  265. return (FALSE);
  266. }
  267. nChars = ToAscii(uVirtKey, HIWORD(lParam), lpbKeyState,
  268. (LPVOID)szAscii, 0);
  269. if (!nChars) {
  270. szAscii[0] = 0;
  271. }
  272. iRet = ProcessKey((WORD)szAscii[0], uVirtKey, HIWORD(lParam), lpbKeyState, lpIMC, lpImcP);
  273. if(iRet == CST_INVALID) {
  274. if ((lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)
  275. && (lpImcP->iImeState == CST_INIT)
  276. && !lpImcP->PrivateArea.Comp_Status.dwSTLX) {
  277. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  278. ~(MSG_OPEN_CANDIDATE) & ~(MSG_IN_IMETOASCIIEX);
  279. GenerateMessage(hIMC, lpIMC, lpImcP);
  280. // init lpImcP
  281. lpImcP->PrivateArea.Comp_Context.szInBuffer[0] = 0;
  282. lpImcP->PrivateArea.Comp_Context.PromptCnt = 0;
  283. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  284. lpImcP->PrivateArea.Comp_Status.dwSTLX = 0;
  285. lpImcP->PrivateArea.Comp_Status.dwSTMULCODE = 0;
  286. }
  287. fRet = FALSE;
  288. } else if((iRet == CST_INPUT) && (uVirtKey == TEXT('\b'))
  289. && (lpImcP->iImeState == CST_INIT)) {
  290. lpImcP->fdwImeMsg = ((lpImcP->fdwImeMsg | MSG_END_COMPOSITION)
  291. & ~(MSG_START_COMPOSITION)) & ~(MSG_IN_IMETOASCIIEX);
  292. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  293. ClearCand(lpIMC);
  294. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  295. ~(MSG_OPEN_CANDIDATE);
  296. }
  297. GenerateMessage(hIMC, lpIMC, lpImcP);
  298. fRet = FALSE;
  299. } else if(uVirtKey == VK_CAPITAL) {
  300. DWORD fdwConversion;
  301. // init ime Private status
  302. lpImcP->PrivateArea.Comp_Status.dwSTLX = 0;
  303. lpImcP->PrivateArea.Comp_Status.dwSTMULCODE = 0;
  304. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  305. //Change VK_CAPITAL status check to NT .351 IMM style.
  306. #ifdef LATER
  307. //Code for Win95
  308. if (lpbKeyState[VK_CAPITAL] & 0x01) {
  309. // change to native mode
  310. #ifdef EUDC
  311. fdwConversion = (lpIMC->fdwConversion |IME_CMODE_NATIVE);
  312. fdwConversion &= ~(IME_CMODE_CHARCODE | IME_CMODE_NOCONVERSION);
  313. #else
  314. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE);
  315. fdwConversion &= ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC | IME_CMODE_NOCONVERSION);
  316. #endif //EUDC
  317. uCaps = 0;
  318. } else {
  319. #else //LATER
  320. //Code for NT 3.51
  321. if (lpbKeyState[VK_CAPITAL] & 0x01) {
  322. // change to alphanumeric mode
  323. #ifdef EUDC
  324. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_CHARCODE |
  325. IME_CMODE_NATIVE);
  326. #else
  327. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_CHARCODE |
  328. IME_CMODE_NATIVE | IME_CMODE_EUDC);
  329. #endif //EUDC
  330. uCaps = 1;
  331. } else {
  332. // change to native mode
  333. #ifdef EUDC
  334. fdwConversion = (lpIMC->fdwConversion |IME_CMODE_NATIVE);
  335. fdwConversion &= ~(IME_CMODE_CHARCODE | IME_CMODE_NOCONVERSION);
  336. #else
  337. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE);
  338. fdwConversion &= ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC | IME_CMODE_NOCONVERSION);
  339. #endif //EUDC
  340. uCaps = 0;
  341. }
  342. #endif //LATER
  343. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  344. fRet = FALSE;
  345. } else if((iRet == CST_ALPHANUMERIC)
  346. && !(lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)
  347. && (uVirtKey == VK_SPACE)) {
  348. fRet = FALSE;
  349. } else {
  350. fRet = TRUE;
  351. }
  352. ImmUnlockIMCC(lpIMC->hPrivate);
  353. ImmUnlockIMC(hIMC);
  354. return (fRet);
  355. }
  356. /**********************************************************************/
  357. /* TranslateSymbolChar() */
  358. /* Return Value: */
  359. /* the number of translated chars */
  360. /**********************************************************************/
  361. UINT PASCAL TranslateSymbolChar(
  362. LPTRANSMSGLIST lpTransBuf,
  363. WORD wSymbolCharCode,
  364. BOOL SymbolMode)
  365. {
  366. UINT uRet;
  367. LPTRANSMSG lpTransMsg;
  368. uRet = 0;
  369. lpTransMsg = lpTransBuf->TransMsg;
  370. // NT need to modify this!
  371. #ifdef UNICODE
  372. lpTransMsg->message = WM_CHAR;
  373. lpTransMsg->wParam = (DWORD)wSymbolCharCode;
  374. lpTransMsg->lParam = 1UL;
  375. lpTransMsg++;
  376. uRet++;
  377. #else
  378. lpTransMsg->message = WM_CHAR;
  379. lpTransMsg->wParam = (DWORD)HIBYTE(wSymbolCharCode);
  380. lpTransMsg->lParam = 1UL;
  381. lpTransMsg++;
  382. uRet++;
  383. lpTransMsg->message = WM_CHAR;
  384. lpTransMsg->wParam = (DWORD)LOBYTE(wSymbolCharCode);
  385. lpTransMsg->lParam = 1UL;
  386. lpTransMsg++;
  387. uRet++;
  388. #endif
  389. if(SymbolMode) {
  390. // lpTransMsg = lpTransBuf->TransMsg;
  391. #ifdef UNICODE
  392. lpTransMsg->message = WM_CHAR;
  393. lpTransMsg->wParam = (DWORD)wSymbolCharCode;
  394. lpTransMsg->lParam = 1UL;
  395. lpTransMsg++;
  396. uRet++;
  397. #else
  398. lpTransMsg->message = WM_CHAR;
  399. lpTransMsg->wParam = (DWORD)HIBYTE(wSymbolCharCode);
  400. lpTransMsg->lParam = 1UL;
  401. lpTransMsg++;
  402. uRet++;
  403. lpTransMsg->message = WM_CHAR;
  404. lpTransMsg->wParam = (DWORD)LOBYTE(wSymbolCharCode);
  405. lpTransMsg->lParam = 1UL;
  406. lpTransMsg++;
  407. uRet++;
  408. #endif
  409. }
  410. if(MBIndex.IMEChara[0].IC_INSSPC) {
  411. lpTransMsg = lpTransBuf->TransMsg;
  412. lpTransMsg->message = WM_CHAR;
  413. lpTransMsg->wParam = (DWORD)0x20;
  414. lpTransMsg->lParam = 1UL;
  415. lpTransMsg++;
  416. uRet++;
  417. }
  418. return (uRet); // generate two messages
  419. }
  420. /**********************************************************************/
  421. /* TranslateFullChar() */
  422. /* Return Value: */
  423. /* the number of translated chars */
  424. /**********************************************************************/
  425. UINT PASCAL TranslateFullChar(
  426. LPTRANSMSGLIST lpTransBuf,
  427. WORD wCharCode)
  428. {
  429. // if your IME is possible to generate over ? messages,
  430. // you need to take care about it
  431. LPTRANSMSG lpTransMsg;
  432. wCharCode = sImeG.wFullABC[wCharCode - TEXT(' ')];
  433. lpTransMsg = lpTransBuf->TransMsg;
  434. // NT need to modify this!
  435. #ifdef UNICODE
  436. lpTransMsg->message = WM_CHAR;
  437. lpTransMsg->wParam = (DWORD)wCharCode;
  438. lpTransMsg->lParam = 1UL;
  439. lpTransMsg++;
  440. #else
  441. lpTransMsg->message = WM_CHAR;
  442. lpTransMsg->wParam = (DWORD)HIBYTE(wCharCode);
  443. lpTransMsg->lParam = 1UL;
  444. lpTransMsg++;
  445. lpTransMsg->message = WM_CHAR;
  446. lpTransMsg->wParam = (DWORD)LOBYTE(wCharCode);
  447. lpTransMsg->lParam = 1UL;
  448. lpTransMsg++;
  449. #endif
  450. if(MBIndex.IMEChara[0].IC_INSSPC) {
  451. lpTransMsg = lpTransBuf->TransMsg;
  452. lpTransMsg->message = WM_CHAR;
  453. lpTransMsg->wParam = (DWORD)0x20;
  454. lpTransMsg->lParam = 1UL;
  455. lpTransMsg++;
  456. return (3); // generate two messages
  457. } else {
  458. return (2); // generate two messages
  459. }
  460. }
  461. /**********************************************************************/
  462. /* TranslateToAscii() */
  463. /* Return Value: */
  464. /* the number of translated chars */
  465. /**********************************************************************/
  466. UINT PASCAL TranslateToAscii( // translate the key to WM_CHAR
  467. // as keyboard driver
  468. UINT uVirtKey,
  469. UINT uScanCode,
  470. LPTRANSMSGLIST lpTransBuf,
  471. WORD wCharCode)
  472. {
  473. LPTRANSMSG lpTransMsg;
  474. lpTransMsg = lpTransBuf->TransMsg;
  475. if (wCharCode) { // one char code
  476. lpTransMsg->message = WM_CHAR;
  477. lpTransMsg->wParam = wCharCode;
  478. lpTransMsg->lParam = (uScanCode << 16) | 1UL;
  479. return (1);
  480. }
  481. // no char code case
  482. return (0);
  483. }
  484. /**********************************************************************/
  485. /* TranslateImeMessage() */
  486. /* Return Value: */
  487. /* the number of translated messages */
  488. /**********************************************************************/
  489. UINT PASCAL TranslateImeMessage(
  490. LPTRANSMSGLIST lpTransBuf,
  491. LPINPUTCONTEXT lpIMC,
  492. LPPRIVCONTEXT lpImcP)
  493. {
  494. UINT uNumMsg;
  495. UINT i;
  496. BOOL bLockMsgBuf;
  497. LPTRANSMSG lpTransMsg;
  498. uNumMsg = 0;
  499. bLockMsgBuf = FALSE;
  500. for (i = 0; i < 2; i++) {
  501. if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
  502. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  503. if (!i) {
  504. uNumMsg++;
  505. } else {
  506. lpTransMsg->message = WM_IME_NOTIFY;
  507. lpTransMsg->wParam = IMN_CLOSECANDIDATE;
  508. lpTransMsg->lParam = 0x0001;
  509. lpTransMsg++;
  510. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
  511. }
  512. }
  513. }
  514. if (lpImcP->fdwImeMsg & MSG_END_COMPOSITION) {
  515. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  516. if (!i) {
  517. uNumMsg++;
  518. } else {
  519. lpTransMsg->message = WM_IME_ENDCOMPOSITION;
  520. lpTransMsg->wParam = 0;
  521. lpTransMsg->lParam = 0;
  522. lpTransMsg++;
  523. lpImcP->fdwImeMsg &= ~(MSG_ALREADY_START);
  524. }
  525. }
  526. }
  527. if (lpImcP->fdwImeMsg & MSG_START_COMPOSITION) {
  528. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  529. if (!i) {
  530. uNumMsg++;
  531. } else {
  532. lpTransMsg->message = WM_IME_STARTCOMPOSITION;
  533. lpTransMsg->wParam = 0;
  534. lpTransMsg->lParam = 0;
  535. lpTransMsg++;
  536. lpImcP->fdwImeMsg |= MSG_ALREADY_START;
  537. }
  538. }
  539. }
  540. if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONPOS) {
  541. if (!i) {
  542. uNumMsg++;
  543. } else {
  544. lpTransMsg->message = WM_IME_NOTIFY;
  545. lpTransMsg->wParam = IMN_SETCOMPOSITIONWINDOW;
  546. lpTransMsg->lParam = 0;
  547. lpTransMsg++;
  548. }
  549. }
  550. if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
  551. if (!i) {
  552. uNumMsg++;
  553. } else {
  554. lpTransMsg->message = WM_IME_COMPOSITION;
  555. lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
  556. lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
  557. lpTransMsg++;
  558. }
  559. }
  560. if (lpImcP->fdwImeMsg & MSG_GUIDELINE) {
  561. if (!i) {
  562. uNumMsg++;
  563. } else {
  564. lpTransMsg->message = WM_IME_NOTIFY;
  565. lpTransMsg->wParam = IMN_GUIDELINE;
  566. lpTransMsg->lParam = 0;
  567. lpTransMsg++;
  568. }
  569. }
  570. if (lpImcP->fdwImeMsg & MSG_OPEN_CANDIDATE) {
  571. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)
  572. || (lpImcP->PrivateArea.Comp_Status.dwSTMULCODE)
  573. || (lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  574. if (!i) {
  575. uNumMsg++;
  576. } else {
  577. lpTransMsg->message = WM_IME_NOTIFY;
  578. lpTransMsg->wParam = IMN_OPENCANDIDATE;
  579. lpTransMsg->lParam = 0x0001;
  580. lpTransMsg++;
  581. lpImcP->fdwImeMsg |= MSG_ALREADY_OPEN;
  582. }
  583. }
  584. }
  585. if (lpImcP->fdwImeMsg & MSG_CHANGE_CANDIDATE) {
  586. if (!i) {
  587. uNumMsg++;
  588. } else {
  589. lpTransMsg->message = WM_IME_NOTIFY;
  590. lpTransMsg->wParam = IMN_CHANGECANDIDATE;
  591. lpTransMsg->lParam = 0x0001;
  592. lpTransMsg++;
  593. }
  594. }
  595. if (lpImcP->fdwImeMsg & MSG_IMN_UPDATE_SOFTKBD) {
  596. if (!i) {
  597. uNumMsg++;
  598. } else {
  599. lpTransMsg->message = WM_IME_NOTIFY;
  600. lpTransMsg->wParam = IMN_PRIVATE;
  601. lpTransMsg->lParam = IMN_PRIVATE_UPDATE_SOFTKBD;
  602. lpTransMsg++;
  603. }
  604. }
  605. if (lpImcP->fdwImeMsg & MSG_IMN_UPDATE_STATUS) {
  606. if (!i) {
  607. uNumMsg++;
  608. } else {
  609. lpTransMsg->message = WM_IME_NOTIFY;
  610. lpTransMsg->wParam = IMN_PRIVATE;
  611. lpTransMsg->lParam = IMN_PRIVATE_UPDATE_STATUS;
  612. lpTransMsg++;
  613. }
  614. }
  615. if (lpImcP->fdwImeMsg & MSG_IMN_DESTROYCAND) {
  616. if (!i) {
  617. uNumMsg++;
  618. } else {
  619. lpTransMsg->message = WM_IME_NOTIFY;
  620. lpTransMsg->wParam = IMN_PRIVATE;
  621. lpTransMsg->lParam = IMN_PRIVATE_DESTROYCANDWIN;
  622. lpTransMsg++;
  623. }
  624. }
  625. if (lpImcP->fdwImeMsg & MSG_BACKSPACE) {
  626. if (!i) {
  627. uNumMsg++;
  628. } else {
  629. lpTransMsg->message = WM_CHAR;
  630. lpTransMsg->wParam = TEXT('\b');
  631. lpTransMsg->lParam = 0x000e;
  632. lpTransMsg++;
  633. }
  634. }
  635. if (!i) {
  636. HIMCC hMem;
  637. if (!uNumMsg) {
  638. return (uNumMsg);
  639. }
  640. if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
  641. UINT uNumMsgLimit;
  642. uNumMsgLimit = lpTransBuf->uMsgCount;
  643. if (uNumMsg <= uNumMsgLimit) {
  644. lpTransMsg = lpTransBuf->TransMsg;
  645. continue;
  646. }
  647. }
  648. // we need to use message buffer
  649. if (!lpIMC->hMsgBuf) {
  650. lpIMC->hMsgBuf = ImmCreateIMCC(uNumMsg * sizeof(TRANSMSG));
  651. lpIMC->dwNumMsgBuf = 0;
  652. } else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf,
  653. (lpIMC->dwNumMsgBuf + uNumMsg) * sizeof(TRANSMSG))) {
  654. if (hMem != lpIMC->hMsgBuf) {
  655. ImmDestroyIMCC(lpIMC->hMsgBuf);
  656. lpIMC->hMsgBuf = hMem;
  657. }
  658. } else {
  659. return (0);
  660. }
  661. lpTransMsg= (LPTRANSMSG) ImmLockIMCC(lpIMC->hMsgBuf);
  662. if (!lpTransMsg) {
  663. return (0);
  664. }
  665. lpTransMsg += lpIMC->dwNumMsgBuf;
  666. bLockMsgBuf = TRUE;
  667. } else {
  668. if (bLockMsgBuf) {
  669. ImmUnlockIMCC(lpIMC->hMsgBuf);
  670. }
  671. }
  672. }
  673. return (uNumMsg);
  674. }
  675. /**********************************************************************/
  676. /* ImeToAsciiEx() */
  677. /* Return Value: */
  678. /* the number of translated message */
  679. /**********************************************************************/
  680. UINT WINAPI ImeToAsciiEx(
  681. UINT uVirtKey,
  682. UINT uScanCode,
  683. CONST LPBYTE lpbKeyState,
  684. LPTRANSMSGLIST lpTransBuf,
  685. UINT fuState,
  686. HIMC hIMC)
  687. {
  688. WORD wCharCode;
  689. LPINPUTCONTEXT lpIMC;
  690. LPCOMPOSITIONSTRING lpCompStr;
  691. LPPRIVCONTEXT lpImcP;
  692. UINT uNumMsg;
  693. int iRet;
  694. #ifdef UNICODE
  695. wCharCode = HIWORD(uVirtKey);
  696. #else
  697. wCharCode = HIBYTE(uVirtKey);
  698. #endif
  699. uVirtKey = LOBYTE(uVirtKey);
  700. // hIMC=NULL?
  701. if (!hIMC) {
  702. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  703. wCharCode);
  704. return (uNumMsg);
  705. }
  706. // get lpIMC
  707. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  708. if (!lpIMC) {
  709. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  710. wCharCode);
  711. return (uNumMsg);
  712. }
  713. // get lpImcP
  714. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  715. if (!lpImcP) {
  716. ImmUnlockIMC(hIMC);
  717. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  718. wCharCode);
  719. return (uNumMsg);
  720. }
  721. // get lpCompStr and init
  722. if (lpImcP->fdwGcsFlag & (GCS_RESULTREAD|GCS_RESULT)) {
  723. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  724. if (lpCompStr) {
  725. lpCompStr->dwResultStrLen = 0;
  726. }
  727. ImmUnlockIMCC(lpIMC->hCompStr);
  728. lpImcP->fdwGcsFlag = (DWORD) 0;
  729. }
  730. // Now all composition realated information already pass to app
  731. // a brand new start
  732. // init lpImcP->fdwImeMsg
  733. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|
  734. MSG_ALREADY_START) | MSG_IN_IMETOASCIIEX;
  735. // Process Key(wCharCode)
  736. iRet = ProcessKey(wCharCode, uVirtKey, uScanCode, lpbKeyState, lpIMC,
  737. lpImcP);
  738. // iRet process
  739. // CST_ONLINE_CZ
  740. if (iRet == CST_ONLINE_CZ) {
  741. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_IMN_UPDATE_STATUS) & ~(MSG_IN_IMETOASCIIEX);
  742. if(wCharCode == VK_ESCAPE) {
  743. CWCodeStr[0] = 0;
  744. CWDBCSStr[0] = 0;
  745. lpImcP->PrivateArea.Comp_Status.OnLineCreWord = 0;
  746. } else {
  747. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  748. if (!lpCompStr) {
  749. return 0;
  750. }
  751. Finalize(lpIMC, lpCompStr, lpImcP, 0x1b); // compsition
  752. ClearCand(lpIMC);
  753. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  754. ~(MSG_OPEN_CANDIDATE);
  755. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
  756. ~(MSG_START_COMPOSITION);
  757. InitCompStr(lpCompStr);
  758. lpImcP->PrivateArea.Comp_Status.OnLineCreWord ^= 1;
  759. lpImcP->iImeState = CST_INIT;
  760. // init fields of hPrivate
  761. lpImcP->dwCompChar = (DWORD) 0;
  762. lpImcP->PrivateArea.Comp_Status.dwSTLX = 0;
  763. lpImcP->PrivateArea.Comp_Status.dwSTMULCODE = 0;
  764. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  765. // online create word
  766. if((!lpImcP->PrivateArea.Comp_Status.OnLineCreWord)
  767. && (lstrlen(CWDBCSStr))) {
  768. TCHAR MBName[MAXSTRLEN];
  769. TCHAR Buf[LINE_LEN];
  770. lstrcpy(MBName, sImeG.szIMESystemPath);
  771. lstrcat((LPTSTR)MBName, TEXT("\\"));
  772. lstrcat((LPTSTR)MBName, (LPCTSTR)lpImcP->MB_Name);
  773. ConvCreateWord( lpIMC->hWnd,
  774. (LPCTSTR)MBName,
  775. (LPTSTR)CWDBCSStr,
  776. (LPTSTR)CWCodeStr);
  777. // In current GBK and Unicode Encoding, one Chinese character
  778. // has two bytes as its internal code.
  779. if(lstrlen(CWDBCSStr) <= (sizeof(WORD) / sizeof(TCHAR))) {
  780. InfoMessage(NULL, IDS_WARN_MEMPRASE);
  781. CWCodeStr[0] = 0;
  782. CWDBCSStr[0] = 0;
  783. } else if(lstrlen(CWDBCSStr) && lstrlen(CWCodeStr)) {
  784. int iAddRet;
  785. TCHAR czCZ_Confirm_Title[20];
  786. LoadString(hInst, IDS_CZ_CONFIRM, Buf, sizeof(Buf)/sizeof(TCHAR) );
  787. LoadString(hInst, IDS_CZ_CONFIRM_TITLE, czCZ_Confirm_Title,
  788. sizeof(czCZ_Confirm_Title) / sizeof(TCHAR) );
  789. lstrcat(Buf, TEXT("\n\n") );
  790. lstrcat(Buf, CWDBCSStr);
  791. lstrcat(Buf, TEXT(" ") );
  792. lstrcat(Buf, CWCodeStr);
  793. if ( MessageBox(lpIMC->hWnd, Buf,czCZ_Confirm_Title,
  794. MB_YESNO | MB_ICONINFORMATION) == IDYES) {
  795. iAddRet = AddZCItem(lpIMC->hPrivate, CWCodeStr, CWDBCSStr);
  796. if (iAddRet == ADD_FALSE) {
  797. InfoMessage(NULL, IDS_WARN_MEMPRASE);
  798. } else if (iAddRet == ADD_REP) {
  799. InfoMessage(NULL, IDS_WARN_DUPPRASE);
  800. } else if (iAddRet == ADD_FULL) {
  801. InfoMessage(NULL, IDS_WARN_OVEREMB);
  802. }
  803. } else {
  804. CWCodeStr[0] = 0;
  805. CWDBCSStr[0] = 0;
  806. }
  807. } else {
  808. CWCodeStr[0] = 0;
  809. CWDBCSStr[0] = 0;
  810. }
  811. } else {
  812. CWCodeStr[0] = 0;
  813. CWDBCSStr[0] = 0;
  814. }
  815. ImmUnlockIMCC(lpIMC->hCompStr);
  816. }
  817. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg | MSG_IMN_UPDATE_STATUS;
  818. GenerateMessage(hIMC, lpIMC, lpImcP);
  819. uNumMsg = 0;
  820. }
  821. // CST_SOFTKB
  822. if (iRet == CST_SOFTKB) {
  823. WORD wSymbolCharCode;
  824. WORD CHIByte, CLOByte;
  825. int SKDataIndex;
  826. // Mapping VK
  827. if(uVirtKey == 0x20) {
  828. SKDataIndex = 0;
  829. } else if(uVirtKey >= 0x30 && uVirtKey <= 0x39) {
  830. SKDataIndex = uVirtKey - 0x30 + 1;
  831. } else if (uVirtKey >= 0x41 && uVirtKey <= 0x5a) {
  832. SKDataIndex = uVirtKey - 0x41 + 0x0b;
  833. } else if (uVirtKey >= 0xba && uVirtKey <= 0xbf) {
  834. SKDataIndex = uVirtKey - 0xba + 0x25;
  835. } else if (uVirtKey >= 0xdb && uVirtKey <= 0xde) {
  836. SKDataIndex = uVirtKey - 0xdb + 0x2c;
  837. } else if (uVirtKey == 0xc0) {
  838. SKDataIndex = 0x2b;
  839. } else {
  840. SKDataIndex = 0;
  841. }
  842. #ifdef UNICODE //
  843. if (lpbKeyState[VK_SHIFT] & 0x80) {
  844. wSymbolCharCode = SKLayoutS[lpImeL->dwSKWant][SKDataIndex];
  845. } else {
  846. wSymbolCharCode = SKLayout[lpImeL->dwSKWant][SKDataIndex];
  847. }
  848. if(wSymbolCharCode == 0x0020) {
  849. #else
  850. if (lpbKeyState[VK_SHIFT] & 0x80) {
  851. CHIByte = SKLayoutS[lpImeL->dwSKWant][SKDataIndex*2] & 0x00ff;
  852. CLOByte = SKLayoutS[lpImeL->dwSKWant][SKDataIndex*2 + 1] & 0x00ff;
  853. } else {
  854. CHIByte = SKLayout[lpImeL->dwSKWant][SKDataIndex*2] & 0x00ff;
  855. CLOByte = SKLayout[lpImeL->dwSKWant][SKDataIndex*2 + 1] & 0x00ff;
  856. }
  857. wSymbolCharCode = (CHIByte << 8) | CLOByte;
  858. if(wSymbolCharCode == 0x2020) {
  859. #endif //UNICODE
  860. MessageBeep((UINT) -1);
  861. uNumMsg = 0;
  862. } else {
  863. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  864. }
  865. }
  866. // CST_ALPHANUMERIC
  867. else if (iRet == CST_ALPHANUMERIC) {
  868. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  869. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  870. ~(MSG_OPEN_CANDIDATE) & ~(MSG_IN_IMETOASCIIEX);
  871. GenerateMessage(hIMC, lpIMC, lpImcP);
  872. // init lpImcP
  873. lpImcP->PrivateArea.Comp_Context.szInBuffer[0] = 0;
  874. lpImcP->PrivateArea.Comp_Context.PromptCnt = 0;
  875. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  876. lpImcP->PrivateArea.Comp_Status.dwSTLX = 0;
  877. lpImcP->PrivateArea.Comp_Status.dwSTMULCODE = 0;
  878. }
  879. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  880. WORD wSymbolCharCode;
  881. if(wCharCode == TEXT('.')) {
  882. #ifdef UNICODE
  883. wSymbolCharCode = 0x3002;
  884. #else
  885. wSymbolCharCode = TEXT('');
  886. #endif
  887. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  888. } else if(wCharCode == TEXT(',')) {
  889. #ifdef UNICODE
  890. wSymbolCharCode = 0xff0c;
  891. #else
  892. wSymbolCharCode = TEXT('');
  893. #endif
  894. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  895. } else if(wCharCode == TEXT(';')) {
  896. #ifdef UNICODE
  897. wSymbolCharCode = 0xff1b;
  898. #else
  899. wSymbolCharCode = TEXT('');
  900. #endif
  901. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  902. } else if(wCharCode == TEXT(':')) {
  903. #ifdef UNICODE
  904. wSymbolCharCode = 0xff1a;
  905. #else
  906. wSymbolCharCode = TEXT('');
  907. #endif
  908. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  909. } else if(wCharCode == TEXT('?')) {
  910. #ifdef UNICODE
  911. wSymbolCharCode = 0xff1f;
  912. #else
  913. wSymbolCharCode = TEXT('');
  914. #endif
  915. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  916. } else if(wCharCode == TEXT('!')) {
  917. #ifdef UNICODE
  918. wSymbolCharCode = 0xff01;
  919. #else
  920. wSymbolCharCode = TEXT('');
  921. #endif
  922. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  923. } else if(wCharCode == TEXT('(')) {
  924. #ifdef UNICODE
  925. wSymbolCharCode = 0xff08;
  926. #else
  927. wSymbolCharCode = TEXT('');
  928. #endif
  929. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  930. } else if(wCharCode == TEXT(')')) {
  931. #ifdef UNICODE
  932. wSymbolCharCode = 0xff09;
  933. #else
  934. wSymbolCharCode = TEXT('');
  935. #endif
  936. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  937. } else if(wCharCode == TEXT('\\')) {
  938. #ifdef UNICODE
  939. wSymbolCharCode = 0x3001;
  940. #else
  941. wSymbolCharCode = TEXT('');
  942. #endif
  943. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  944. } else if(wCharCode == TEXT('@')) {
  945. #ifdef UNICODE
  946. wSymbolCharCode = 0x00b7;
  947. #else
  948. wSymbolCharCode = TEXT('');
  949. #endif
  950. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  951. } else if(wCharCode == TEXT('&')) {
  952. #ifdef UNICODE
  953. wSymbolCharCode = 0x2014;
  954. #else
  955. wSymbolCharCode = TEXT('');
  956. #endif
  957. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  958. } else if(wCharCode == TEXT('$')) {
  959. #ifdef UNICODE
  960. wSymbolCharCode = 0xffe5;
  961. #else
  962. wSymbolCharCode = TEXT('');
  963. #endif
  964. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  965. } else if(wCharCode == TEXT('_')) {
  966. #ifdef UNICODE
  967. wSymbolCharCode = 0x2014;
  968. #else
  969. wSymbolCharCode = TEXT('');
  970. #endif
  971. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, 1);
  972. } else if(wCharCode == TEXT('^')) {
  973. #ifdef UNICODE
  974. wSymbolCharCode = 0x2026;
  975. #else
  976. wSymbolCharCode = TEXT('');
  977. #endif
  978. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, 1);
  979. } else if(wCharCode == TEXT('"')) {
  980. if(lpImcP->uSYHFlg) {
  981. #ifdef UNICODE
  982. wSymbolCharCode = 0x201d;
  983. } else {
  984. wSymbolCharCode = 0x201c;
  985. #else
  986. wSymbolCharCode = TEXT('');
  987. } else {
  988. wSymbolCharCode = TEXT('');
  989. #endif
  990. }
  991. lpImcP->uSYHFlg ^= 0x00000001;
  992. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  993. } else if(wCharCode == TEXT('\'')) {
  994. if(lpImcP->uDYHFlg) {
  995. #ifdef UNICODE
  996. wSymbolCharCode = 0x2019;
  997. } else {
  998. wSymbolCharCode = 0x2018;
  999. #else
  1000. wSymbolCharCode = TEXT('');
  1001. } else {
  1002. wSymbolCharCode = TEXT('');
  1003. #endif
  1004. }
  1005. lpImcP->uDYHFlg ^= 0x00000001;
  1006. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  1007. } else if(wCharCode == TEXT('<')) {
  1008. if(lpImcP->uDSMHFlg) {
  1009. #ifdef UNICODE
  1010. wSymbolCharCode = 0x3008;
  1011. #else
  1012. wSymbolCharCode = TEXT('');
  1013. #endif
  1014. lpImcP->uDSMHCount++;
  1015. } else {
  1016. #ifdef UNICODE
  1017. wSymbolCharCode = 0x300a;
  1018. #else
  1019. wSymbolCharCode = TEXT('');
  1020. #endif
  1021. lpImcP->uDSMHFlg = 0x00000001;
  1022. }
  1023. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  1024. } else if(wCharCode == TEXT('>')) {
  1025. if((lpImcP->uDSMHFlg) && (lpImcP->uDSMHCount)) {
  1026. #ifdef UNICODE
  1027. wSymbolCharCode = 0x3009;
  1028. #else
  1029. wSymbolCharCode = TEXT('');
  1030. #endif
  1031. lpImcP->uDSMHCount--;
  1032. } else {
  1033. #ifdef UNICODE
  1034. wSymbolCharCode = 0x300b;
  1035. #else
  1036. wSymbolCharCode = TEXT('');
  1037. #endif
  1038. lpImcP->uDSMHFlg = 0x00000000;
  1039. }
  1040. uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode, FALSE);
  1041. } else {
  1042. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
  1043. // convert to DBCS
  1044. uNumMsg = TranslateFullChar(lpTransBuf, wCharCode);
  1045. } else {
  1046. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1047. wCharCode);
  1048. }
  1049. }
  1050. } else if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
  1051. // convert to DBCS
  1052. uNumMsg = TranslateFullChar(lpTransBuf, wCharCode);
  1053. } else {
  1054. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1055. wCharCode);
  1056. }
  1057. }
  1058. // CST_CHOOSE
  1059. else if (iRet == CST_CHOOSE) {
  1060. LPCANDIDATEINFO lpCandInfo;
  1061. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  1062. if(!lpCandInfo){
  1063. ImmUnlockIMC(hIMC);
  1064. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1065. wCharCode);
  1066. return (uNumMsg);
  1067. }
  1068. if (uVirtKey == VK_PRIOR) {
  1069. wCharCode = VK_PRIOR;
  1070. } else if (uVirtKey == VK_NEXT) {
  1071. wCharCode = VK_NEXT;
  1072. } else if (uVirtKey == TEXT(' ')) {
  1073. // convert space to '1'
  1074. wCharCode = '1';
  1075. } else if (uVirtKey >= TEXT('0') && uVirtKey <= TEXT('9')) {
  1076. // convert shift-0 ... shift-9 to 0 ... 9
  1077. wCharCode = (WORD) uVirtKey;
  1078. } else if (uVirtKey == VK_HOME) {
  1079. wCharCode = VK_HOME;
  1080. } else if (uVirtKey == VK_END) {
  1081. wCharCode = VK_END;
  1082. } else if (wCharCode == TEXT('-')) {
  1083. wCharCode = VK_PRIOR;
  1084. } else if (wCharCode == TEXT('=')) {
  1085. wCharCode = VK_NEXT;
  1086. } else {
  1087. }
  1088. lpImcP->iImeState = CST_CHOOSE;
  1089. Finalize(lpIMC, lpCompStr, lpImcP, wCharCode); // compsition
  1090. ChooseCand(wCharCode, lpIMC, lpCandInfo, lpImcP);
  1091. ImmUnlockIMCC(lpIMC->hCandInfo);
  1092. uNumMsg = TranslateImeMessage(lpTransBuf, lpIMC, lpImcP);
  1093. }
  1094. // CST_INPUT(IME_CMODE_CHARCODE)
  1095. else if (iRet == CST_INPUT &&
  1096. lpIMC->fdwConversion & IME_CMODE_CHARCODE) {
  1097. lpImcP->iImeState = CST_INPUT;
  1098. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1099. wCharCode);
  1100. }
  1101. // CST_INPUT
  1102. else if (iRet == CST_INPUT) {
  1103. LPGUIDELINE lpGuideLine;
  1104. // get lpCompStr & lpGuideLine
  1105. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  1106. if(!lpCompStr){
  1107. ImmUnlockIMC(hIMC);
  1108. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1109. wCharCode);
  1110. return (uNumMsg);
  1111. }
  1112. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  1113. if(!lpGuideLine){
  1114. ImmUnlockIMC(hIMC);
  1115. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1116. wCharCode);
  1117. return (uNumMsg);
  1118. }
  1119. // composition
  1120. CompWord(wCharCode, lpIMC, lpCompStr, lpImcP, lpGuideLine);
  1121. ImmUnlockIMCC(lpIMC->hGuideLine);
  1122. ImmUnlockIMCC(lpIMC->hCompStr);
  1123. // generate message
  1124. uNumMsg = TranslateImeMessage(lpTransBuf, lpIMC, lpImcP);
  1125. }
  1126. // ELSE
  1127. else if (iRet == CST_INVALID_INPUT) {
  1128. //MessageBeep((UINT) -1);
  1129. uNumMsg = 0;
  1130. }else {
  1131. uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
  1132. wCharCode);
  1133. }
  1134. // reset lpImcP->fdwImeMsg
  1135. lpImcP->fdwImeMsg &= (MSG_ALREADY_OPEN|MSG_ALREADY_START);
  1136. lpImcP->fdwGcsFlag &= (GCS_RESULTREAD|GCS_RESULT);
  1137. ImmUnlockIMCC(lpIMC->hPrivate);
  1138. ImmUnlockIMC(hIMC);
  1139. return (uNumMsg);
  1140. }