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.

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