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.

639 lines
20 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. CHCAND.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #include "uniime.h"
  11. #if !defined(ROMANIME)
  12. /**********************************************************************/
  13. /* PhrasePredition() */
  14. /* Return vlaue */
  15. /* the number of candidates in the candidate list */
  16. /**********************************************************************/
  17. UINT PASCAL PhrasePrediction( // predict Chinese word(s) by searching
  18. // phrase data base
  19. #if defined(UNIIME)
  20. LPIMEL lpImeL,
  21. #endif
  22. LPINPUTCONTEXT lpIMC,
  23. LPCOMPOSITIONSTRING lpCompStr,
  24. LPPRIVCONTEXT lpImcP)
  25. {
  26. LPCANDIDATEINFO lpCandInfo;
  27. LPCANDIDATELIST lpCandList;
  28. DWORD dwStartLen, dwEndLen;
  29. UINT nCand;
  30. if (!lpCompStr) {
  31. return (0);
  32. }
  33. if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|IME_CMODE_EUDC|
  34. IME_CMODE_SYMBOL)) != IME_CMODE_NATIVE) {
  35. // should not do phrase prediction, if not under IME_CMODE_NATIVE
  36. return (0);
  37. }
  38. //if ((WORD)lpIMC->fdwSentence != IME_SMODE_PHRASEPREDICT) {
  39. if (!(lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT)) {
  40. // should not do phrase prediction, if not under IME_SMODE_PHRASEPREDICT
  41. return (0);
  42. }
  43. if (!lpIMC->hCandInfo) {
  44. return (0);
  45. }
  46. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  47. if (!lpCandInfo) {
  48. return (0);
  49. }
  50. lpCandList = (LPCANDIDATELIST)
  51. ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
  52. // ImeToAsciiEx will call into this function, so we need to init again
  53. lpCandList->dwCount = 0;
  54. // default start from 0
  55. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  56. dwStartLen = sizeof(WCHAR) / sizeof(TCHAR);
  57. dwEndLen = (UINT)-1;
  58. // one day may be this API can accept bo po mo fo as aid information
  59. // so we pass the ResultReadStr for Phonetic
  60. // one DBCS char may have two pronounciations but when it is in a
  61. // phrase it may only use one pronounciation of them
  62. UniSearchPhrasePrediction(lpImeL, NATIVE_CP,
  63. (LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset),
  64. lpCompStr->dwResultStrLen,
  65. #if defined(PHON)
  66. (LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwResultReadStrOffset),
  67. lpCompStr->dwResultReadStrLen,
  68. #else
  69. NULL, 0,
  70. #endif
  71. dwStartLen, dwEndLen, (UINT)-1, lpCandList);
  72. // how many strings we got?
  73. nCand = lpCandList->dwCount;
  74. if (nCand == 0) {
  75. lpCandInfo->dwCount = 0;
  76. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  77. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  78. goto PhPrUnlockCandInfo;
  79. }
  80. // for showing phrase prediction string(s)
  81. lpCandInfo->dwCount = 1;
  82. // open composition candidate UI window for the string(s)
  83. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  84. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CHANGE_CANDIDATE) &
  85. ~(MSG_CLOSE_CANDIDATE);
  86. } else {
  87. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE) &
  88. ~(MSG_CLOSE_CANDIDATE);
  89. }
  90. PhPrUnlockCandInfo:
  91. ImmUnlockIMCC(lpIMC->hCandInfo);
  92. return (nCand);
  93. }
  94. /**********************************************************************/
  95. /* SelectOneCand() */
  96. /**********************************************************************/
  97. void PASCAL SelectOneCand(
  98. #if defined(UNIIME)
  99. LPIMEL lpImeL,
  100. #endif
  101. HIMC hIMC,
  102. LPINPUTCONTEXT lpIMC,
  103. LPCOMPOSITIONSTRING lpCompStr,
  104. LPPRIVCONTEXT lpImcP,
  105. LPCANDIDATELIST lpCandList)
  106. {
  107. DWORD dwCompStrLen;
  108. DWORD dwReadClauseLen, dwReadStrLen;
  109. LPTSTR lpSelectStr;
  110. LPGUIDELINE lpGuideLine;
  111. if (!lpCompStr) {
  112. MessageBeep((UINT)-1);
  113. return;
  114. }
  115. if (!lpImcP) {
  116. MessageBeep((UINT)-1);
  117. return;
  118. }
  119. // backup the dwCompStrLen, this value decide whether
  120. // we go for phrase prediction
  121. dwCompStrLen = lpCompStr->dwCompStrLen;
  122. // backup the value, this value will be destroyed in InitCompStr
  123. dwReadClauseLen = lpCompStr->dwCompReadClauseLen;
  124. dwReadStrLen = lpCompStr->dwCompReadStrLen;
  125. lpSelectStr = (LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
  126. lpCandList->dwSelection]);
  127. InitCompStr(lpCompStr);
  128. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  129. ImmSetConversionStatus(hIMC,
  130. lpIMC->fdwConversion & ~(IME_CMODE_SYMBOL),
  131. lpIMC->fdwSentence);
  132. }
  133. // the result reading clause = compsotion reading clause
  134. CopyMemory((LPBYTE)lpCompStr + lpCompStr->dwResultReadClauseOffset,
  135. (LPBYTE)lpCompStr + lpCompStr->dwCompReadClauseOffset,
  136. dwReadClauseLen * sizeof(TCHAR) + sizeof(TCHAR));
  137. lpCompStr->dwResultReadClauseLen = dwReadClauseLen;
  138. // the result reading string = compsotion reading string
  139. CopyMemory((LPBYTE)lpCompStr + lpCompStr->dwResultReadStrOffset,
  140. (LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset,
  141. dwReadStrLen * sizeof(TCHAR) + sizeof(TCHAR));
  142. lpCompStr->dwResultReadStrLen = dwReadStrLen;
  143. // calculate result string length
  144. lpCompStr->dwResultStrLen = lstrlen(lpSelectStr);
  145. // the result string = the selected candidate;
  146. CopyMemory((LPBYTE)lpCompStr + lpCompStr->dwResultStrOffset, lpSelectStr,
  147. lpCompStr->dwResultStrLen * sizeof(TCHAR) + sizeof(TCHAR));
  148. lpCompStr->dwResultClauseLen = 2 * sizeof(DWORD);
  149. *(LPDWORD)((LPBYTE)lpCompStr + lpCompStr->dwResultClauseOffset +
  150. sizeof(DWORD)) = lpCompStr->dwResultStrLen;
  151. // tell application, there is a reslut string
  152. lpImcP->fdwImeMsg |= MSG_COMPOSITION;
  153. lpImcP->dwCompChar = (DWORD) 0;
  154. lpImcP->fdwGcsFlag |= GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
  155. GCS_DELTASTART|GCS_RESULTREAD|GCS_RESULT;
  156. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  157. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  158. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  159. } else {
  160. lpImcP->fdwImeMsg &= ~(MSG_CLOSE_CANDIDATE|MSG_OPEN_CANDIDATE);
  161. }
  162. // no candidate now, the right candidate string already be finalized
  163. lpCandList->dwCount = 0;
  164. lpImcP->iImeState = CST_INIT;
  165. *(LPDWORD)lpImcP->bSeq = 0;
  166. #if defined(CHAJEI) || defined(QUICK) || defined(WINAR30) || defined(UNIIME)
  167. *(LPDWORD)&lpImcP->bSeq[4] = 0;
  168. #endif
  169. //if ((WORD)lpIMC->fdwSentence != IME_SMODE_PHRASEPREDICT) {
  170. if (!(lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT)) {
  171. // not in phrase prediction mode
  172. } else if (!dwCompStrLen) {
  173. } else if (lpCompStr->dwResultStrLen != sizeof(WCHAR) / sizeof(TCHAR)) {
  174. } else {
  175. // we only predict when we have composition string before and
  176. // result string is one DBCS char
  177. PhrasePrediction(
  178. #if defined(UNIIME)
  179. lpImeL,
  180. #endif
  181. lpIMC, lpCompStr, lpImcP);
  182. }
  183. if (!lpCandList->dwCount) {
  184. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  185. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
  186. ~(MSG_START_COMPOSITION);
  187. } else {
  188. lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION|MSG_START_COMPOSITION);
  189. }
  190. }
  191. if (!lpImeL->hRevKL) {
  192. return;
  193. }
  194. if (lpCompStr->dwResultStrLen != sizeof(WCHAR) / sizeof(TCHAR)) {
  195. // we only can reverse convert one DBCS character for now
  196. if (lpImcP->fdwImeMsg & MSG_GUIDELINE) {
  197. return;
  198. }
  199. }
  200. lpGuideLine = ImmLockIMCC(lpIMC->hGuideLine);
  201. if (!lpGuideLine) {
  202. return;
  203. }
  204. if (lpCompStr->dwResultStrLen != sizeof(WCHAR) / sizeof(TCHAR)) {
  205. // we only can reverse convert one DBCS character for now
  206. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  207. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  208. } else {
  209. TCHAR szStrBuf[4];
  210. UINT uSize;
  211. *(LPDWORD)szStrBuf = 0;
  212. *(LPWSTR)szStrBuf = *(LPWSTR)((LPBYTE)lpCompStr +
  213. lpCompStr->dwResultStrOffset);
  214. uSize = ImmGetConversionList(lpImeL->hRevKL, (HIMC)NULL, szStrBuf,
  215. (LPCANDIDATELIST)((LPBYTE)lpGuideLine + lpGuideLine->dwPrivateOffset),
  216. lpGuideLine->dwPrivateSize, GCL_REVERSECONVERSION);
  217. if (uSize) {
  218. lpGuideLine->dwLevel = GL_LEVEL_INFORMATION;
  219. lpGuideLine->dwIndex = GL_ID_REVERSECONVERSION;
  220. lpImcP->fdwImeMsg |= MSG_GUIDELINE;
  221. if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  222. lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION|
  223. MSG_START_COMPOSITION);
  224. } else {
  225. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg|
  226. MSG_START_COMPOSITION) & ~(MSG_END_COMPOSITION);
  227. }
  228. } else {
  229. lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
  230. lpGuideLine->dwIndex = GL_ID_UNKNOWN;
  231. }
  232. }
  233. ImmUnlockIMCC(lpIMC->hGuideLine);
  234. return;
  235. }
  236. /**********************************************************************/
  237. /* CandEscapeKey() */
  238. /**********************************************************************/
  239. void PASCAL CandEscapeKey(
  240. LPINPUTCONTEXT lpIMC,
  241. LPPRIVCONTEXT lpImcP)
  242. {
  243. LPCOMPOSITIONSTRING lpCompStr;
  244. LPGUIDELINE lpGuideLine;
  245. // clean all candidate information
  246. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  247. ClearCand(lpIMC);
  248. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  249. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  250. } else if (lpImcP->fdwImeMsg & MSG_OPEN_CANDIDATE) {
  251. ClearCand(lpIMC);
  252. lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  253. } else {
  254. }
  255. lpImcP->iImeState = CST_INPUT;
  256. // if it start composition, we need to clean composition
  257. if (!(lpImcP->fdwImeMsg & (MSG_ALREADY_START|MSG_START_COMPOSITION))) {
  258. return;
  259. }
  260. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  261. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  262. CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
  263. ImmUnlockIMCC(lpIMC->hGuideLine);
  264. ImmUnlockIMCC(lpIMC->hCompStr);
  265. return;
  266. }
  267. /**********************************************************************/
  268. /* ChooseCand() */
  269. /**********************************************************************/
  270. void PASCAL ChooseCand( // choose one of candidate strings by
  271. // input char
  272. #if defined(UNIIME)
  273. LPINSTDATAL lpInstL,
  274. LPIMEL lpImeL,
  275. #endif
  276. WORD wCharCode,
  277. HIMC hIMC,
  278. LPINPUTCONTEXT lpIMC,
  279. LPCANDIDATEINFO lpCandInfo,
  280. LPPRIVCONTEXT lpImcP)
  281. {
  282. LPCANDIDATELIST lpCandList;
  283. LPCOMPOSITIONSTRING lpCompStr;
  284. LPGUIDELINE lpGuideLine;
  285. #if defined(PHON)
  286. WORD wStandardChar;
  287. char cIndex;
  288. #endif
  289. if (wCharCode == VK_ESCAPE) { // escape key
  290. CandEscapeKey(lpIMC, lpImcP);
  291. return;
  292. }
  293. if (!lpCandInfo) {
  294. MessageBeep((UINT)-1);
  295. return;
  296. }
  297. if (!lpCandInfo->dwCount) {
  298. MessageBeep((UINT)-1);
  299. return;
  300. }
  301. lpCandList = (LPCANDIDATELIST)
  302. ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
  303. #if defined(WINAR30)
  304. if (wCharCode == CHOOSE_CIRCLE) { // circle selection
  305. if (lpCandList->dwCount <= lpCandList->dwPageSize) {
  306. wCharCode = lpImeL->wCandStart;
  307. }
  308. }
  309. #endif
  310. if (wCharCode == CHOOSE_CIRCLE) { // circle selection
  311. lpCandList->dwPageStart = lpCandList->dwSelection =
  312. lpCandList->dwSelection + lpCandList->dwPageSize;
  313. if (lpCandList->dwSelection >= lpCandList->dwCount) {
  314. // no more candidates, restart it!
  315. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  316. MessageBeep((UINT)-1);
  317. }
  318. // inform UI, dwSelectedCand is changed
  319. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  320. return;
  321. }
  322. if (wCharCode == CHOOSE_NEXTPAGE) { // next selection
  323. lpCandList->dwPageStart = lpCandList->dwSelection =
  324. lpCandList->dwSelection + lpCandList->dwPageSize;
  325. if (lpCandList->dwSelection >= lpCandList->dwCount) {
  326. // no more candidates, restart it!
  327. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  328. MessageBeep((UINT)-1);
  329. }
  330. // inform UI, dwSelectedCand is changed
  331. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  332. return;
  333. }
  334. if (wCharCode == CHOOSE_PREVPAGE) { // previous selection
  335. if (!lpCandList->dwSelection) {
  336. MessageBeep((UINT)-1);
  337. return;
  338. }
  339. // maybe we can not use this size, it totally depend on
  340. // whether the application draw UI by itself
  341. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  342. lpImcP->dwPrevPageStart = lpCandList->dwPageStart;
  343. lpImcP->fdwImeMsg |= MSG_IMN_PAGEUP;
  344. }
  345. if (lpCandList->dwSelection < lpCandList->dwPageSize) {
  346. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  347. } else {
  348. lpCandList->dwPageStart = lpCandList->dwSelection =
  349. lpCandList->dwSelection - lpCandList->dwPageSize;
  350. }
  351. // inform UI, dwSelectedCand is changed
  352. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  353. return;
  354. }
  355. if (wCharCode == CHOOSE_HOME) { // home selection
  356. if (lpCandList->dwSelection == 0) {
  357. MessageBeep((UINT)-1); // already home!
  358. return;
  359. }
  360. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  361. // inform UI, dwSelectedCand is changed
  362. lpImcP->fdwImeMsg |= MSG_CHANGE_CANDIDATE;
  363. return;
  364. }
  365. if ((wCharCode >= 0 + lpImeL->wCandRangeStart) && (wCharCode <= 9)) {
  366. // dayi starts from 0, CandRangeStart == 0
  367. // array starts from 1, CandPerPage == 10
  368. DWORD dwSelection;
  369. // choose one candidate from the candidate list
  370. dwSelection = lpCandList->dwSelection + (wCharCode +
  371. lpImeL->wCandPerPage - lpImeL->wCandStart) %
  372. lpImeL->wCandPerPage;
  373. if (dwSelection >= lpCandList->dwCount) {
  374. // out of range
  375. MessageBeep((UINT)-1);
  376. return;
  377. }
  378. // one candidate is selected by 1, 2, or 3 ...
  379. #if defined(WINAR30)
  380. if (!*(LPWSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
  381. dwSelection])) {
  382. MessageBeep((UINT)-1);
  383. return;
  384. }
  385. #endif
  386. lpCandList->dwSelection = dwSelection;
  387. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  388. // translate into translate buffer
  389. SelectOneCand(
  390. #if defined(UNIIME)
  391. lpImeL,
  392. #endif
  393. hIMC, lpIMC, lpCompStr, lpImcP, lpCandList);
  394. ImmUnlockIMCC(lpIMC->hCompStr);
  395. return;
  396. }
  397. #if defined(UNIIME)
  398. if (!lpInstL) {
  399. MessageBeep((UINT)-1);
  400. return;
  401. }
  402. #endif
  403. // don't select by choose key, the 1st candidate is default selected
  404. // candidate string is decided but we also need to decide the
  405. // composition string for this input
  406. #if defined(PHON)
  407. // this check only useful in IBM and other layout
  408. wStandardChar = bUpper[wCharCode - ' '];
  409. // even for ETen 26 Keys, this is OK we don't need to access ETen2ndLayout
  410. wStandardChar = bStandardLayout[lpImeL->nReadLayout][wStandardChar - ' '];
  411. cIndex = cIndexTable[wStandardChar - ' '];
  412. if (cIndex >= 3) {
  413. MessageBeep((UINT)-1);
  414. return;
  415. }
  416. #endif
  417. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  418. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  419. // translate into translate buffer
  420. SelectOneCand(
  421. #if defined(UNIIME)
  422. lpImeL,
  423. #endif
  424. hIMC, lpIMC, lpCompStr, lpImcP, lpCandList);
  425. // don't phrase prediction under this case
  426. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  427. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  428. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  429. } else {
  430. lpImcP->fdwImeMsg &= ~(MSG_CLOSE_CANDIDATE|MSG_OPEN_CANDIDATE);
  431. }
  432. CompWord(
  433. #if defined(UNIIME)
  434. lpInstL, lpImeL,
  435. #endif
  436. wCharCode, hIMC, lpIMC, lpCompStr, lpGuideLine, lpImcP);
  437. if (lpGuideLine) {
  438. ImmUnlockIMCC(lpIMC->hGuideLine);
  439. }
  440. if (lpCompStr) {
  441. ImmUnlockIMCC(lpIMC->hCompStr);
  442. }
  443. return;
  444. }
  445. #if defined(WINAR30) || defined(DAYI)
  446. /**********************************************************************/
  447. /* SearchSymbol */
  448. /**********************************************************************/
  449. void PASCAL SearchSymbol( // serach symbol characters
  450. WORD wSymbolSet,
  451. HIMC hIMC,
  452. LPINPUTCONTEXT lpIMC,
  453. LPPRIVCONTEXT lpImcP)
  454. {
  455. LPCANDIDATEINFO lpCandInfo;
  456. LPCANDIDATELIST lpCandList;
  457. UINT i;
  458. if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|IME_CMODE_EUDC|
  459. IME_CMODE_SYMBOL)) != (IME_CMODE_NATIVE|IME_CMODE_SYMBOL)) {
  460. return;
  461. }
  462. if (!lpIMC->hCandInfo) {
  463. return;
  464. }
  465. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  466. if (!lpCandInfo) {
  467. return;
  468. }
  469. lpCandList = (LPCANDIDATELIST)
  470. ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
  471. lpCandList->dwCount = 0;
  472. #if defined(DAYI)
  473. if (wSymbolSet >= 'A' && wSymbolSet <= 'Z') {
  474. AddCodeIntoCand(lpCandList, sImeG.wFullABC[wSymbolSet - ' ']);
  475. } else if (wSymbolSet >= 'a' && wSymbolSet <= 'z') {
  476. AddCodeIntoCand(lpCandList, sImeG.wFullABC[wSymbolSet - ' ']);
  477. } else {
  478. #endif
  479. #if defined(WINAR30)
  480. {
  481. #endif
  482. for (i = 0; i < sizeof(lpImeL->wSymbol) / sizeof(WORD); i++) {
  483. if (lpImeL->wSymbol[i] == wSymbolSet) {
  484. break;
  485. }
  486. }
  487. if (++i < sizeof(lpImeL->wSymbol) / sizeof(WORD)) {
  488. for (; lpImeL->wSymbol[i] > 0x007F; i++) {
  489. AddCodeIntoCand(lpCandList, lpImeL->wSymbol[i]);
  490. }
  491. }
  492. }
  493. if (!lpCandList->dwCount) {
  494. ImmSetConversionStatus(hIMC,
  495. lpIMC->fdwConversion & ~(IME_CMODE_SYMBOL),
  496. lpIMC->fdwSentence);
  497. CompCancel(hIMC, lpIMC);
  498. Select(
  499. #if defined(UNIIME)
  500. lpImeL,
  501. #endif
  502. lpIMC, TRUE);
  503. } else if (lpCandList->dwCount == 1) {
  504. LPCOMPOSITIONSTRING lpCompStr;
  505. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  506. if (lpCompStr) {
  507. SelectOneCand(hIMC, lpIMC, lpCompStr, lpImcP, lpCandList);
  508. ImmUnlockIMCC(lpIMC->hCompStr);
  509. }
  510. } else {
  511. lpCandInfo->dwCount = 1;
  512. if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  513. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CHANGE_CANDIDATE) &
  514. ~(MSG_CLOSE_CANDIDATE);
  515. } else {
  516. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_OPEN_CANDIDATE) &
  517. ~(MSG_CLOSE_CANDIDATE);
  518. }
  519. lpImcP->iImeState = CST_CHOOSE;
  520. }
  521. ImmUnlockIMCC(lpIMC->hCandInfo);
  522. }
  523. #endif // defined(WINAR30) || defined(DAYI)
  524. #endif // !defined(ROMANIME)