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.

670 lines
24 KiB

  1. /*++
  2. Copyright (c) 1995-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. COMPOSE.C
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include <imedefs.h>
  9. void PASCAL EngChCand(
  10. LPCOMPOSITIONSTRING lpCompStr,
  11. LPCANDIDATELIST lpCandList,
  12. LPPRIVCONTEXT lpImcP,
  13. LPINPUTCONTEXT lpIMC,
  14. WORD wCharCode)
  15. {
  16. int i;
  17. if (MBIndex.IMEChara[0].IC_Trace) {
  18. MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 0, BOX_UI);
  19. } else {
  20. MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 0, LIN_UI);
  21. }
  22. //
  23. if((lpCandList->dwCount =
  24. (DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Cnt)
  25. == 0) {
  26. } else {
  27. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),
  28. (LPTSTR)lpImcP->PrivateArea.Comp_Context.szSelectBuffer);
  29. for (i=1;i<lpImcP->PrivateArea.Comp_Context.Candi_Cnt;i++) {
  30. lpCandList->dwOffset[i] = lpCandList->dwOffset[0]
  31. +(DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Pos[(i+1)%10]*sizeof(TCHAR) ;
  32. *((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[i])-1) = TEXT('\0');
  33. }
  34. }
  35. return;
  36. }
  37. /**********************************************************************/
  38. /* Engine() */
  39. /* Description: */
  40. /* search MB and fill lpCompStr and lpCandList */
  41. /**********************************************************************/
  42. UINT PASCAL Engine(
  43. LPCOMPOSITIONSTRING lpCompStr,
  44. LPCANDIDATELIST lpCandList,
  45. LPPRIVCONTEXT lpImcP,
  46. LPINPUTCONTEXT lpIMC,
  47. WORD wCharCode)
  48. {
  49. int i;
  50. if(wCharCode == VK_ESCAPE) {
  51. lpCandList->dwCount = 0;
  52. if (MBIndex.IMEChara[0].IC_Trace) {
  53. MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 0, BOX_UI);
  54. } else {
  55. MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 0, LIN_UI);
  56. }
  57. return (ENGINE_ESC);
  58. } else if(wCharCode == TEXT('\b')) {
  59. EngChCand(lpCompStr, lpCandList, lpImcP, lpIMC, wCharCode);
  60. return (ENGINE_BKSPC);
  61. } else if((wCharCode == 0x21) || (wCharCode == 0x22)
  62. || (wCharCode == 0x23) || (wCharCode == 0x24)) {
  63. EngChCand(lpCompStr, lpCandList, lpImcP, lpIMC, wCharCode);
  64. return (ENGINE_CHCAND);
  65. } else if ((wCharCode >= TEXT('0') && wCharCode <= TEXT('9')) &&
  66. (lpImcP->iImeState == CST_CHOOSE)) {
  67. lpCandList->dwCount = lpImcP->PrivateArea.Comp_Context.Candi_Cnt;
  68. lpImcP->dwOldCandCnt = lpCandList->dwCount;
  69. if (MBIndex.IMEChara[0].IC_Trace) {
  70. MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 1, BOX_UI);
  71. } else {
  72. MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 1, LIN_UI);
  73. }
  74. // if LX on, set cand
  75. if(!(MBIndex.IMEChara[0].IC_LX)
  76. ||!(lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  77. } else {
  78. lpCandList->dwCount =
  79. (DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Cnt;
  80. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),
  81. (LPTSTR)lpImcP->PrivateArea.Comp_Context.szSelectBuffer);
  82. for (i=1;i<lpImcP->PrivateArea.Comp_Context.Candi_Cnt;i++) {
  83. lpCandList->dwOffset[i] = lpCandList->dwOffset[0]
  84. +(DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Pos[(i+1)%10]*sizeof(TCHAR);
  85. *((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[i])-1) = TEXT('\0');
  86. }
  87. }
  88. return (ENGINE_MULTISEL);
  89. } else {
  90. UINT MB_SUB_RET;
  91. if(IsUsedCode(wCharCode, lpImcP)
  92. || (wCharCode == MBIndex.MBDesc[0].cWildChar)
  93. || (wCharCode == TEXT(' ')))
  94. {
  95. if((wCharCode != TEXT(' ')) && (wCharCode != TEXT('?'))
  96. && (lpImcP->PrivateArea.Comp_Status.dwSTMULCODE)) {
  97. if (MBIndex.IMEChara[0].IC_Trace) {
  98. MB_SUB(lpIMC->hPrivate, 0x20, 0, BOX_UI);
  99. } else {
  100. MB_SUB(lpIMC->hPrivate, 0x20, 0, LIN_UI);
  101. }
  102. // online create word
  103. if(lpImcP->PrivateArea.Comp_Status.OnLineCreWord) {
  104. UINT i, j;
  105. for(i=lstrlen(CWDBCSStr), j=0; i<MAXINPUTWORD; i++, j++) {
  106. CWDBCSStr[i] = lpImcP->PrivateArea.Comp_Context.CKBBuf[j];
  107. }
  108. }
  109. if(MBIndex.IMEChara[0].IC_INSSPC) {
  110. int i,j, ilen;
  111. ilen = lstrlen(lpImcP->PrivateArea.Comp_Context.CKBBuf);
  112. lpImcP->PrivateArea.Comp_Context.CKBBuf[ilen + ilen/2] = 0;
  113. for(i = ilen, j=3*ilen/2; i>2; i-=2, j-=3) {
  114. lpImcP->PrivateArea.Comp_Context.CKBBuf[j-1] = 0x20;
  115. lpImcP->PrivateArea.Comp_Context.CKBBuf[j-2] =
  116. lpImcP->PrivateArea.Comp_Context.CKBBuf[i-1];
  117. lpImcP->PrivateArea.Comp_Context.CKBBuf[j-3] =
  118. lpImcP->PrivateArea.Comp_Context.CKBBuf[i-2];
  119. }
  120. lpImcP->PrivateArea.Comp_Context.CKBBuf[i] = 0x20;
  121. } else {
  122. }
  123. lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),
  124. lpImcP->PrivateArea.Comp_Context.CKBBuf);
  125. // calculate result string length
  126. lpCompStr->dwResultStrLen =
  127. lstrlen(lpImcP->PrivateArea.Comp_Context.CKBBuf);
  128. lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  129. GCS_DELTASTART|GCS_RESULTREAD|GCS_RESULT;
  130. #ifdef CROSSREF
  131. CrossReverseConv(lpIMC, lpCompStr, lpImcP, lpCandList);
  132. #endif
  133. }
  134. if (MBIndex.IMEChara[0].IC_Trace) {
  135. MB_SUB_RET = MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 0, BOX_UI);
  136. } else {
  137. MB_SUB_RET = MB_SUB(lpIMC->hPrivate, (TCHAR)wCharCode, 0, LIN_UI);
  138. }
  139. switch (MB_SUB_RET)
  140. {
  141. case (ENGINE_COMP): //Engine is composeing
  142. if((lpCandList->dwCount =
  143. (DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Cnt)
  144. == 0) {
  145. } else {
  146. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),
  147. (LPTSTR)lpImcP->PrivateArea.Comp_Context.szSelectBuffer);
  148. for (i=1;i<lpImcP->PrivateArea.Comp_Context.Candi_Cnt;i++) {
  149. lpCandList->dwOffset[i] = lpCandList->dwOffset[0]
  150. +(DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Pos[(i+1)%10]*sizeof(TCHAR);
  151. *((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[i])-1) = TEXT('\0');
  152. }
  153. }
  154. return (ENGINE_COMP);
  155. case (ENGINE_ASCII): //Can't compose
  156. return ENGINE_ASCII;
  157. case (ENGINE_RESAULT): //Composition complete and Result string available
  158. InitCompStr(lpCompStr);
  159. // online create word
  160. if(lpImcP->PrivateArea.Comp_Status.OnLineCreWord) {
  161. UINT i, j;
  162. for(i=lstrlen(CWDBCSStr), j=0; i<MAXINPUTWORD; i++, j++) {
  163. CWDBCSStr[i] = lpImcP->PrivateArea.Comp_Context.CKBBuf[j];
  164. }
  165. }
  166. if(MBIndex.IMEChara[0].IC_INSSPC) {
  167. int i,j, ilen;
  168. ilen = lstrlen(lpImcP->PrivateArea.Comp_Context.CKBBuf);
  169. lpImcP->PrivateArea.Comp_Context.CKBBuf[ilen + ilen/2] = 0;
  170. for(i = ilen, j=3*ilen/2; i>2; i-=2, j-=3) {
  171. lpImcP->PrivateArea.Comp_Context.CKBBuf[j-1] = 0x20;
  172. lpImcP->PrivateArea.Comp_Context.CKBBuf[j-2] =
  173. lpImcP->PrivateArea.Comp_Context.CKBBuf[i-1];
  174. lpImcP->PrivateArea.Comp_Context.CKBBuf[j-3] =
  175. lpImcP->PrivateArea.Comp_Context.CKBBuf[i-2];
  176. }
  177. lpImcP->PrivateArea.Comp_Context.CKBBuf[i] = 0x20;
  178. } else {
  179. }
  180. lstrcpy((LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),
  181. lpImcP->PrivateArea.Comp_Context.CKBBuf);
  182. // calculate result string length
  183. lpCompStr->dwResultStrLen =
  184. lstrlen(lpImcP->PrivateArea.Comp_Context.CKBBuf);
  185. #ifdef CROSSREF
  186. CrossReverseConv(lpIMC, lpCompStr, lpImcP, lpCandList);
  187. #endif
  188. // if LX on, set cand
  189. if(!(MBIndex.IMEChara[0].IC_LX)
  190. ||!(lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  191. } else {
  192. lpCandList->dwCount =
  193. (DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Cnt;
  194. lstrcpy((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[0]),
  195. (LPTSTR)lpImcP->PrivateArea.Comp_Context.szSelectBuffer);
  196. for (i=1;i<lpImcP->PrivateArea.Comp_Context.Candi_Cnt;i++) {
  197. lpCandList->dwOffset[i] = lpCandList->dwOffset[0]
  198. +(DWORD)lpImcP->PrivateArea.Comp_Context.Candi_Pos[(i+1)%10]*sizeof(TCHAR);
  199. *((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[i])-1) = TEXT('\0');
  200. }
  201. }
  202. return (ENGINE_RESAULT);
  203. default:
  204. return (ENGINE_COMP);
  205. }
  206. } else {
  207. return (ENGINE_COMP);
  208. }
  209. }
  210. }
  211. /**********************************************************************/
  212. /* CompEscapeKey() */
  213. /**********************************************************************/
  214. void PASCAL CompEscapeKey(
  215. LPINPUTCONTEXT lpIMC,
  216. LPCOMPOSITIONSTRING lpCompStr,
  217. LPGUIDELINE lpGuideLine,
  218. LPPRIVCONTEXT lpImcP)
  219. {
  220. // add temp
  221. lpImcP->PrivateArea.Comp_Context.szInBuffer[0] = 0;
  222. lpImcP->PrivateArea.Comp_Context.PromptCnt = 0;
  223. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  224. if (!lpGuideLine) {
  225. MessageBeep((UINT)-1);
  226. } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
  227. } else {
  228. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  229. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  230. lpGuideLine->dwStrLen = 0;
  231. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  232. }
  233. if (lpImcP->iImeState == CST_CHOOSE) {
  234. Finalize(lpIMC, lpCompStr, lpImcP, VK_ESCAPE);
  235. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  236. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
  237. ~(MSG_START_COMPOSITION);
  238. }
  239. lpImcP->iImeState = CST_INIT;
  240. if (lpCompStr) {
  241. InitCompStr(lpCompStr);
  242. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  243. lpImcP->dwCompChar = VK_ESCAPE;
  244. lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  245. GCS_DELTASTART);
  246. }
  247. return;
  248. }
  249. /**********************************************************************/
  250. /* CompBackSpaceKey() */
  251. /**********************************************************************/
  252. void PASCAL CompBackSpaceKey(
  253. LPINPUTCONTEXT lpIMC,
  254. LPCOMPOSITIONSTRING lpCompStr,
  255. LPPRIVCONTEXT lpImcP)
  256. {
  257. if (lpCompStr->dwCursorPos < sizeof(BYTE)) {
  258. lpCompStr->dwCursorPos = sizeof(BYTE);
  259. }
  260. // go back a compsoition char
  261. lpCompStr->dwCursorPos -= sizeof(BYTE);
  262. // clean the sequence code
  263. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  264. lpImcP->dwCompChar = TEXT('\b');
  265. lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  266. GCS_DELTASTART);
  267. if (!lpCompStr->dwCursorPos) {
  268. if ((lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN))
  269. || (lpImcP->PrivateArea.Comp_Status.dwInvalid)
  270. || (lpImcP->iImeState != CST_INIT)) {
  271. lpImcP->iImeState = CST_INIT;
  272. ClearCand(lpIMC);
  273. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  274. ~(MSG_OPEN_CANDIDATE);
  275. if(!(lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  276. lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen =
  277. lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
  278. Finalize(lpIMC, lpCompStr, lpImcP, TEXT('\b'));
  279. lpImcP->PrivateArea.Comp_Status.dwInvalid = 0;
  280. }
  281. return;
  282. }
  283. lpImcP->iImeState = CST_INIT;
  284. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  285. InitCompStr(lpCompStr);
  286. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION)
  287. & ~(MSG_START_COMPOSITION);
  288. return;
  289. }
  290. }
  291. #ifdef EUDC
  292. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  293. }else{
  294. #endif //EUDC
  295. // chang candidate by backspace
  296. if (MBIndex.IMEChara[0].IC_TS) {
  297. lpImcP->fdwImeMsg =
  298. (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE | MSG_CHANGE_CANDIDATE) &
  299. ~(MSG_CLOSE_CANDIDATE);
  300. } else {
  301. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  302. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  303. ~(MSG_OPEN_CANDIDATE);
  304. }
  305. }
  306. #ifdef EUDC
  307. }
  308. #endif//EUDC
  309. // reading string is composition string for some simple IMEs
  310. // delta start is the same as cursor position for backspace
  311. lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen =
  312. lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
  313. Finalize(lpIMC, lpCompStr, lpImcP, TEXT('\b'));
  314. return;
  315. }
  316. /**********************************************************************/
  317. /* CompStrInfo() */
  318. /**********************************************************************/
  319. void PASCAL CompStrInfo(
  320. LPCOMPOSITIONSTRING lpCompStr,
  321. LPPRIVCONTEXT lpImcP,
  322. LPGUIDELINE lpGuideLine,
  323. WORD wCharCode)
  324. {
  325. register DWORD dwCursorPos;
  326. // multicode
  327. if(lpImcP->PrivateArea.Comp_Status.dwSTMULCODE) {
  328. InitCompStr(lpCompStr);
  329. }
  330. //
  331. dwCursorPos = lpCompStr->dwCursorPos;
  332. // dwCrusorPos limit
  333. if (dwCursorPos >= MBIndex.MBDesc[0].wMaxCodes) {
  334. // exceed the max input key limitation
  335. lpGuideLine->dwLevel = GL_LEVEL_ERROR;
  336. lpGuideLine->dwIndex = GL_ID_TOOMANYSTROKE;
  337. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  338. MessageBeep(0xFFFFFFFF);
  339. return;
  340. }
  341. // set MSG_START_COMPOSITION
  342. if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  343. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_START_COMPOSITION) &
  344. ~(MSG_END_COMPOSITION);
  345. }
  346. if (lpImcP->iImeState == CST_INIT) {
  347. }
  348. // composition/reading string - UsedCode(Full Shape)
  349. lpImcP->dwCompChar = (DWORD)wCharCode;
  350. // set reading string for lpCompStr
  351. *((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset +
  352. dwCursorPos*sizeof(TCHAR))) = (BYTE)lpImcP->dwCompChar;
  353. // composition/reading attribute - IME has converted these chars
  354. *((LPUNAWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset +
  355. dwCursorPos*sizeof(TCHAR))) = ((ATTR_TARGET_CONVERTED << 8)|ATTR_TARGET_CONVERTED);
  356. // set reading string lenght for lpCompStr
  357. if (lpCompStr->dwCompReadStrLen <= dwCursorPos) {
  358. lpCompStr->dwCompReadStrLen += sizeof(BYTE);
  359. }
  360. // composition string is reading string for some simple IMEs
  361. lpCompStr->dwCompStrLen = lpCompStr->dwCompReadStrLen;
  362. // composition/reading attribute length is equal to reading string length
  363. lpCompStr->dwCompReadAttrLen = lpCompStr->dwCompReadStrLen;
  364. lpCompStr->dwCompAttrLen = lpCompStr->dwCompStrLen;
  365. // delta start from previous cursor position
  366. lpCompStr->dwDeltaStart = lpCompStr->dwCursorPos;
  367. // set new cursor with next to the composition string
  368. lpCompStr->dwCursorPos = lpCompStr->dwCompStrLen;
  369. // tell app, there is a composition char generated
  370. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  371. // set lpImeP->fdwGcsFlag
  372. lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|GCS_DELTASTART;
  373. return;
  374. }
  375. /**********************************************************************/
  376. /* Finalize() */
  377. /* Return vlaue */
  378. /* Engine Flag */
  379. /* Description: */
  380. /* Call Engine finalize Chinese word(s) by searching table */
  381. /* (Set lpCompStr and lpCandList) */
  382. /* Set lpImeP(iImeState, fdwImeMsg, fdwGcsFlag) */
  383. /**********************************************************************/
  384. UINT PASCAL Finalize(
  385. LPINPUTCONTEXT lpIMC,
  386. LPCOMPOSITIONSTRING lpCompStr,
  387. LPPRIVCONTEXT lpImcP,
  388. WORD wCharCode)
  389. {
  390. LPCANDIDATEINFO lpCandInfo;
  391. LPCANDIDATELIST lpCandList;
  392. UINT fEngine;
  393. if (!lpIMC->hCandInfo) {
  394. return (0);
  395. }
  396. // get lpCandInfo
  397. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  398. if (!lpCandInfo) {
  399. return (0);
  400. }
  401. // get lpCandList and init dwCount & dwSelection
  402. lpCandList = (LPCANDIDATELIST)
  403. ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
  404. lpCandList->dwCount = 0;
  405. lpCandList->dwSelection = 0;
  406. // search the IME tables
  407. fEngine =Engine(lpCompStr, lpCandList, lpImcP, lpIMC, wCharCode);
  408. if (fEngine == ENGINE_COMP) {
  409. lpCandInfo->dwCount = 1;
  410. if(lpCandList->dwCount == 0) {
  411. MessageBeep((UINT)-1);
  412. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  413. ~(MSG_OPEN_CANDIDATE);
  414. ImmUnlockIMCC(lpIMC->hCandInfo);
  415. return (fEngine);
  416. } else {
  417. // open composition candidate UI window for the string(s)
  418. if ((MBIndex.IMEChara[0].IC_TS)
  419. || (lpImcP->PrivateArea.Comp_Status.dwSTMULCODE)) {
  420. if ((lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) ==
  421. (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) {
  422. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CHANGE_CANDIDATE) &
  423. ~(MSG_CLOSE_CANDIDATE);
  424. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  425. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  426. } else {
  427. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE) &
  428. ~(MSG_CLOSE_CANDIDATE);
  429. }
  430. } else {
  431. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  432. lpImcP->fdwImeMsg =
  433. (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  434. ~(MSG_OPEN_CANDIDATE);
  435. }
  436. }
  437. }
  438. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  439. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  440. }
  441. } else if (fEngine == ENGINE_ASCII) {
  442. } else if (fEngine == ENGINE_RESAULT) {
  443. // Set lpImep! and tell application, there is a reslut string
  444. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  445. lpImcP->dwCompChar = (DWORD) 0;
  446. lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  447. GCS_DELTASTART|GCS_RESULTREAD|GCS_RESULT;
  448. if(!(MBIndex.IMEChara[0].IC_LX)
  449. || !(lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  450. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  451. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  452. ~(MSG_OPEN_CANDIDATE);
  453. }
  454. // clear candidate now
  455. lpCandList->dwCount = 0;
  456. // set iImeState with CST_INIT
  457. lpImcP->iImeState = CST_INIT;
  458. } else {
  459. if ((MBIndex.IMEChara[0].IC_TS)
  460. || (lpImcP->PrivateArea.Comp_Status.dwSTLX)) {
  461. if ((lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) ==
  462. (MSG_ALREADY_OPEN|MSG_CLOSE_CANDIDATE)) {
  463. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CHANGE_CANDIDATE) &
  464. ~(MSG_CLOSE_CANDIDATE);
  465. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  466. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  467. } else {
  468. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE) &
  469. ~(MSG_CLOSE_CANDIDATE);
  470. }
  471. lpImcP->iImeState = CST_INIT;
  472. } else {
  473. }
  474. }
  475. } else if (fEngine == ENGINE_CHCAND) {
  476. } else if (fEngine == ENGINE_MULTISEL) {
  477. } else if (fEngine == ENGINE_ESC) {
  478. } else if (fEngine == ENGINE_BKSPC) {
  479. } else {
  480. }
  481. ImmUnlockIMCC(lpIMC->hCandInfo);
  482. return fEngine;
  483. }
  484. /**********************************************************************/
  485. /* CompWord() */
  486. /**********************************************************************/
  487. void PASCAL CompWord( // compose the Chinese word(s) according to
  488. // input key
  489. WORD wCharCode,
  490. LPINPUTCONTEXT lpIMC,
  491. LPCOMPOSITIONSTRING lpCompStr,
  492. LPPRIVCONTEXT lpImcP,
  493. LPGUIDELINE lpGuideLine)
  494. {
  495. // lpComStr=NULL?
  496. if (!lpCompStr) {
  497. MessageBeep((UINT)-1);
  498. return;
  499. }
  500. // escape key
  501. if ((wCharCode == VK_ESCAPE) || (wCharCode == 0x0d)) {
  502. lpImcP->iImeState = CST_INIT;
  503. CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  504. return;
  505. }
  506. // GuideLine
  507. if (!lpGuideLine) {
  508. } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
  509. lpGuideLine->dwStrLen = 0;
  510. } else {
  511. // previous input error cause us trancate some chars
  512. if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
  513. lpCompStr->dwCompReadStrLen = lpCompStr->dwCompStrLen =
  514. lpCompStr->dwCursorPos;
  515. lpCompStr->dwCompReadAttrLen = lpCompStr->dwCompReadStrLen;
  516. lpCompStr->dwCompAttrLen = lpCompStr->dwCompStrLen;
  517. }
  518. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  519. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  520. lpGuideLine->dwStrLen = 0;
  521. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  522. }
  523. // backspace key
  524. if (wCharCode == TEXT('\b')) {
  525. CompBackSpaceKey(lpIMC, lpCompStr, lpImcP);
  526. return;
  527. }
  528. lpImcP->iImeState = CST_INPUT;
  529. if(wCharCode == TEXT(' ')) {
  530. #ifdef EUDC
  531. }else if( lpIMC->fdwConversion & IME_CMODE_EUDC && lpCompStr->dwCompReadStrLen >= EUDC_MAX_READING ){
  532. MessageBeep((UINT)-1);
  533. #endif //EUDC
  534. } else {
  535. // build up composition string info
  536. CompStrInfo(lpCompStr, lpImcP, lpGuideLine, wCharCode);
  537. }
  538. #ifdef EUDC
  539. if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  540. if (lpCompStr->dwCompReadStrLen >= lpImeL->nMaxKey
  541. || lpCompStr->dwCompReadStrLen >= EUDC_MAX_READING
  542. || wCharCode == TEXT(' ')) {
  543. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  544. lpImcP->fdwGcsFlag |= GCS_RESULTREAD|GCS_RESULTSTR;
  545. }
  546. } else
  547. #endif //EUDC
  548. Finalize(lpIMC, lpCompStr, lpImcP, wCharCode); // compsition
  549. return;
  550. }