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.

1461 lines
46 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. DIC.C
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "fakeime.h"
  9. #include "vksub.h"
  10. #include "immsec.h"
  11. #if defined(FAKEIMEM) || defined(UNICODE)
  12. int GetCandidateStringsFromDictionary(LPWSTR lpString, LPWSTR lpBuf, DWORD dwBufLen, LPTSTR szDicFileName);
  13. #endif
  14. BOOL GetAnsiPathName(LPCWSTR lpszUniPath,LPSTR lpszAnsiPath,UINT nMaxLen)
  15. {
  16. if (WideCharToMultiByte(CP_ACP,
  17. WC_COMPOSITECHECK,
  18. lpszUniPath,
  19. -1,
  20. lpszAnsiPath,
  21. nMaxLen,
  22. NULL,
  23. NULL) != 0) {
  24. return TRUE;
  25. }
  26. else {
  27. return FALSE;
  28. }
  29. }
  30. /**********************************************************************/
  31. /* */
  32. /* FlushText() */
  33. /* */
  34. /**********************************************************************/
  35. void PASCAL FlushText(HIMC hIMC)
  36. {
  37. LPINPUTCONTEXT lpIMC;
  38. LPCOMPOSITIONSTRING lpCompStr;
  39. LPCANDIDATEINFO lpCandInfo;
  40. TRANSMSG GnMsg;
  41. if (!IsCompStr(hIMC))
  42. return;
  43. if (!(lpIMC = ImmLockIMC(hIMC)))
  44. return;
  45. if (IsCandidate(lpIMC))
  46. {
  47. //
  48. // Flush candidate lists.
  49. //
  50. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  51. ClearCandidate(lpCandInfo);
  52. ImmUnlockIMCC(lpIMC->hCandInfo);
  53. GnMsg.message = WM_IME_NOTIFY;
  54. GnMsg.wParam = IMN_CLOSECANDIDATE;
  55. GnMsg.lParam = 1;
  56. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  57. }
  58. if (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr))
  59. {
  60. //
  61. // Flush composition strings.
  62. //
  63. ClearCompStr(lpCompStr,CLR_RESULT_AND_UNDET);
  64. ImmUnlockIMCC(lpIMC->hCompStr);
  65. GnMsg.message = WM_IME_COMPOSITION;
  66. GnMsg.wParam = 0;
  67. GnMsg.lParam = 0;
  68. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  69. GnMsg.message = WM_IME_ENDCOMPOSITION;
  70. GnMsg.wParam = 0;
  71. GnMsg.lParam = 0;
  72. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  73. }
  74. ImmUnlockIMC(hIMC);
  75. }
  76. /**********************************************************************/
  77. /* */
  78. /* RevertText() */
  79. /* */
  80. /**********************************************************************/
  81. void PASCAL RevertText(HIMC hIMC)
  82. {
  83. LPINPUTCONTEXT lpIMC;
  84. LPCOMPOSITIONSTRING lpCompStr;
  85. LPCANDIDATEINFO lpCandInfo;
  86. TRANSMSG GnMsg;
  87. LPMYSTR lpread,lpstr;
  88. if (!IsCompStr(hIMC))
  89. return;
  90. if (!(lpIMC = ImmLockIMC(hIMC)))
  91. return;
  92. if (IsCandidate(lpIMC))
  93. {
  94. //
  95. // Flush candidate lists.
  96. //
  97. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  98. ClearCandidate(lpCandInfo);
  99. ImmUnlockIMCC(lpIMC->hCandInfo);
  100. GnMsg.message = WM_IME_NOTIFY;
  101. GnMsg.wParam = IMN_CLOSECANDIDATE;
  102. GnMsg.lParam = 1;
  103. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  104. }
  105. if (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr))
  106. {
  107. lpstr = GETLPCOMPSTR(lpCompStr);
  108. lpread = GETLPCOMPREADSTR(lpCompStr);
  109. lHanToZen(lpstr,lpread,lpIMC->fdwConversion);
  110. //
  111. // make attribute
  112. //
  113. lpCompStr->dwCursorPos = Mylstrlen(lpstr);
  114. // DeltaStart is 0 at RevertText time.
  115. lpCompStr->dwDeltaStart = 0;
  116. lmemset(GETLPCOMPATTR(lpCompStr),0,Mylstrlen(lpstr));
  117. lmemset(GETLPCOMPREADATTR(lpCompStr),0,Mylstrlen(lpread));
  118. SetClause(GETLPCOMPCLAUSE(lpCompStr),Mylstrlen(lpstr));
  119. SetClause(GETLPCOMPREADCLAUSE(lpCompStr),Mylstrlen(lpread));
  120. lpCompStr->dwCompClauseLen = 8;
  121. lpCompStr->dwCompReadClauseLen = 8;
  122. //
  123. // make length
  124. //
  125. lpCompStr->dwCompStrLen = Mylstrlen(lpstr);
  126. lpCompStr->dwCompReadStrLen = Mylstrlen(lpread);
  127. lpCompStr->dwCompAttrLen = Mylstrlen(lpstr);
  128. lpCompStr->dwCompReadAttrLen = Mylstrlen(lpread);
  129. //
  130. // Generate messages.
  131. //
  132. GnMsg.message = WM_IME_COMPOSITION;
  133. GnMsg.wParam = 0;
  134. GnMsg.lParam = GCS_COMPALL | GCS_CURSORPOS | GCS_DELTASTART;
  135. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  136. ImmUnlockIMCC(lpIMC->hCompStr);
  137. }
  138. ImmUnlockIMC(hIMC);
  139. }
  140. /**********************************************************************/
  141. /* */
  142. /* ConvKanji() */
  143. /* */
  144. /* VK_KANJI Key handling function */
  145. /* */
  146. /**********************************************************************/
  147. BOOL PASCAL ConvKanji(HIMC hIMC)
  148. {
  149. LPINPUTCONTEXT lpIMC;
  150. LPCOMPOSITIONSTRING lpCompStr;
  151. LPCANDIDATEINFO lpCandInfo;
  152. LPCANDIDATELIST lpCandList;
  153. MYCHAR szBuf[256+2];
  154. int nBufLen;
  155. LPMYSTR lpstr;
  156. TRANSMSG GnMsg;
  157. LPBYTE lpb;
  158. OFSTRUCT ofs;
  159. LPMYSTR lpT, lpT2;
  160. int cnt;
  161. BOOL bRc = FALSE;
  162. if ((GetFileAttributes(szDicFileName) == 0xFFFFFFFF) ||
  163. (GetFileAttributes(szDicFileName) == FILE_ATTRIBUTE_DIRECTORY)) {
  164. MakeGuideLine(hIMC,MYGL_NODICTIONARY);
  165. }
  166. if (!IsCompStr(hIMC))
  167. return FALSE;
  168. if (!(lpIMC = ImmLockIMC(hIMC)))
  169. return FALSE;
  170. if (!(lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr)))
  171. goto cvk_exit10;
  172. if (!(lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo)))
  173. goto cvk_exit20;
  174. //
  175. // Since IME handles all string as Unicode, convert the CompReadStr
  176. // from Unicode into multibyte string. Also the dictionary holdsits data
  177. // as Hiragana, so map the string from Katakana to Hiragana.
  178. //
  179. lpT2 = GETLPCOMPREADSTR(lpCompStr);
  180. //
  181. // Get the candidate strings from dic file.
  182. //
  183. szBuf[256] = 0; // Double NULL-terminate
  184. szBuf[257] = 0; // Double NULL-terminate
  185. #if defined(FAKEIMEM) || defined(UNICODE)
  186. nBufLen = GetCandidateStringsFromDictionary(lpT2, szBuf, 256, (LPTSTR)szDicFileName);
  187. #else
  188. nBufLen = GetPrivateProfileString(lpT2, NULL,(LPSTR)"",
  189. (LPSTR)szBuf,256,(LPSTR)szDicFileName );
  190. #endif
  191. //
  192. // Check the result of dic. Because my candidate list has only MAXCANDSTRNUM
  193. // candidate strings.
  194. //
  195. lpT = &szBuf[0];
  196. cnt = 0;
  197. while(*lpT)
  198. {
  199. cnt++;
  200. lpT += (Mylstrlen(lpT) + 1);
  201. if (cnt > MAXCANDSTRNUM)
  202. {
  203. //
  204. // The dic is too big....
  205. //
  206. goto cvk_exit40;
  207. }
  208. }
  209. lpb = GETLPCOMPATTR(lpCompStr);
  210. if (nBufLen < 1)
  211. {
  212. if (!*lpb)
  213. {
  214. //
  215. // make attribute
  216. //
  217. lmemset(GETLPCOMPATTR(lpCompStr),1,
  218. Mylstrlen(GETLPCOMPSTR(lpCompStr)));
  219. lmemset(GETLPCOMPREADATTR(lpCompStr),1,
  220. Mylstrlen(GETLPCOMPREADSTR(lpCompStr)));
  221. GnMsg.message = WM_IME_COMPOSITION;
  222. GnMsg.wParam = 0;
  223. GnMsg.lParam = GCS_COMPSTR | GCS_CURSORPOS |
  224. GCS_COMPATTR | GCS_COMPREADATTR;
  225. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  226. }
  227. goto cvk_exit40;
  228. }
  229. lpstr = (LPMYSTR)szBuf;
  230. if (!*lpb)
  231. {
  232. //
  233. // String is not converted yet.
  234. //
  235. while (*lpstr)
  236. {
  237. if (0 != Mylstrcmp(lpstr,GETLPCOMPSTR(lpCompStr)))
  238. {
  239. set_compstr:
  240. //
  241. // Set the composition string to the structure.
  242. //
  243. Mylstrcpy(GETLPCOMPSTR(lpCompStr),lpstr);
  244. lpstr = GETLPCOMPSTR(lpCompStr);
  245. //
  246. // Set the length and cursor position to the structure.
  247. //
  248. lpCompStr->dwCompStrLen = Mylstrlen(lpstr);
  249. lpCompStr->dwCursorPos = 0;
  250. // Because FAKEIME does not support clause, DeltaStart is 0 anytime.
  251. lpCompStr->dwDeltaStart = 0;
  252. //
  253. // make attribute
  254. //
  255. lmemset((LPBYTE)GETLPCOMPATTR(lpCompStr),1, Mylstrlen(lpstr));
  256. lmemset((LPBYTE)GETLPCOMPREADATTR(lpCompStr),1,
  257. Mylstrlen(GETLPCOMPREADSTR(lpCompStr)));
  258. //
  259. // make clause info
  260. //
  261. SetClause(GETLPCOMPCLAUSE(lpCompStr),Mylstrlen(lpstr));
  262. SetClause(GETLPCOMPREADCLAUSE(lpCompStr),Mylstrlen(GETLPCOMPREADSTR(lpCompStr)));
  263. lpCompStr->dwCompClauseLen = 8;
  264. lpCompStr->dwCompReadClauseLen = 8;
  265. //
  266. // Generate messages.
  267. //
  268. GnMsg.message = WM_IME_COMPOSITION;
  269. GnMsg.wParam = 0;
  270. GnMsg.lParam = GCS_COMPALL | GCS_CURSORPOS | GCS_DELTASTART;
  271. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  272. bRc = TRUE;
  273. goto cvk_exit40;
  274. }
  275. lpstr += (Mylstrlen(lpstr) + 1);
  276. }
  277. }
  278. else
  279. {
  280. //
  281. // String is converted, so that open candidate.
  282. //
  283. int i = 0;
  284. LPDWORD lpdw;
  285. //
  286. // generate WM_IME_NOTFIY IMN_OPENCANDIDATE message.
  287. //
  288. if (!IsCandidate(lpIMC))
  289. {
  290. GnMsg.message = WM_IME_NOTIFY;
  291. GnMsg.wParam = IMN_OPENCANDIDATE;
  292. GnMsg.lParam = 1L;
  293. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  294. }
  295. //
  296. // Make candidate structures.
  297. //
  298. lpCandInfo->dwSize = sizeof(MYCAND);
  299. lpCandInfo->dwCount = 1;
  300. lpCandInfo->dwOffset[0] =
  301. (DWORD)((LPSTR)&((LPMYCAND)lpCandInfo)->cl - (LPSTR)lpCandInfo);
  302. lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]);
  303. lpdw = (LPDWORD)&(lpCandList->dwOffset);
  304. while (*lpstr)
  305. {
  306. lpCandList->dwOffset[i] =
  307. (DWORD)((LPSTR)((LPMYCAND)lpCandInfo)->szCand[i] - (LPSTR)lpCandList);
  308. Mylstrcpy((LPMYSTR)((LPSTR)lpCandList+lpCandList->dwOffset[i]),lpstr);
  309. lpstr += (Mylstrlen(lpstr) + 1);
  310. i++;
  311. }
  312. lpCandList->dwSize = sizeof(CANDIDATELIST) +
  313. (MAXCANDSTRNUM * (sizeof(DWORD) + MAXCANDSTRSIZE));
  314. lpCandList->dwStyle = IME_CAND_READ;
  315. lpCandList->dwCount = i;
  316. if (i < MAXCANDPAGESIZE)
  317. lpCandList->dwPageSize = i;
  318. else
  319. lpCandList->dwPageSize = MAXCANDPAGESIZE;
  320. lpCandList->dwSelection++;
  321. if (lpCandList->dwSelection == (DWORD)i)
  322. {
  323. lpCandList->dwPageStart = 0;
  324. lpCandList->dwSelection = 0;
  325. }
  326. else if (lpCandList->dwSelection >= MAXCANDPAGESIZE)
  327. {
  328. if (lpCandList->dwPageStart + MAXCANDPAGESIZE < lpCandList->dwCount)
  329. lpCandList->dwPageStart++;
  330. }
  331. //
  332. // Generate messages.
  333. //
  334. GnMsg.message = WM_IME_NOTIFY;
  335. GnMsg.wParam = IMN_CHANGECANDIDATE;
  336. GnMsg.lParam = 1L;
  337. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  338. //
  339. // If the selected candidate string is changed, the composition string
  340. // should be updated.
  341. //
  342. lpstr = (LPMYSTR)((LPSTR)lpCandList +
  343. lpCandList->dwOffset[lpCandList->dwSelection]);
  344. goto set_compstr;
  345. }
  346. cvk_exit40:
  347. ImmUnlockIMCC(lpIMC->hCandInfo);
  348. cvk_exit20:
  349. ImmUnlockIMCC(lpIMC->hCompStr);
  350. cvk_exit10:
  351. ImmUnlockIMC(hIMC);
  352. return bRc;
  353. }
  354. /**********************************************************************/
  355. /* */
  356. /* IsEat( code ) */
  357. /* */
  358. /**********************************************************************/
  359. BOOL PASCAL IsEat( code )
  360. register WORD code;
  361. {
  362. #if defined(FAKEIMEM) || defined(UNICODE)
  363. return TRUE;
  364. #else
  365. return( (code >= 0x20 && 0x7f >= code) || (code >= 0x0a1 && 0x0df >= code) ? TRUE : FALSE );
  366. #endif
  367. }
  368. /**********************************************************************/
  369. /* */
  370. /* DeleteChar() */
  371. /* */
  372. /**********************************************************************/
  373. void PASCAL DeleteChar( HIMC hIMC ,UINT uVKey)
  374. {
  375. LPINPUTCONTEXT lpIMC;
  376. LPCOMPOSITIONSTRING lpCompStr;
  377. LPCANDIDATEINFO lpCandInfo;
  378. LPMYSTR lpstr;
  379. LPMYSTR lpread;
  380. LPMYSTR lpptr;
  381. int nChar;
  382. BOOL fDone = FALSE;
  383. DWORD dwCurPos;
  384. TRANSMSG GnMsg;
  385. if (!IsCompStr(hIMC))
  386. return;
  387. if (!(lpIMC = ImmLockIMC(hIMC)))
  388. return;
  389. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  390. dwCurPos = lpCompStr->dwCursorPos;
  391. lpstr = GETLPCOMPSTR(lpCompStr);
  392. if( uVKey == VK_BACK )
  393. {
  394. if( dwCurPos == 0 )
  395. goto dc_exit;
  396. lpptr = MyCharPrev( lpstr, lpstr+dwCurPos );
  397. #if defined(FAKEIMEM) || defined(UNICODE)
  398. nChar = 1;
  399. #else
  400. nChar = IsDBCSLeadByte( *lpptr ) ? 2 : 1;
  401. #endif
  402. if( lpstr == lpptr && Mylstrlen(lpstr) == nChar )
  403. {
  404. dwCurPos = 0;
  405. *lpstr = MYTEXT('\0');
  406. }
  407. else
  408. {
  409. Mylstrcpy( lpptr, lpstr+dwCurPos );
  410. dwCurPos -= nChar;
  411. }
  412. fDone = TRUE;
  413. }
  414. else if( uVKey == VK_DELETE )
  415. {
  416. if( dwCurPos == (DWORD)Mylstrlen(lpstr) )
  417. goto dc_exit;
  418. #if defined(FAKEIMEM) || defined(UNICODE)
  419. nChar = 1;
  420. #else
  421. nChar = IsDBCSLeadByte( *(lpstr+dwCurPos) ) ? 2 : 1;
  422. #endif
  423. Mylstrcpy( lpstr+dwCurPos, lpstr+dwCurPos+nChar );
  424. fDone = TRUE;
  425. }
  426. if (fDone)
  427. {
  428. lpstr = GETLPCOMPSTR(lpCompStr);
  429. lpread = GETLPCOMPREADSTR(lpCompStr);
  430. lZenToHan (lpread,lpstr);
  431. lmemset(GETLPCOMPATTR(lpCompStr),0,Mylstrlen(lpstr));
  432. lmemset(GETLPCOMPREADATTR(lpCompStr),0,Mylstrlen(lpread));
  433. //
  434. // make length
  435. //
  436. lpCompStr->dwCompStrLen = Mylstrlen(lpstr);
  437. lpCompStr->dwCompReadStrLen = Mylstrlen(lpread);
  438. lpCompStr->dwCompAttrLen = Mylstrlen(lpstr);
  439. lpCompStr->dwCompReadAttrLen = Mylstrlen(lpread);
  440. lpCompStr->dwCursorPos = dwCurPos;
  441. // DeltaStart is same of Cursor Pos at DeleteChar time.
  442. lpCompStr->dwDeltaStart = dwCurPos;
  443. //
  444. // make clause info
  445. //
  446. SetClause(GETLPCOMPCLAUSE(lpCompStr),Mylstrlen(lpstr));
  447. SetClause(GETLPCOMPREADCLAUSE(lpCompStr),Mylstrlen(lpread));
  448. lpCompStr->dwCompClauseLen = 8;
  449. lpCompStr->dwCompReadClauseLen = 8;
  450. if (lpCompStr->dwCompStrLen)
  451. {
  452. GnMsg.message = WM_IME_COMPOSITION;
  453. GnMsg.wParam = 0;
  454. GnMsg.lParam = GCS_COMPALL | GCS_CURSORPOS | GCS_DELTASTART;
  455. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  456. }
  457. else
  458. {
  459. if (IsCandidate(lpIMC))
  460. {
  461. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  462. ClearCandidate(lpCandInfo);
  463. GnMsg.message = WM_IME_NOTIFY;
  464. GnMsg.wParam = IMN_CLOSECANDIDATE;
  465. GnMsg.lParam = 1;
  466. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  467. ImmUnlockIMCC(lpIMC->hCandInfo);
  468. }
  469. ClearCompStr(lpCompStr,CLR_RESULT_AND_UNDET);
  470. GnMsg.message = WM_IME_COMPOSITION;
  471. GnMsg.wParam = 0;
  472. GnMsg.lParam = 0;
  473. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  474. GnMsg.message = WM_IME_ENDCOMPOSITION;
  475. GnMsg.wParam = 0;
  476. GnMsg.lParam = 0;
  477. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  478. }
  479. }
  480. dc_exit:
  481. ImmUnlockIMCC(lpIMC->hCompStr);
  482. ImmUnlockIMC(hIMC);
  483. }
  484. /**********************************************************************/
  485. /* */
  486. /* AddChar() */
  487. /* */
  488. /* One character add function */
  489. /* */
  490. /**********************************************************************/
  491. void PASCAL AddChar( hIMC, code )
  492. HIMC hIMC;
  493. WORD code;
  494. {
  495. LPMYSTR lpchText;
  496. LPMYSTR lpread;
  497. LPMYSTR lpstr;
  498. LPMYSTR lpprev;
  499. WORD code2 = 0;
  500. WORD code3;
  501. DWORD fdwConversion;
  502. LPINPUTCONTEXT lpIMC;
  503. LPCOMPOSITIONSTRING lpCompStr;
  504. DWORD dwStrLen;
  505. DWORD dwSize;
  506. TRANSMSG GnMsg;
  507. DWORD dwGCR = 0L;
  508. #if defined(FAKEIMEM) || defined(UNICODE)
  509. WCHAR Katakana, Sound;
  510. #endif
  511. lpIMC = ImmLockIMC(hIMC);
  512. if (ImmGetIMCCSize(lpIMC->hCompStr) < sizeof (MYCOMPSTR))
  513. {
  514. // Init time.
  515. dwSize = sizeof(MYCOMPSTR);
  516. lpIMC->hCompStr = ImmReSizeIMCC(lpIMC->hCompStr,dwSize);
  517. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  518. lpCompStr->dwSize = dwSize;
  519. }
  520. else
  521. {
  522. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  523. }
  524. dwStrLen = lpCompStr->dwCompStrLen;
  525. if (!dwStrLen)
  526. {
  527. //lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  528. InitCompStr(lpCompStr,CLR_RESULT_AND_UNDET);
  529. GnMsg.message = WM_IME_STARTCOMPOSITION;
  530. GnMsg.wParam = 0;
  531. GnMsg.lParam = 0;
  532. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  533. }
  534. else if (IsConvertedCompStr(hIMC))
  535. {
  536. MakeResultString(hIMC,FALSE);
  537. InitCompStr(lpCompStr,CLR_UNDET);
  538. dwGCR = GCS_RESULTALL;
  539. }
  540. if( IsEat( code ) )
  541. {
  542. // Get ConvMode from IMC.
  543. fdwConversion = lpIMC->fdwConversion;
  544. lpchText = GETLPCOMPSTR(lpCompStr);
  545. lpstr = lpchText;
  546. if( lpCompStr->dwCursorPos )
  547. lpstr += lpCompStr->dwCursorPos;
  548. lpstr = lpchText + Mylstrlen(lpchText);
  549. lpprev = MyCharPrev( lpchText, lpstr );
  550. if( fdwConversion & IME_CMODE_CHARCODE ) {
  551. code = (WORD)(LONG_PTR)AnsiUpper( (LPSTR)(LONG_PTR)code );
  552. if( !( (code >= MYTEXT('0') && code <= MYTEXT('9')) ||
  553. (code >= MYTEXT('A') && code <= MYTEXT('F')) ) || lpCompStr->dwCursorPos >= 4 ){
  554. MessageBeep( 0 );
  555. goto ac_exit;
  556. }
  557. *lpstr++ = (BYTE)code;
  558. lpCompStr->dwCursorPos++;
  559. }
  560. else if ( fdwConversion & IME_CMODE_FULLSHAPE )
  561. {
  562. if ( fdwConversion & IME_CMODE_ROMAN &&
  563. fdwConversion & IME_CMODE_NATIVE )
  564. {
  565. #if defined(FAKEIMEM) || defined(UNICODE)
  566. if (*lpprev) {
  567. code2 = *lpprev;
  568. }
  569. else
  570. {
  571. if( IsSecond( code ) )
  572. {
  573. code = ConvChar(hIMC, 0, code );
  574. if (!(fdwConversion & IME_CMODE_KATAKANA))
  575. {
  576. code = KataToHira(code);
  577. }
  578. }
  579. goto DBCS_BETA;
  580. }
  581. if (!( code2 = ZenToHan( code2 ) ))
  582. {
  583. if( IsSecond( code ) )
  584. {
  585. code = ConvChar(hIMC, 0, code );
  586. if (!(fdwConversion & IME_CMODE_KATAKANA))
  587. {
  588. code = KataToHira(code);
  589. }
  590. }
  591. goto DBCS_BETA;
  592. }
  593. if ( IsSecond( code ) )
  594. {
  595. if ( IsFirst( code2 ) &&
  596. (code3 = ConvChar(hIMC, code2, code )))
  597. {
  598. if (fdwConversion & IME_CMODE_KATAKANA)
  599. {
  600. *lpprev = code3;
  601. }
  602. else
  603. {
  604. *lpprev = KataToHira(code3);
  605. }
  606. }
  607. else
  608. {
  609. code = ConvChar(hIMC, 0, code );
  610. if (!(fdwConversion & IME_CMODE_KATAKANA))
  611. {
  612. code = KataToHira(code);
  613. }
  614. goto DBCS_BETA;
  615. }
  616. }
  617. else if( (WORD)(LONG_PTR)CharUpperW( (LPMYSTR)(LONG_PTR)code ) == 'N'
  618. && (WORD)(LONG_PTR)CharUpperW( (LPMYSTR)(LONG_PTR)code2 ) == 'N' )
  619. {
  620. code3 = 0xFF9D;
  621. code2 = HanToZen( code3, 0,fdwConversion);
  622. *lpprev = code2;
  623. }
  624. else
  625. goto DBCS_BETA;
  626. #else
  627. if ( IsDBCSLeadByte( *lpprev ) )
  628. code2 = MAKEWORD( *(lpprev+1), *lpprev );
  629. else
  630. {
  631. if ( IsSecond( code ) )
  632. code = ConvChar(hIMC, 0, code );
  633. goto DBCS_BETA;
  634. }
  635. if (!( code2 = ZenToHan( code2 ) ))
  636. {
  637. if( IsSecond( code ) )
  638. code = ConvChar(hIMC, 0, code );
  639. goto DBCS_BETA;
  640. }
  641. if ( IsSecond( code ) )
  642. {
  643. if ( IsFirst( code2 ) &&
  644. (code3 = ConvChar(hIMC, code2, code )))
  645. {
  646. code2 = HanToZen( code3, fdwConversion);
  647. *lpprev++ = HIBYTE( code2 );
  648. *lpprev = LOBYTE( code2 );
  649. }
  650. else
  651. {
  652. code = ConvChar(hIMC, 0, code );
  653. goto DBCS_BETA;
  654. }
  655. }
  656. else if( (WORD)(LONG_PTR)AnsiUpper( (LPSTR)(LONG_PTR)code ) == 'N'
  657. && (WORD)(LONG_PTR)AnsiUpper( (LPSTR)(LONG_PTR)code2 ) == 'N' )
  658. {
  659. code3 = 0xdd;
  660. code2 = HanToZen( code3, fdwConversion);
  661. *lpprev++ = HIBYTE( code2 );
  662. *lpprev = LOBYTE( code2 );
  663. } else {
  664. //if (!IsFirst( code ))
  665. // MakeGuideLine(hIMC,MYGL_TYPINGERROR);
  666. goto DBCS_BETA;
  667. }
  668. #endif
  669. }
  670. else
  671. {
  672. DBCS_BETA:
  673. if( code == MYTEXT('^') )
  674. {
  675. #if defined(FAKEIMEM) || defined(UNICODE)
  676. code2 = *lpprev;
  677. #else
  678. code2 = MAKEWORD( *(lpprev+1), *lpprev );
  679. #endif
  680. if( IsTenten( code2 ) == FALSE )
  681. goto DBCS_BETA2;
  682. code2 = ConvTenten( code2 );
  683. #if defined(FAKEIMEM) || defined(UNICODE)
  684. *lpprev++ = code2;
  685. #else
  686. if( HIBYTE( code2 ) )
  687. *lpprev++ = HIBYTE( code2 );
  688. *lpprev++ = LOBYTE( code2 );
  689. #endif
  690. }
  691. else if( code == MYTEXT('_') )
  692. {
  693. #if defined(FAKEIMEM) || defined(UNICODE)
  694. code2 = *lpprev;
  695. #else
  696. code2 = MAKEWORD( *(lpprev+1), *lpprev );
  697. #endif
  698. if( IsMaru( code2 ) == FALSE )
  699. goto DBCS_BETA2;
  700. code2 = ConvMaru( code2 );
  701. #if defined(FAKEIMEM) || defined(UNICODE)
  702. *lpprev = code2;
  703. #else
  704. if( HIBYTE( code2 ) )
  705. *lpprev++ = HIBYTE( code2 );
  706. *lpprev = LOBYTE( code2 );
  707. #endif
  708. }
  709. else
  710. {
  711. #if defined(FAKEIMEM) || defined(UNICODE)
  712. code = HanToZen(code,0,fdwConversion);
  713. #endif
  714. DBCS_BETA2:
  715. #if defined(FAKEIMEM) || defined(UNICODE)
  716. *lpstr++ = code;
  717. lpCompStr->dwCursorPos += 1;
  718. #else
  719. code2 = HanToZen( code,fdwConversion);
  720. if( HIBYTE( code2 ) )
  721. *lpstr++ = HIBYTE( code2 );
  722. *lpstr++ = LOBYTE( code2 );
  723. lpCompStr->dwCursorPos += 2;
  724. #endif
  725. }
  726. }
  727. }
  728. else
  729. {
  730. if (fdwConversion & IME_CMODE_ROMAN &&
  731. fdwConversion & IME_CMODE_NATIVE )
  732. {
  733. if (IsSecond( code ))
  734. {
  735. if (IsFirst( *lpprev ) &&
  736. (code2 = ConvChar(hIMC,*lpprev,code)))
  737. {
  738. #if defined(FAKEIMEM) || defined(UNICODE)
  739. if (OneCharZenToHan(code2,&Katakana, &Sound))
  740. {
  741. *lpprev = Katakana;
  742. if (Sound) {
  743. *lpstr++ = Sound;
  744. lpCompStr->dwCursorPos++;
  745. }
  746. }
  747. else
  748. {
  749. code = ConvChar(hIMC, 0, code );
  750. goto SBCS_BETA;
  751. }
  752. #else
  753. /* half size ' ' matching code */
  754. if (HIBYTE(code2))
  755. {
  756. *lpprev = HIBYTE( code2 );
  757. *lpstr++ = LOBYTE( code2 );
  758. lpCompStr->dwCursorPos++;
  759. }
  760. else
  761. *lpprev = (BYTE)code2;
  762. #endif
  763. }
  764. else
  765. {
  766. code = ConvChar(hIMC, 0, code );
  767. //MakeGuideLine(hIMC,MYGL_TYPINGERROR);
  768. goto SBCS_BETA;
  769. }
  770. }
  771. else
  772. {
  773. #if defined(FAKEIMEM) || defined(UNICODE)
  774. if( (WORD)(LONG_PTR)CharUpperW( (LPMYSTR)(LONG_PTR)code ) == 'N'
  775. && (WORD)(LONG_PTR)CharUpperW( (LPMYSTR)(LONG_PTR)(code2 = *lpprev ) ) == 'N' )
  776. {
  777. *lpprev = (MYCHAR) 0xFF9D;
  778. }
  779. #else
  780. if( (WORD)(LONG_PTR)AnsiUpper( (LPSTR)(LONG_PTR)code ) == 'N'
  781. && (WORD)(LONG_PTR)AnsiUpper((LPSTR)(LONG_PTR)(code2 = *lpprev ) ) == 'N' )
  782. *lpprev = (unsigned char)0xdd;
  783. #endif
  784. else
  785. {
  786. //MakeGuideLine(hIMC,MYGL_TYPINGERROR);
  787. goto SBCS_BETA;
  788. }
  789. }
  790. }
  791. else
  792. {
  793. SBCS_BETA:
  794. #if defined(FAKEIMEM) || defined(UNICODE)
  795. if (OneCharZenToHan(code,&Katakana,&Sound))
  796. {
  797. *lpstr++ = Katakana;
  798. if (Sound)
  799. {
  800. *lpstr++ = Sound;
  801. lpCompStr->dwCursorPos++;
  802. }
  803. }
  804. else
  805. {
  806. *lpstr++ = code;
  807. }
  808. #else
  809. *lpstr++ = (BYTE)code;
  810. #endif
  811. lpCompStr->dwCursorPos++;
  812. }
  813. }
  814. *lpstr = MYTEXT('\0');
  815. }
  816. // make reading string.
  817. lpstr = GETLPCOMPSTR(lpCompStr);
  818. lpread = GETLPCOMPREADSTR(lpCompStr);
  819. #if defined(FAKEIMEM) || defined(UNICODE)
  820. if (fdwConversion & IME_CMODE_KATAKANA)
  821. {
  822. if (fdwConversion & IME_CMODE_FULLSHAPE)
  823. {
  824. Mylstrcpy(lpread,lpstr);
  825. }
  826. else
  827. {
  828. lHanToZen(lpread,lpstr,fdwConversion);
  829. }
  830. }
  831. else
  832. {
  833. LPMYSTR pSrc = lpstr;
  834. LPMYSTR pDst = lpread;
  835. for (; *pSrc;) {
  836. *pDst++ = HiraToKata(*pSrc);
  837. pSrc++;
  838. }
  839. *pDst = (MYCHAR) 0;
  840. }
  841. #else
  842. lZenToHan (lpread,lpstr);
  843. #endif
  844. // make attribute
  845. lpCompStr->dwCursorPos = Mylstrlen(lpstr);
  846. lpCompStr->dwDeltaStart = (DWORD)(MyCharPrev(lpstr, lpstr+Mylstrlen(lpstr)) - lpstr);
  847. //MakeAttrClause(lpCompStr);
  848. lmemset((LPBYTE)GETLPCOMPATTR(lpCompStr),0, Mylstrlen(lpstr));
  849. lmemset((LPBYTE)GETLPCOMPREADATTR(lpCompStr),0, Mylstrlen(lpread));
  850. // make length
  851. lpCompStr->dwCompStrLen = Mylstrlen(lpstr);
  852. lpCompStr->dwCompReadStrLen = Mylstrlen(lpread);
  853. lpCompStr->dwCompAttrLen = Mylstrlen(lpstr);
  854. lpCompStr->dwCompReadAttrLen = Mylstrlen(lpread);
  855. //
  856. // make clause info
  857. //
  858. SetClause(GETLPCOMPCLAUSE(lpCompStr),Mylstrlen(lpstr));
  859. SetClause(GETLPCOMPREADCLAUSE(lpCompStr),Mylstrlen(lpread));
  860. lpCompStr->dwCompClauseLen = 8;
  861. lpCompStr->dwCompReadClauseLen = 8;
  862. GnMsg.message = WM_IME_COMPOSITION;
  863. GnMsg.wParam = 0;
  864. GnMsg.lParam = GCS_COMPALL | GCS_CURSORPOS | GCS_DELTASTART | dwGCR;
  865. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  866. ac_exit:
  867. ImmUnlockIMCC(lpIMC->hCompStr);
  868. ImmUnlockIMC(hIMC);
  869. }
  870. /**********************************************************************/
  871. /* */
  872. /* DicKeydownHandler() */
  873. /* */
  874. /* WM_KEYDOWN handler for dictionary routine */
  875. /* */
  876. /* wParam */
  877. /* virtual key */
  878. /* */
  879. /* lParam */
  880. /* differ depending on wParam */
  881. /* */
  882. /**********************************************************************/
  883. BOOL PASCAL DicKeydownHandler( hIMC, wParam, lParam ,lpbKeyState)
  884. HIMC hIMC;
  885. UINT wParam;
  886. LPARAM lParam;
  887. LPBYTE lpbKeyState;
  888. {
  889. LPINPUTCONTEXT lpIMC;
  890. switch( wParam )
  891. {
  892. case VK_ESCAPE:
  893. FlushText(hIMC);
  894. break;
  895. case VK_DELETE:
  896. case VK_BACK:
  897. DeleteChar(hIMC,wParam);
  898. break;
  899. case VK_SPACE:
  900. ConvKanji(hIMC);
  901. break;
  902. case VK_F3:
  903. if (IsCTLPushed(lpbKeyState))
  904. ChangeMode(hIMC,TO_CMODE_ROMAN);
  905. break;
  906. case VK_F6:
  907. if (IsCTLPushed(lpbKeyState))
  908. ChangeMode(hIMC,TO_CMODE_HIRAGANA);
  909. else
  910. ChangeCompStr(hIMC,TO_CMODE_HIRAGANA);
  911. break;
  912. case VK_F7:
  913. if (IsCTLPushed(lpbKeyState))
  914. ChangeMode(hIMC,TO_CMODE_KATAKANA);
  915. else
  916. ChangeCompStr(hIMC,TO_CMODE_KATAKANA);
  917. break;
  918. case VK_F8:
  919. if (IsCTLPushed(lpbKeyState))
  920. ChangeMode(hIMC,TO_CMODE_FULLSHAPE);
  921. else
  922. ChangeCompStr(hIMC,TO_CMODE_FULLSHAPE);
  923. break;
  924. case VK_F9:
  925. if (IsCTLPushed(lpbKeyState))
  926. ChangeMode(hIMC,TO_CMODE_ALPHANUMERIC);
  927. else
  928. ChangeCompStr(hIMC,TO_CMODE_ALPHANUMERIC);
  929. break;
  930. case VK_RETURN:
  931. lpIMC = ImmLockIMC(hIMC);
  932. if( !( lpIMC->fdwConversion & IME_CMODE_CHARCODE ) )
  933. MakeResultString(hIMC,TRUE);
  934. else
  935. FlushText(hIMC);
  936. ImmUnlockIMC(hIMC);
  937. break;
  938. case VK_G:
  939. #ifdef DEBUG
  940. if (dwDebugFlag & DEBF_GUIDELINE)
  941. {
  942. if (IsCTLPushed(lpbKeyState))
  943. {
  944. MakeGuideLine(hIMC,MYGL_TESTGUIDELINE);
  945. return( TRUE );
  946. }
  947. }
  948. #endif
  949. break;
  950. default:
  951. break;
  952. }
  953. if (( VK_0 <= wParam && VK_9 >= wParam ) ||
  954. ( VK_A <= wParam && VK_Z >= wParam ) ||
  955. ( VK_NUMPAD0 <= wParam && VK_NUMPAD9 >= wParam ) ||
  956. ( VK_OEM_1 <= wParam && VK_OEM_9 >= wParam ) ||
  957. ( VK_MULTIPLY <= wParam && VK_DIVIDE >= wParam ))
  958. {
  959. return( FALSE );
  960. }
  961. else
  962. return( TRUE );
  963. }
  964. /**********************************************************************/
  965. /* */
  966. /* Entry : MakeResultString( HIMC) */
  967. /* */
  968. /**********************************************************************/
  969. BOOL WINAPI MakeResultString( HIMC hIMC, BOOL fFlag)
  970. {
  971. TRANSMSG GnMsg;
  972. LPCOMPOSITIONSTRING lpCompStr;
  973. LPCANDIDATEINFO lpCandInfo;
  974. LPINPUTCONTEXT lpIMC;
  975. if (!IsCompStr(hIMC))
  976. return FALSE;
  977. lpIMC = ImmLockIMC(hIMC);
  978. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  979. if (IsCandidate(lpIMC))
  980. {
  981. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  982. ClearCandidate(lpCandInfo);
  983. ImmUnlockIMCC(lpIMC->hCandInfo);
  984. GnMsg.message = WM_IME_NOTIFY;
  985. GnMsg.wParam = IMN_CLOSECANDIDATE;
  986. GnMsg.lParam = 1L;
  987. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  988. }
  989. Mylstrcpy(GETLPRESULTSTR(lpCompStr),GETLPCOMPSTR(lpCompStr));
  990. Mylstrcpy(GETLPRESULTREADSTR(lpCompStr),GETLPCOMPREADSTR(lpCompStr));
  991. lpCompStr->dwResultStrLen = lpCompStr->dwCompStrLen;
  992. lpCompStr->dwResultReadStrLen = lpCompStr->dwCompReadStrLen;
  993. lpCompStr->dwCompStrLen = 0;
  994. lpCompStr->dwCompReadStrLen = 0;
  995. //
  996. // make clause info
  997. //
  998. SetClause(GETLPRESULTCLAUSE(lpCompStr),Mylstrlen(GETLPRESULTSTR(lpCompStr)));
  999. SetClause(GETLPRESULTREADCLAUSE(lpCompStr),Mylstrlen(GETLPRESULTREADSTR(lpCompStr)));
  1000. lpCompStr->dwResultClauseLen = 8;
  1001. lpCompStr->dwResultReadClauseLen = 8;
  1002. ImmUnlockIMCC(lpIMC->hCompStr);
  1003. if (fFlag)
  1004. {
  1005. GnMsg.message = WM_IME_COMPOSITION;
  1006. GnMsg.wParam = 0;
  1007. GnMsg.lParam = GCS_RESULTALL;
  1008. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  1009. GnMsg.message = WM_IME_ENDCOMPOSITION;
  1010. GnMsg.wParam = 0;
  1011. GnMsg.lParam = 0;
  1012. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  1013. }
  1014. ImmUnlockIMC(hIMC);
  1015. return TRUE;
  1016. }
  1017. /**********************************************************************/
  1018. /* */
  1019. /* MakeGuideLine() */
  1020. /* */
  1021. /* Update the transrate key buffer. */
  1022. /* */
  1023. /**********************************************************************/
  1024. BOOL PASCAL MakeGuideLine(HIMC hIMC, DWORD dwID)
  1025. {
  1026. LPINPUTCONTEXT lpIMC;
  1027. LPGUIDELINE lpGuideLine;
  1028. TRANSMSG GnMsg;
  1029. DWORD dwSize = sizeof(GUIDELINE) + (MAXGLCHAR + sizeof(MYCHAR)) * 2 * sizeof(MYCHAR);
  1030. LPMYSTR lpStr;
  1031. #ifdef FAKEIMEM
  1032. char szBuf[MAXGLCHAR+1];
  1033. #endif
  1034. lpIMC = ImmLockIMC(hIMC);
  1035. lpIMC->hGuideLine = ImmReSizeIMCC(lpIMC->hGuideLine,dwSize);
  1036. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  1037. lpGuideLine->dwSize = dwSize;
  1038. lpGuideLine->dwLevel = glTable[dwID].dwLevel;
  1039. lpGuideLine->dwIndex = glTable[dwID].dwIndex;
  1040. lpGuideLine->dwStrOffset = sizeof(GUIDELINE);
  1041. lpStr = (LPMYSTR)(((LPSTR)lpGuideLine) + lpGuideLine->dwStrOffset);
  1042. #ifdef FAKEIMEM
  1043. LoadString(hInst, glTable[dwID].dwStrID, szBuf, MAXGLCHAR);
  1044. MultiByteToWideChar(CP_ACP, 0, szBuf, -1, lpStr, MAXGLCHAR);
  1045. #else
  1046. LoadString(hInst,glTable[dwID].dwStrID,lpStr, MAXGLCHAR);
  1047. #endif
  1048. lpGuideLine->dwStrLen = Mylstrlen(lpStr);
  1049. if (glTable[dwID].dwPrivateID)
  1050. {
  1051. lpGuideLine->dwPrivateOffset = sizeof(GUIDELINE) + (MAXGLCHAR + 1) * sizeof(MYCHAR);
  1052. lpStr = (LPMYSTR)(((LPSTR)lpGuideLine) + lpGuideLine->dwPrivateOffset);
  1053. #ifdef FAKEIMEM
  1054. LoadString(hInst, glTable[dwID].dwStrID, szBuf, MAXGLCHAR);
  1055. MultiByteToWideChar(CP_ACP, 0, szBuf, -1, lpStr, MAXGLCHAR);
  1056. #else
  1057. LoadString(hInst,glTable[dwID].dwStrID,lpStr, MAXGLCHAR);
  1058. #endif
  1059. lpGuideLine->dwPrivateSize = Mylstrlen(lpStr) * sizeof(MYCHAR);
  1060. }
  1061. else
  1062. {
  1063. lpGuideLine->dwPrivateOffset = 0L;
  1064. lpGuideLine->dwPrivateSize = 0L;
  1065. }
  1066. GnMsg.message = WM_IME_NOTIFY;
  1067. GnMsg.wParam = IMN_GUIDELINE;
  1068. GnMsg.lParam = 0;
  1069. GenerateMessage(hIMC, lpIMC, lpCurTransKey,(LPTRANSMSG)&GnMsg);
  1070. ImmUnlockIMCC(lpIMC->hGuideLine);
  1071. ImmUnlockIMC(hIMC);
  1072. return TRUE;
  1073. }
  1074. /**********************************************************************/
  1075. /* */
  1076. /* GenerateMessage() */
  1077. /* */
  1078. /* Update the transrate key buffer. */
  1079. /* */
  1080. /**********************************************************************/
  1081. BOOL PASCAL GenerateMessage(HIMC hIMC, LPINPUTCONTEXT lpIMC, LPTRANSMSGLIST lpTransBuf,LPTRANSMSG lpGeneMsg)
  1082. {
  1083. if (lpTransBuf)
  1084. return GenerateMessageToTransKey(lpTransBuf,lpGeneMsg);
  1085. if (IsWindow(lpIMC->hWnd))
  1086. {
  1087. LPTRANSMSG lpTransMsg;
  1088. if (!(lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf,
  1089. sizeof(TRANSMSG) * (lpIMC->dwNumMsgBuf +1))))
  1090. return FALSE;
  1091. if (!(lpTransMsg = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf)))
  1092. return FALSE;
  1093. lpTransMsg[lpIMC->dwNumMsgBuf] = *lpGeneMsg;
  1094. ImmUnlockIMCC(lpIMC->hMsgBuf);
  1095. lpIMC->dwNumMsgBuf++;
  1096. ImmGenerateMessage(hIMC);
  1097. }
  1098. return TRUE;
  1099. }
  1100. /**********************************************************************/
  1101. /* */
  1102. /* Entry : CheckAttr( LPCOMPOSITIONSTRING) */
  1103. /* */
  1104. /**********************************************************************/
  1105. BOOL PASCAL CheckAttr( LPCOMPOSITIONSTRING lpCompStr)
  1106. {
  1107. int i,len;
  1108. LPBYTE lpb = GETLPCOMPATTR(lpCompStr);
  1109. len = lpCompStr->dwCompAttrLen;
  1110. for (i = 0; i < len; i++)
  1111. if (*lpb++ & 0x01)
  1112. return TRUE;
  1113. return FALSE;
  1114. }
  1115. /**********************************************************************/
  1116. /* */
  1117. /* Entry : MakeAttrClause( LPCOMPOSITIONSTRING) */
  1118. /* */
  1119. /**********************************************************************/
  1120. void PASCAL MakeAttrClause( LPCOMPOSITIONSTRING lpCompStr)
  1121. {
  1122. int len = lpCompStr->dwCompAttrLen;
  1123. int readlen = lpCompStr->dwCompReadAttrLen;
  1124. LPDWORD lpdw;
  1125. LPBYTE lpb;
  1126. DWORD dwCursorPos = lpCompStr->dwCursorPos;
  1127. int i;
  1128. if (len != readlen)
  1129. return;
  1130. lpb = GETLPCOMPATTR(lpCompStr);
  1131. for (i = 0;i < len; i++)
  1132. {
  1133. if ((DWORD)i < dwCursorPos)
  1134. *lpb++ = 0x10;
  1135. else
  1136. *lpb++ = 0x00;
  1137. }
  1138. lpb = GETLPCOMPREADATTR(lpCompStr);
  1139. for (i = 0;i < readlen; i++)
  1140. {
  1141. if ((DWORD)i < dwCursorPos)
  1142. *lpb++ = 0x10;
  1143. else
  1144. *lpb++ = 0x00;
  1145. }
  1146. lpdw = GETLPCOMPCLAUSE(lpCompStr);
  1147. *lpdw++ = 0;
  1148. *lpdw++ = (BYTE)dwCursorPos;
  1149. *lpdw++ = len;
  1150. lpdw = GETLPCOMPREADCLAUSE(lpCompStr);
  1151. *lpdw++ = 0;
  1152. *lpdw++ = (BYTE)dwCursorPos;
  1153. *lpdw++ = len;
  1154. }
  1155. /**********************************************************************/
  1156. /* */
  1157. /* Entry : HandleShiftArrow( HIMC, fArrow) */
  1158. /* */
  1159. /**********************************************************************/
  1160. void PASCAL HandleShiftArrow( HIMC hIMC, BOOL fArrow)
  1161. {
  1162. LPINPUTCONTEXT lpIMC;
  1163. LPCOMPOSITIONSTRING lpCompStr;
  1164. DWORD dwStartClause = 0;
  1165. DWORD dwEndClause = 0;
  1166. LPMYSTR lpstart,lpstr,lpend;
  1167. if (!(lpIMC = ImmLockIMC(hIMC)))
  1168. return;
  1169. if (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr))
  1170. {
  1171. // Temp! Error, if the string is already converted.
  1172. if (CheckAttr(lpCompStr))
  1173. goto hsa_exit;
  1174. lpstart = GETLPCOMPSTR(lpCompStr);
  1175. lpstr = lpstart + lpCompStr->dwCursorPos;
  1176. lpend = lpstart + Mylstrlen(lpstart);
  1177. if (fArrow == ARR_RIGHT)
  1178. {
  1179. if (lpstr < lpend)
  1180. lpstr = MyCharNext(lpstr);
  1181. }
  1182. else
  1183. {
  1184. if (lpstr > lpstart)
  1185. lpstr = MyCharPrev(lpstart,lpstr);
  1186. }
  1187. lpCompStr->dwCursorPos = (DWORD)(lpstr - lpstart);
  1188. MakeAttrClause(lpCompStr);
  1189. }
  1190. hsa_exit:
  1191. ImmUnlockIMCC(lpIMC->hCompStr);
  1192. ImmUnlockIMC(hIMC);
  1193. }
  1194. #if defined(FAKEIMEM) || defined(UNICODE)
  1195. int CopyCandidateStringsFromDictionary(LPMYSTR lpDic, LPMYSTR lpRead, LPMYSTR lpBuf, DWORD dwBufLen)
  1196. {
  1197. DWORD dwWritten = 0;
  1198. LPMYSTR lpSection, lpTemp;
  1199. const LPMYSTR szSep = MYTEXT(" \r\n\t");
  1200. LPMYSTR lpToken = Mystrtok(lpDic, szSep);
  1201. while (NULL != lpToken)
  1202. {
  1203. if (MYTEXT('[') == *lpToken)
  1204. {
  1205. lpSection = lpToken + 1;
  1206. if (NULL != (lpTemp = Mystrchr(lpSection, MYTEXT(']'))))
  1207. *lpTemp = MYTEXT('\0');
  1208. if (0 == Mylstrcmp(lpSection, lpRead))
  1209. {
  1210. lpToken = Mystrtok(NULL, szSep);
  1211. break; // found it.
  1212. }
  1213. }
  1214. lpToken = Mystrtok(NULL, szSep);
  1215. }
  1216. if (NULL != lpToken)
  1217. {
  1218. LPMYSTR lpWrite = lpBuf;
  1219. DWORD dwW;
  1220. while ((NULL != lpToken) &&
  1221. ((dwBufLen - dwWritten) > 1) &&
  1222. (MYTEXT('[') != *lpToken))
  1223. {
  1224. if (NULL != (lpTemp = Mystrchr(lpToken, MYTEXT('='))))
  1225. *lpTemp = MYTEXT('\0');
  1226. Mylstrcpyn(lpWrite, lpToken, dwBufLen - dwWritten - 1);
  1227. dwW = Mylstrlen(lpToken) + 1;
  1228. lpWrite += dwW;
  1229. dwWritten += dwW;
  1230. lpToken = Mystrtok(NULL, szSep);
  1231. }
  1232. *lpWrite = MYTEXT('\0');
  1233. dwWritten++;
  1234. return dwWritten;
  1235. }
  1236. return 0;
  1237. }
  1238. int GetCandidateStringsFromDictionary(LPMYSTR lpRead, LPMYSTR lpBuf, DWORD dwBufLen, LPTSTR lpFilename)
  1239. {
  1240. HANDLE hTblFile;
  1241. PSECURITY_ATTRIBUTES psa;
  1242. int nSize = 0;
  1243. DWORD dwFileSize, dwRead;
  1244. LPMYSTR lpDic;
  1245. psa = CreateSecurityAttributes();
  1246. hTblFile = CreateFile(lpFilename,
  1247. GENERIC_READ,
  1248. FILE_SHARE_READ,
  1249. NULL,
  1250. OPEN_EXISTING,
  1251. FILE_ATTRIBUTE_NORMAL,
  1252. (HANDLE)NULL);
  1253. if (hTblFile == INVALID_HANDLE_VALUE) {
  1254. goto Err0;
  1255. }
  1256. if (dwBufLen > 2)
  1257. {
  1258. if ((dwFileSize = GetFileSize(hTblFile, (LPDWORD)NULL)) != 0xffffffff)
  1259. {
  1260. if ((lpDic = (LPMYSTR)GlobalAlloc(GPTR, dwFileSize + 2)))
  1261. {
  1262. if (ReadFile(hTblFile, lpDic, dwFileSize, &dwRead, NULL))
  1263. {
  1264. if (*lpDic == 0xfeff)
  1265. {
  1266. *(LPWSTR)(((LPBYTE)lpDic) + dwFileSize) = MYTEXT('\0');
  1267. nSize = CopyCandidateStringsFromDictionary(lpDic+1, lpRead, lpBuf, dwBufLen);
  1268. }
  1269. }
  1270. GlobalFree(lpDic);
  1271. }
  1272. }
  1273. }
  1274. CloseHandle(hTblFile);
  1275. Err0:
  1276. FreeSecurityAttributes(psa);
  1277. return nSize;
  1278. }
  1279. #endif