Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1421 lines
51 KiB

  1. /******************************************************************************
  2. *
  3. * File Name: main.c
  4. *
  5. * - Interface entry of IME for Windows 95-H.
  6. *
  7. * Author: Beomseok Oh (BeomOh)
  8. *
  9. * Copyright (C) Microsoft Corp 1993-1994. All rights reserved.
  10. *
  11. ******************************************************************************/
  12. // include files
  13. #include "precomp.h"
  14. // local definitions
  15. #define IME_SETOPEN 0x04
  16. #define IME_GETOPEN 0x05
  17. #define IME_MOVEIMEWINDOW 0x08
  18. #define IME_AUTOMATA 0x30
  19. #define IME_HANJAMODE 0x31
  20. #define MAX_PAGES 4
  21. // public data
  22. HINSTANCE hInst;
  23. int iTotalNumMsg;
  24. DWORD gdwSystemInfoFlags = 0;
  25. #ifdef DEBUG
  26. #pragma data_seg("SHAREDDATA")
  27. BOOL fFuncLog = FALSE; // Enable FUNCTIONLOG output forcely.
  28. #pragma data_seg()
  29. #endif // DEBUG
  30. BOOL LibMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
  31. {
  32. BOOL fRet = TRUE;
  33. FUNCTIONLOG("LibMain");
  34. hInst = hinstDLL;
  35. switch (fdwReason)
  36. {
  37. case DLL_PROCESS_ATTACH:
  38. fRet = RegisterUIClass(hInst);
  39. InitializeResource(hInst);
  40. MyDebugOut(MDB_LOG, "ProcessAttach:hinstDLL = 0x%08lX", hinstDLL);
  41. #ifdef LATER
  42. // #58993 MSInfo32.exe is dead-locked by calling RegCreateKey.
  43. {
  44. HKEY hKey;
  45. DWORD dwBuf, dwCb;
  46. if (RegCreateKey(HKEY_CURRENT_USER, szIMEKey, &hKey) == ERROR_SUCCESS)
  47. {
  48. dwCb = sizeof(dwBuf);
  49. if (RegQueryValueEx(hKey, szUseXW, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
  50. != ERROR_SUCCESS) {
  51. dwCb = sizeof(dwBuf);
  52. dwBuf = 1;
  53. RegSetValueEx(hKey, szUseXW, 0, REG_DWORD, (LPBYTE)&dwBuf, dwCb);
  54. }
  55. }
  56. RegCloseKey(hKey);
  57. }
  58. #endif
  59. break;
  60. case DLL_THREAD_ATTACH:
  61. break;
  62. case DLL_PROCESS_DETACH:
  63. fRet = UnregisterUIClass(hInst);
  64. MyDebugOut(MDB_LOG, "ProcessDetach:hinstDLL = 0x%08lX", hinstDLL);
  65. break;
  66. case DLL_THREAD_DETACH:
  67. break;
  68. }
  69. #if 0 // BUGBUG:
  70. return fRet;
  71. #else
  72. return TRUE;
  73. #endif
  74. UNREFERENCED_PARAMETER(lpvReserved);
  75. }
  76. DWORD WINAPI ImeConversionList(HIMC hIMC, LPCTSTR lpSource, LPCANDIDATELIST lpDest,
  77. DWORD dwBufLen, UINT uFlag)
  78. {
  79. WANSUNG wsChar;
  80. int iMapCandStr;
  81. DWORD i, iIndexOfCandStr, iNumOfCandStr;
  82. LPSTR lpCandStr;
  83. DWORD dwRet;
  84. FUNCTIONLOG("ImeConversionList");
  85. switch (uFlag)
  86. {
  87. case GCL_CONVERSION:
  88. if (IsDBCSLeadByte((BYTE)*lpSource))
  89. {
  90. wsChar.e.high = (BYTE)*lpSource;
  91. wsChar.e.low = (BYTE)*(lpSource + 1);
  92. if ((iMapCandStr = SearchHanjaIndex(wsChar.w)) < 0)
  93. dwRet = 0;
  94. else
  95. {
  96. iIndexOfCandStr = wHanjaIndex[iMapCandStr];
  97. iNumOfCandStr = wHanjaIndex[iMapCandStr + 1] - iIndexOfCandStr - 1;
  98. if (dwBufLen)
  99. {
  100. lpDest->dwSize = sizeof(CANDIDATELIST) + sizeof(DWORD)
  101. * (iNumOfCandStr-1) + iNumOfCandStr*3;
  102. lpDest->dwStyle = IME_CAND_READ;
  103. lpDest->dwCount = iNumOfCandStr;
  104. lpDest->dwPageStart = lpDest->dwSelection = 0;
  105. lpDest->dwPageSize = 9;
  106. for (i = 0; i < iNumOfCandStr; i++)
  107. {
  108. lpDest->dwOffset[i] = sizeof(CANDIDATELIST)
  109. + sizeof(DWORD) * (iNumOfCandStr-1) + i*3;
  110. lpCandStr = (LPSTR)lpDest + lpDest->dwOffset[i];
  111. *lpCandStr++ = (BYTE)HIBYTE(wHanja[iIndexOfCandStr + i]);
  112. *lpCandStr++ = (BYTE)LOBYTE(wHanja[iIndexOfCandStr + i]);
  113. *lpCandStr++ = '\0';
  114. }
  115. }
  116. dwRet = sizeof(CANDIDATELIST) + sizeof(DWORD) * (iNumOfCandStr-1)
  117. + iNumOfCandStr*3;
  118. }
  119. }
  120. else
  121. dwRet = 0;
  122. break;
  123. // BUGBUG: Not implemented yet...
  124. case GCL_REVERSECONVERSION:
  125. default:
  126. dwRet = 0;
  127. }
  128. return dwRet;
  129. UNREFERENCED_PARAMETER(hIMC);
  130. UNREFERENCED_PARAMETER(lpSource);
  131. UNREFERENCED_PARAMETER(lpDest);
  132. UNREFERENCED_PARAMETER(dwBufLen);
  133. UNREFERENCED_PARAMETER(uFlag);
  134. }
  135. BOOL WINAPI ImeConfigure(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData)
  136. {
  137. HPROPSHEETPAGE rPages[MAX_PAGES];
  138. PROPSHEETHEADER psh;
  139. BOOL fRet = FALSE;
  140. FUNCTIONLOG("ImeConfigure");
  141. psh.dwSize = sizeof(psh);
  142. psh.dwFlags = PSH_PROPTITLE;
  143. psh.hwndParent = hWnd;
  144. psh.hInstance = hInst;
  145. psh.pszCaption = MAKEINTRESOURCE(IDS_PROGRAM);
  146. psh.nPages = 0;
  147. psh.nStartPage = 0;
  148. psh.phpage = rPages;
  149. switch (dwMode)
  150. {
  151. case IME_CONFIG_GENERAL:
  152. AddPage(&psh, DLG_GENERAL, GeneralDlgProc);
  153. if (PropertySheet(&psh) != -1)
  154. fRet = TRUE;
  155. break;
  156. default:
  157. break;
  158. }
  159. return fRet;
  160. UNREFERENCED_PARAMETER(hKL);
  161. UNREFERENCED_PARAMETER(lpData);
  162. }
  163. BOOL WINAPI ImeDestroy(UINT uReserved)
  164. {
  165. FUNCTIONLOG("ImeDestroy");
  166. // Remove resources
  167. DeleteObject(hBMClient);
  168. DeleteObject(hBMEng);
  169. DeleteObject(hBMHan);
  170. DeleteObject(hBMBan);
  171. DeleteObject(hBMJun);
  172. DeleteObject(hBMChi[0]);
  173. DeleteObject(hBMChi[1]);
  174. DeleteObject(hBMComp);
  175. DeleteObject(hBMCand);
  176. DeleteObject(hBMCandNum);
  177. DeleteObject(hBMCandArr[0]);
  178. DeleteObject(hBMCandArr[1]);
  179. DeleteObject(hIMECursor);
  180. DeleteObject(hFontFix);
  181. return TRUE;
  182. UNREFERENCED_PARAMETER(uReserved);
  183. }
  184. LRESULT WINAPI ImeEscape(HIMC hIMC, UINT uSubFunc, LPVOID lpData)
  185. {
  186. LPINPUTCONTEXT lpIMC;
  187. LRESULT lRet;
  188. FUNCTIONLOG("ImeEscape");
  189. switch (uSubFunc)
  190. {
  191. case IME_ESC_AUTOMATA:
  192. lRet = EscAutomata(hIMC, lpData, TRUE);
  193. break;
  194. case IME_AUTOMATA:
  195. lRet = EscAutomata(hIMC, lpData, FALSE);
  196. break;
  197. case IME_GETOPEN:
  198. lRet = EscGetOpen(hIMC, lpData);
  199. break;
  200. case IME_ESC_HANJA_MODE:
  201. if ((lRet = EscHanjaMode(hIMC, lpData, TRUE)) != FALSE
  202. && (lpIMC = ImmLockIMC(hIMC)) != NULL)
  203. {
  204. SendMessage(lpIMC->hWnd, WM_IME_NOTIFY, IMN_OPENCANDIDATE, 1L);
  205. ImmUnlockIMC(hIMC);
  206. }
  207. break;
  208. case IME_HANJAMODE:
  209. lRet = EscHanjaMode(hIMC, lpData, FALSE);
  210. break;
  211. case IME_SETOPEN:
  212. lRet = EscSetOpen(hIMC, lpData);
  213. break;
  214. case IME_MOVEIMEWINDOW:
  215. lRet = EscMoveIMEWindow(hIMC, lpData);
  216. break;
  217. default:
  218. MyDebugOut(MDB_ERROR, "Unknown ImeEscape() subfunc(#0x%Xl) is called.", uSubFunc);
  219. break;
  220. }
  221. return lRet;
  222. }
  223. BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo, LPTSTR lpszClassName, DWORD dwSystemInfoFlags)
  224. {
  225. BOOL fRet = FALSE;
  226. FUNCTIONLOG("ImeInqure");
  227. gdwSystemInfoFlags = dwSystemInfoFlags;
  228. if (lpIMEInfo)
  229. {
  230. lpIMEInfo->dwPrivateDataSize = sizeof(DWORD);
  231. lpIMEInfo->fdwProperty = IME_PROP_AT_CARET | IME_PROP_NEED_ALTKEY;
  232. #ifdef UNICODE
  233. lpIMEInfo->fdwProperty |= IME_PROP_UNICODE;
  234. #endif
  235. lpIMEInfo->fdwConversionCaps = IME_CMODE_NATIVE
  236. | IME_CMODE_FULLSHAPE | IME_CMODE_HANJACONVERT;
  237. lpIMEInfo->fdwSentenceCaps = 0;
  238. lpIMEInfo->fdwUICaps = 0;
  239. lpIMEInfo->fdwSCSCaps = SCS_CAP_COMPSTR;
  240. lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
  241. lstrcpy(lpszClassName, szUIClassName);
  242. fRet = TRUE;
  243. }
  244. else
  245. {
  246. MyDebugOut(MDB_ERROR, "ImeInquire() returns FALSE.");
  247. }
  248. return fRet;
  249. }
  250. BOOL WINAPI ImeProcessKey(HIMC hIMC, UINT uVKey, LPARAM lKeyData, CONST LPBYTE lpbKeyState)
  251. {
  252. LPINPUTCONTEXT lpIMC;
  253. LPCOMPOSITIONSTRING lpCompStr;
  254. BYTE bCode;
  255. register int i;
  256. BOOL fRet = FALSE;
  257. FUNCTIONLOG("ImeProcessKey");
  258. MyDebugOut(MDB_LOG, "hIMC = 0x%08lX, uVKey = 0x%04X", hIMC, uVKey);
  259. if (uVKey == VK_PROCESSKEY)
  260. return TRUE;
  261. if (hIMC && !(lKeyData & ((LPARAM)KF_UP << 16)) && uVKey != VK_SHIFT
  262. && uVKey != VK_CONTROL && (lpIMC = ImmLockIMC(hIMC)))
  263. {
  264. if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)
  265. {
  266. fRet = TRUE;
  267. }
  268. else if (uVKey == VK_HANGEUL || uVKey == VK_JUNJA || uVKey == VK_HANJA)
  269. {
  270. fRet = TRUE;
  271. }
  272. else if (lpIMC->fOpen)
  273. {
  274. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  275. if (lpCompStr && lpCompStr->dwCompStrLen)
  276. {
  277. if (uVKey == VK_MENU)
  278. MakeFinalMsgBuf(hIMC, 0);
  279. else
  280. fRet = TRUE;
  281. }
  282. else
  283. {
  284. if (lpIMC->fdwConversion & IME_CMODE_HANGEUL)
  285. {
  286. i = (lpbKeyState[VK_SHIFT] & 0x80)? 1: 0;
  287. bCode = bHTable[uCurrentInputMethod - IDD_2BEOL][uVKey][i];
  288. if ((bCode && i != 0 && uCurrentInputMethod != IDD_2BEOL) ||
  289. (bCode > 0x80U && !(lpbKeyState[VK_CONTROL] & 0x80)
  290. && !(lpbKeyState[VK_MENU] & 0x80)))
  291. fRet = TRUE;
  292. }
  293. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)
  294. {
  295. i = (lpbKeyState[VK_SHIFT] & 0x80)? 3: 2;
  296. bCode = bHTable[uCurrentInputMethod - IDD_2BEOL][uVKey][i];
  297. if (bCode && !(lpbKeyState[VK_CONTROL] & 0x80)
  298. && !(lpbKeyState[VK_MENU] & 0x80))
  299. fRet = TRUE;
  300. }
  301. }
  302. ImmUnlockIMCC(lpIMC->hCompStr);
  303. }
  304. ImmUnlockIMC(hIMC);
  305. }
  306. return fRet;
  307. }
  308. #ifdef XWANSUNG_IME
  309. LPTSTR PathFindFileName(LPCSTR pPath)
  310. {
  311. LPCSTR pT;
  312. for (pT = pPath; *pPath; pPath = AnsiNext(pPath)) {
  313. if ((pPath[0] == '\\' || pPath[0] == ':') && pPath[1] && (pPath[1] != '\\'))
  314. pT = pPath + 1;
  315. }
  316. return (LPTSTR)pT;
  317. }
  318. #endif
  319. BOOL WINAPI ImeSelect(HIMC hIMC, BOOL fSelect)
  320. {
  321. HKEY hKey;
  322. DWORD dwBuf, dwCb;
  323. LPINPUTCONTEXT lpIMC;
  324. LPCOMPOSITIONSTRING lpCompStr;
  325. LPCANDIDATEINFO lpCandInfo;
  326. LPCANDIDATELIST lpCandList;
  327. #ifdef XWANSUNG_IME
  328. LPDWORD lpdw;
  329. TCHAR szModuleName[MAX_PATH];
  330. BOOL fUseXW = FALSE;
  331. #endif
  332. BOOL fRet = FALSE;
  333. FUNCTIONLOG("ImeSelect");
  334. MyDebugOut(MDB_LOG, "hIMC = 0x%08lX, fSelect = %s", hIMC, (fSelect)? "TRUE": "FALSE");
  335. if (hIMC && fSelect && (lpIMC = ImmLockIMC(hIMC)))
  336. {
  337. // Initialize Input Method variables from Registry.
  338. if (RegOpenKey(HKEY_CURRENT_USER, szIMEKey, &hKey) == ERROR_SUCCESS)
  339. {
  340. dwCb = sizeof(dwBuf);
  341. if (RegQueryValueEx(hKey, szInputMethod, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
  342. == ERROR_SUCCESS)
  343. uCurrentInputMethod = dwBuf;
  344. dwCb = sizeof(dwBuf);
  345. if (RegQueryValueEx(hKey, szCompDel, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
  346. == ERROR_SUCCESS)
  347. fCurrentCompDel = dwBuf;
  348. #ifdef XWANSUNG_IME
  349. if (lpIMC->hPrivate && (lpdw = (LPDWORD)ImmLockIMCC(lpIMC->hPrivate)))
  350. {
  351. dwCb = sizeof(dwBuf);
  352. if (RegQueryValueEx(hKey, szUseXW, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
  353. == ERROR_SUCCESS)
  354. fUseXW = dwBuf;
  355. GetModuleFileName(NULL, szModuleName, sizeof(szModuleName));
  356. *lpdw = GetProfileInt(szUseXW, PathFindFileName((LPCSTR)szModuleName), fUseXW);
  357. fCurrentUseXW = (*lpdw) ? TRUE: FALSE;
  358. ImmUnlockIMCC(lpIMC->hPrivate);
  359. }
  360. #endif
  361. RegCloseKey(hKey);
  362. }
  363. if (!(lpIMC->fdwInit & INIT_CONVERSION))
  364. {
  365. lpIMC->fOpen = FALSE;
  366. lpIMC->fdwConversion = IME_CMODE_ALPHANUMERIC; // Set initial conversion mode.
  367. lpIMC->fdwInit |= INIT_CONVERSION;
  368. }
  369. if (!(lpIMC->fdwInit & INIT_LOGFONT))
  370. {
  371. GetObject(hFontFix, sizeof(LOGFONT), &lpIMC->lfFont.A);
  372. lpIMC->fdwInit |= INIT_LOGFONT;
  373. }
  374. if (!(lpIMC->fdwInit & INIT_STATUSWNDPOS))
  375. {
  376. lpIMC->ptStatusWndPos = ptState;
  377. lpIMC->fdwInit |= INIT_STATUSWNDPOS;
  378. }
  379. if (!(lpIMC->fdwInit & INIT_COMPFORM))
  380. {
  381. lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
  382. lpIMC->cfCompForm.ptCurrentPos = ptComp;
  383. lpIMC->fdwInit |= INIT_COMPFORM;
  384. }
  385. if (lpIMC->hCandInfo)
  386. lpIMC->hCandInfo = ImmReSizeIMCC(lpIMC->hCandInfo, sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST));
  387. else
  388. lpIMC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST));
  389. if (lpIMC->hCandInfo && (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo)))
  390. {
  391. lpCandInfo->dwSize = sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST);
  392. lpCandInfo->dwCount = 1;
  393. lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
  394. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + sizeof(CANDIDATEINFO));
  395. lpCandList->dwSize = sizeof(CANDIDATELIST);
  396. lpCandList->dwStyle = IME_CAND_READ;
  397. lpCandList->dwCount = 0;
  398. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  399. lpCandList->dwPageSize = 9;
  400. ImmUnlockIMCC(lpIMC->hCandInfo);
  401. }
  402. if (lpIMC->hCompStr)
  403. lpIMC->hCompStr = ImmReSizeIMCC(lpIMC->hCompStr, sizeof(COMPOSITIONSTRING) + 16*3);
  404. else
  405. lpIMC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING) + 16*3);
  406. if (lpIMC->hCompStr && (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr)))
  407. {
  408. lpCompStr->dwSize = sizeof(COMPOSITIONSTRING) + 16*3;
  409. lpCompStr->dwCompStrOffset = sizeof(COMPOSITIONSTRING);
  410. lpCompStr->dwResultStrOffset = sizeof(COMPOSITIONSTRING) + 16;
  411. lpCompStr->dwCompAttrOffset = sizeof(COMPOSITIONSTRING) + 32; // Attrib. str size = 2 bytes
  412. lpCompStr->dwCompStrLen = lpCompStr->dwResultStrLen = lpCompStr->dwCompAttrLen = 0;
  413. ImmUnlockIMCC(lpIMC->hCompStr);
  414. fRet = TRUE;
  415. }
  416. ImmUnlockIMC(hIMC);
  417. }
  418. return fRet;
  419. }
  420. BOOL WINAPI ImeSetActiveContext(HIMC hIMC, BOOL fActive)
  421. {
  422. LPINPUTCONTEXT lpIMC;
  423. LPCOMPOSITIONSTRING lpCompStr;
  424. #ifdef XWANSUNG_IME
  425. LPDWORD lpdw;
  426. #endif
  427. BOOL fRet = FALSE;
  428. FUNCTIONLOG("ImeSetActiveContext");
  429. MyDebugOut(MDB_LOG, "hIMC = 0x%08lX, fActive = %s", hIMC, (fActive)? "TRUE": "FALSE");
  430. if (hIMC && fActive)
  431. {
  432. if (lpIMC = ImmLockIMC(hIMC))
  433. {
  434. #ifdef XWANSUNG_IME
  435. if (lpdw = (LPDWORD)ImmLockIMCC(lpIMC->hPrivate))
  436. {
  437. fCurrentUseXW = (*lpdw)? TRUE: FALSE;
  438. ImmUnlockIMCC(lpIMC->hPrivate);
  439. }
  440. else
  441. fCurrentUseXW = FALSE;
  442. #endif
  443. if (lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr))
  444. {
  445. if (lpCompStr->dwCompStrLen)
  446. {
  447. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0;
  448. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0;
  449. WansungChar.e.high = *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset);
  450. WansungChar.e.low = *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1);
  451. }
  452. else
  453. {
  454. WansungChar.w = 0;
  455. }
  456. ImmUnlockIMCC(lpIMC->hCompStr);
  457. Code2Automata();
  458. fRet = TRUE;
  459. }
  460. ImmUnlockIMC(hIMC);
  461. }
  462. }
  463. else
  464. {
  465. fRet = TRUE;
  466. }
  467. return fRet;
  468. }
  469. BOOL GenerateCandidateList(HIMC hIMC)
  470. {
  471. BOOL fRet = FALSE;
  472. int iMapCandStr;
  473. DWORD i, iIndexOfCandStr, iNumOfCandStr;
  474. LPSTR lpCandStr;
  475. LPINPUTCONTEXT lpIMC;
  476. LPCOMPOSITIONSTRING lpCompStr;
  477. LPCANDIDATEINFO lpCandInfo;
  478. LPCANDIDATELIST lpCandList;
  479. FUNCTIONLOG("GenerateCandiateList");
  480. lpIMC = ImmLockIMC(hIMC);
  481. if (lpIMC == NULL)
  482. return FALSE;
  483. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  484. if (lpCompStr == NULL) {
  485. ImmUnlockIMC(hIMC);
  486. return FALSE;
  487. }
  488. WansungChar.e.high = *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset);
  489. WansungChar.e.low = *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1);
  490. if ((iMapCandStr = SearchHanjaIndex(WansungChar.w)) < 0)
  491. MessageBeep(MB_ICONEXCLAMATION);
  492. else
  493. {
  494. iIndexOfCandStr = wHanjaIndex[iMapCandStr];
  495. iNumOfCandStr = wHanjaIndex[iMapCandStr + 1] - iIndexOfCandStr - 1;
  496. lpIMC->hCandInfo = ImmReSizeIMCC(lpIMC->hCandInfo, sizeof(CANDIDATEINFO)
  497. + sizeof(CANDIDATELIST) + sizeof(DWORD)*(iNumOfCandStr-1) + iNumOfCandStr*3);
  498. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  499. lpCandInfo->dwSize = sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST)
  500. + sizeof(DWORD) * (iNumOfCandStr-1) + iNumOfCandStr*3;
  501. lpCandInfo->dwCount = 1;
  502. lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
  503. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + sizeof(CANDIDATEINFO));
  504. lpCandList->dwSize = sizeof(CANDIDATELIST) + sizeof(DWORD) * (iNumOfCandStr-1)
  505. + iNumOfCandStr*3;
  506. lpCandList->dwStyle = IME_CAND_READ;
  507. lpCandList->dwCount = iNumOfCandStr;
  508. lpCandList->dwPageStart = lpCandList->dwSelection = 0;
  509. lpCandList->dwPageSize = 9;
  510. for (i = 0; i < iNumOfCandStr; i++)
  511. {
  512. lpCandList->dwOffset[i] = sizeof(CANDIDATELIST)
  513. + sizeof(DWORD) * (iNumOfCandStr-1) + i*3;
  514. lpCandStr = (LPSTR)lpCandList + lpCandList->dwOffset[i];
  515. *lpCandStr++ = (BYTE)HIBYTE(wHanja[iIndexOfCandStr + i]);
  516. *lpCandStr++ = (BYTE)LOBYTE(wHanja[iIndexOfCandStr + i]);
  517. *lpCandStr++ = '\0';
  518. }
  519. fRet = TRUE;
  520. ImmUnlockIMCC(lpIMC->hCandInfo);
  521. }
  522. ImmUnlockIMCC(lpIMC->hCompStr);
  523. ImmUnlockIMC(hIMC);
  524. return fRet;
  525. }
  526. UINT WINAPI ImeToAsciiEx(UINT uVirKey, UINT uScanCode, CONST LPBYTE lpbKeyState,
  527. LPDWORD lpdwTransKey, UINT fuState, HIMC hIMC)
  528. {
  529. LPINPUTCONTEXT lpIMC;
  530. LPCOMPOSITIONSTRING lpCompStr;
  531. BYTE bKeyCode;
  532. DWORD i, iStart;
  533. LPSTR lpCandStr;
  534. LPCANDIDATEINFO lpCandInfo;
  535. LPCANDIDATELIST lpCandList;
  536. FUNCTIONLOG("ImeToAsciiEx");
  537. MyDebugOut(MDB_LOG, "hIMC = 0x%08lX, uVirKey = 0x%04X, uScanCode = 0x%04X",
  538. hIMC, uVirKey, uScanCode);
  539. MyDebugOut(MDB_LOG, "lpbKeyState = 0x%08lX, lpdwTransKey = 0x%08lX, fuState = 0x%04X",
  540. lpbKeyState, lpdwTransKey, fuState);
  541. iTotalNumMsg = 0;
  542. lpIMC = ImmLockIMC(hIMC);
  543. if (lpIMC == NULL)
  544. return 0;
  545. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  546. if (lpCompStr == NULL) {
  547. ImmUnlockIMC(hIMC);
  548. return 0;
  549. }
  550. if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)
  551. {
  552. i = (lpbKeyState[VK_SHIFT] & 0x80)? 3: 2;
  553. bKeyCode = bHTable[uCurrentInputMethod - IDD_2BEOL][uVirKey][i];
  554. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  555. if (lpCandInfo->dwCount == 0)
  556. {
  557. lpdwTransKey += iTotalNumMsg*3 + 1;
  558. *lpdwTransKey++ = WM_IME_NOTIFY;
  559. *lpdwTransKey++ = IMN_CLOSECANDIDATE;
  560. *lpdwTransKey++ = 1L;
  561. iTotalNumMsg++;
  562. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion & ~IME_CMODE_HANJACONVERT,
  563. lpIMC->fdwSentence);
  564. }
  565. else
  566. {
  567. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + sizeof(CANDIDATEINFO));
  568. iStart = (lpCandList->dwSelection / lpCandList->dwPageSize)
  569. * lpCandList->dwPageSize;
  570. if (bKeyCode)
  571. {
  572. if (bKeyCode >= '1' && bKeyCode <= '9'
  573. && iStart + bKeyCode - '1' < lpCandList->dwCount)
  574. {
  575. lpCandStr = (LPSTR)lpCandList
  576. + lpCandList->dwOffset[iStart + bKeyCode - '1'];
  577. WansungChar.e.high = lpCandStr[0];
  578. WansungChar.e.low = lpCandStr[1];
  579. lpdwTransKey += iTotalNumMsg*3 + 1;
  580. *lpdwTransKey++ = WM_IME_ENDCOMPOSITION;
  581. *lpdwTransKey++ = 0L;
  582. *lpdwTransKey++ = 0L;
  583. *lpdwTransKey++ = WM_IME_COMPOSITION;
  584. *lpdwTransKey++ = (DWORD)WansungChar.w;
  585. *lpdwTransKey++ = GCS_RESULTSTR;
  586. *lpdwTransKey++ = WM_IME_NOTIFY;
  587. *lpdwTransKey++ = IMN_CLOSECANDIDATE;
  588. *lpdwTransKey++ = 1L;
  589. iTotalNumMsg += 3;
  590. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion & ~IME_CMODE_HANJACONVERT,
  591. lpIMC->fdwSentence);
  592. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0;
  593. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0;
  594. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0;
  595. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0;
  596. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0;
  597. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset) = WansungChar.e.high;
  598. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 1) = WansungChar.e.low;
  599. lpCompStr->dwResultStrLen = 2;
  600. // add a null terminator
  601. *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset +
  602. lpCompStr->dwResultStrLen) = '\0';
  603. bState = NUL;
  604. JohabChar.w = WansungChar.w = mCho = mJung = mJong = 0;
  605. fComplete = FALSE;
  606. }
  607. else
  608. MessageBeep(MB_ICONEXCLAMATION);
  609. }
  610. else
  611. {
  612. switch (uVirKey)
  613. {
  614. case VK_HANJA :
  615. case VK_ESCAPE :
  616. case VK_PROCESSKEY :
  617. lpdwTransKey += iTotalNumMsg*3 + 1;
  618. *lpdwTransKey++ = WM_IME_ENDCOMPOSITION;
  619. *lpdwTransKey++ = 0L;
  620. *lpdwTransKey++ = 0L;
  621. *lpdwTransKey++ = WM_IME_COMPOSITION;
  622. *lpdwTransKey++ = (DWORD)WansungChar.w;
  623. *lpdwTransKey++ = GCS_RESULTSTR;
  624. *lpdwTransKey++ = WM_IME_NOTIFY;
  625. *lpdwTransKey++ = IMN_CLOSECANDIDATE;
  626. *lpdwTransKey++ = 1L;
  627. iTotalNumMsg += 3;
  628. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion & ~IME_CMODE_HANJACONVERT,
  629. lpIMC->fdwSentence);
  630. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0;
  631. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0;
  632. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0;
  633. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0;
  634. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0;
  635. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset) = WansungChar.e.high;
  636. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 1) = WansungChar.e.low;
  637. lpCompStr->dwResultStrLen = 2;
  638. // add a null terminator
  639. *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset +
  640. lpCompStr->dwResultStrLen) = '\0';
  641. bState = NUL;
  642. JohabChar.w = WansungChar.w = mCho = mJung = mJong = 0;
  643. fComplete = FALSE;
  644. break;
  645. case VK_LEFT :
  646. if (iStart)
  647. {
  648. lpCandList->dwPageStart -= 9;
  649. lpCandList->dwSelection -= 9;
  650. lpdwTransKey += iTotalNumMsg*3 + 1;
  651. *lpdwTransKey++ = WM_IME_NOTIFY;
  652. *lpdwTransKey++ = IMN_CHANGECANDIDATE;
  653. *lpdwTransKey++ = 1L;
  654. iTotalNumMsg++;
  655. }
  656. else
  657. MessageBeep(MB_ICONEXCLAMATION);
  658. break;
  659. case VK_RIGHT :
  660. if (iStart + 9 < lpCandList->dwCount)
  661. {
  662. lpCandList->dwPageStart += 9;
  663. lpCandList->dwSelection += 9;
  664. lpdwTransKey += iTotalNumMsg*3 + 1;
  665. *lpdwTransKey++ = WM_IME_NOTIFY;
  666. *lpdwTransKey++ = IMN_CHANGECANDIDATE;
  667. *lpdwTransKey++ = 1L;
  668. iTotalNumMsg++;
  669. }
  670. else
  671. MessageBeep(MB_ICONEXCLAMATION);
  672. break;
  673. default :
  674. MessageBeep(MB_ICONEXCLAMATION);
  675. }
  676. }
  677. ImmUnlockIMCC(lpIMC->hCandInfo);
  678. }
  679. }
  680. else
  681. {
  682. switch (uVirKey)
  683. {
  684. case VK_SHIFT :
  685. case VK_CONTROL :
  686. break;
  687. case VK_PROCESSKEY :
  688. if (bState) MakeFinal(FALSE, lpdwTransKey, TRUE, lpCompStr);
  689. break;
  690. case VK_HANGEUL :
  691. if (bState) MakeFinal(FALSE, lpdwTransKey, TRUE, lpCompStr);
  692. lpdwTransKey += iTotalNumMsg*3 + 1;
  693. *lpdwTransKey++ = WM_IME_KEYDOWN;
  694. *lpdwTransKey++ = VK_HANGEUL;
  695. *lpdwTransKey++ = 1L;
  696. iTotalNumMsg++;
  697. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion ^ IME_CMODE_HANGEUL,
  698. lpIMC->fdwSentence);
  699. UpdateOpenCloseState(hIMC);
  700. break;
  701. case VK_JUNJA :
  702. if (bState) MakeFinal(FALSE, lpdwTransKey, TRUE, lpCompStr);
  703. lpdwTransKey += iTotalNumMsg*3 + 1;
  704. *lpdwTransKey++ = WM_IME_KEYDOWN;
  705. *lpdwTransKey++ = VK_JUNJA;
  706. *lpdwTransKey++ = 1L;
  707. iTotalNumMsg++;
  708. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE,
  709. lpIMC->fdwSentence);
  710. UpdateOpenCloseState(hIMC);
  711. break;
  712. case VK_HANJA :
  713. if (lpCompStr->dwCompStrLen && GenerateCandidateList(hIMC))
  714. {
  715. lpdwTransKey += iTotalNumMsg*3 + 1;
  716. *lpdwTransKey++ = WM_IME_NOTIFY;
  717. *lpdwTransKey++ = IMN_OPENCANDIDATE;
  718. *lpdwTransKey++ = 1L;
  719. iTotalNumMsg++;
  720. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion | IME_CMODE_HANJACONVERT,
  721. lpIMC->fdwSentence);
  722. }
  723. else
  724. {
  725. lpdwTransKey += iTotalNumMsg*3 + 1;
  726. *lpdwTransKey++ = WM_IME_KEYDOWN;
  727. *lpdwTransKey++ = VK_HANJA;
  728. *lpdwTransKey++ = 1L;
  729. iTotalNumMsg++;
  730. }
  731. break;
  732. default :
  733. if (lpIMC->fdwConversion & IME_CMODE_HANGEUL)
  734. {
  735. i = (lpbKeyState[VK_SHIFT] & 0x80)? 1: 0;
  736. bKeyCode = bHTable[uCurrentInputMethod - IDD_2BEOL][uVirKey][i];
  737. if (!bKeyCode || (lpbKeyState[VK_CONTROL] & 0x80) || uScanCode & KF_ALTDOWN)
  738. {
  739. if (bState)
  740. MakeFinal(FALSE, lpdwTransKey, TRUE, lpCompStr);
  741. else
  742. lpCompStr->dwResultStrLen = 0;
  743. lpdwTransKey += iTotalNumMsg*3 + 1;
  744. *lpdwTransKey++ = WM_IME_KEYDOWN;
  745. *lpdwTransKey++ = uVirKey;
  746. *lpdwTransKey++ = ((DWORD)uScanCode << 16) | 1L;
  747. iTotalNumMsg++;
  748. }
  749. else if (bKeyCode & 0x80) // Hangeul Character
  750. {
  751. HangeulAutomata(bKeyCode, lpdwTransKey, lpCompStr);
  752. }
  753. else
  754. {
  755. if (bState)
  756. MakeFinal(FALSE, lpdwTransKey, TRUE, lpCompStr);
  757. else
  758. lpCompStr->dwResultStrLen = 0;
  759. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)
  760. Banja2Junja(bKeyCode, lpdwTransKey, lpCompStr);
  761. else
  762. {
  763. #if 1
  764. if (lpCompStr->dwResultStrLen == 0)
  765. {
  766. lpdwTransKey += iTotalNumMsg*3 + 1;
  767. *lpdwTransKey++ = WM_IME_COMPOSITION;
  768. *lpdwTransKey++ = (DWORD)bKeyCode;
  769. *lpdwTransKey++ = GCS_RESULTSTR;
  770. iTotalNumMsg++;
  771. }
  772. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + lpCompStr->dwResultStrLen) = bKeyCode;
  773. lpCompStr->dwResultStrLen++;
  774. // add a null terminator
  775. *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + lpCompStr->dwResultStrLen) = '\0';
  776. #else
  777. lpdwTransKey += iTotalNumMsg*3 + 1;
  778. *lpdwTransKey++ = WM_IME_KEYDOWN;
  779. *lpdwTransKey++ = uVirKey;
  780. *lpdwTransKey++ = ((DWORD)uScanCode << 16) | 1L;
  781. iTotalNumMsg++;
  782. #endif
  783. }
  784. }
  785. }
  786. else // For Junja case.
  787. {
  788. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)
  789. {
  790. if (uVirKey >= 'A' && uVirKey <= 'Z')
  791. i = (((lpbKeyState[VK_SHIFT] & 0x80)? 1: 0)
  792. ^ ((lpbKeyState[VK_CAPITAL] & 0x01))? 1: 0)? 3: 2;
  793. else
  794. i = (lpbKeyState[VK_SHIFT] & 0x80)? 3: 2;
  795. bKeyCode = bHTable[uCurrentInputMethod - IDD_2BEOL][uVirKey][i];
  796. if (!bKeyCode || (lpbKeyState[VK_CONTROL] & 0x80) || uScanCode & KF_ALTDOWN)
  797. {
  798. lpdwTransKey += iTotalNumMsg*3 + 1;
  799. *lpdwTransKey++ = WM_IME_KEYDOWN;
  800. *lpdwTransKey++ = uVirKey;
  801. *lpdwTransKey++ = ((DWORD)uScanCode << 16) | 1L;
  802. iTotalNumMsg++;
  803. }
  804. else
  805. {
  806. lpCompStr->dwResultStrLen = 0;
  807. Banja2Junja(bKeyCode, lpdwTransKey, lpCompStr);
  808. }
  809. }
  810. else
  811. {
  812. lpdwTransKey += iTotalNumMsg*3 + 1;
  813. *lpdwTransKey++ = WM_IME_KEYDOWN;
  814. *lpdwTransKey++ = uVirKey;
  815. *lpdwTransKey++ = ((DWORD)uScanCode << 16) | 1L;
  816. iTotalNumMsg++;
  817. }
  818. }
  819. }
  820. }
  821. ImmUnlockIMCC(lpIMC->hCompStr);
  822. ImmUnlockIMC(hIMC);
  823. return iTotalNumMsg;
  824. }
  825. BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
  826. {
  827. LPINPUTCONTEXT lpIMC;
  828. LPCOMPOSITIONSTRING lpCompStr;
  829. LPCANDIDATEINFO lpCandInfo;
  830. LPCANDIDATELIST lpCandList;
  831. LPDWORD lpdwMsgBuf;
  832. BOOL fRet = FALSE;
  833. FUNCTIONLOG("NotifyIME");
  834. MyDebugOut(MDB_LOG, "dwAction = 0x%04X, dwIndex = 0x%04X, dwValue = 0x%04X",
  835. dwAction, dwIndex, dwValue);
  836. if (hIMC && (lpIMC = ImmLockIMC(hIMC)))
  837. {
  838. switch (dwAction)
  839. {
  840. case NI_COMPOSITIONSTR:
  841. switch (dwIndex)
  842. {
  843. case CPS_CANCEL:
  844. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  845. if (lpCompStr && lpCompStr->dwCompStrLen)
  846. {
  847. lpIMC->dwNumMsgBuf = 1;
  848. lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf);
  849. lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
  850. *lpdwMsgBuf++ = WM_IME_ENDCOMPOSITION;
  851. *lpdwMsgBuf++ = 0L;
  852. *lpdwMsgBuf++ = 0L;
  853. ImmUnlockIMCC(lpIMC->hMsgBuf);
  854. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0;
  855. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0;
  856. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0;
  857. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0;
  858. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0;
  859. ImmGenerateMessage(hIMC);
  860. // Initialize all Automata Variables.
  861. bState = NUL;
  862. JohabChar.w = WansungChar.w = mCho = mJung = mJong = 0;
  863. fComplete = FALSE;
  864. fRet = TRUE;
  865. }
  866. ImmUnlockIMCC(lpIMC->hCompStr);
  867. break;
  868. case CPS_COMPLETE:
  869. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  870. if (lpCompStr && lpCompStr->dwCompStrLen)
  871. {
  872. if (!WansungChar.w)
  873. MakeInterim(lpCompStr);
  874. mJong = 0;
  875. lpIMC->dwNumMsgBuf = 2;
  876. if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)
  877. lpIMC->dwNumMsgBuf++;
  878. lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf);
  879. lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
  880. *lpdwMsgBuf++ = WM_IME_ENDCOMPOSITION;
  881. *lpdwMsgBuf++ = 0L;
  882. *lpdwMsgBuf++ = 0L;
  883. // Put the finalized character into return buffer.
  884. *lpdwMsgBuf++ = WM_IME_COMPOSITION;
  885. *lpdwMsgBuf++ = (DWORD)WansungChar.w;
  886. *lpdwMsgBuf++ = GCS_RESULTSTR;
  887. if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)
  888. {
  889. // Close candidate window if it is.
  890. *lpdwMsgBuf++ = WM_IME_NOTIFY;
  891. *lpdwMsgBuf++ = IMN_CLOSECANDIDATE;
  892. *lpdwMsgBuf++ = 1L;
  893. ImmSetConversionStatus(hIMC,
  894. lpIMC->fdwConversion & ~IME_CMODE_HANJACONVERT,
  895. lpIMC->fdwSentence);
  896. }
  897. ImmUnlockIMCC(lpIMC->hMsgBuf);
  898. // Update IME Context.
  899. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0;
  900. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0;
  901. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0;
  902. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0;
  903. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0;
  904. lpCompStr->dwResultStrLen = 2;
  905. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset) = WansungChar.e.high;
  906. *((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset + 1) = WansungChar.e.low;
  907. // add a null terminator
  908. *(LPTSTR)((LPSTR)lpCompStr + lpCompStr->dwResultStrOffset +
  909. lpCompStr->dwResultStrLen) = '\0';
  910. ImmGenerateMessage(hIMC);
  911. // Initialize all Automata Variables.
  912. bState = NUL;
  913. JohabChar.w = WansungChar.w = mCho = mJung = 0;
  914. fComplete = FALSE;
  915. fRet = TRUE;
  916. }
  917. ImmUnlockIMCC(lpIMC->hCompStr);
  918. break;
  919. case CPS_CONVERT:
  920. case CPS_REVERT:
  921. break;
  922. }
  923. break;
  924. case NI_OPENCANDIDATE:
  925. if (!(lpIMC->fdwConversion & IME_CMODE_HANJACONVERT))
  926. {
  927. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  928. if (lpCompStr && lpCompStr->dwCompStrLen && GenerateCandidateList(hIMC))
  929. {
  930. lpIMC->dwNumMsgBuf = 1;
  931. lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf);
  932. lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
  933. *lpdwMsgBuf++ = WM_IME_NOTIFY;
  934. *lpdwMsgBuf++ = IMN_OPENCANDIDATE;
  935. *lpdwMsgBuf++ = 1L;
  936. ImmSetConversionStatus(hIMC,
  937. lpIMC->fdwConversion | IME_CMODE_HANJACONVERT,
  938. lpIMC->fdwSentence);
  939. ImmUnlockIMCC(lpIMC->hMsgBuf);
  940. ImmGenerateMessage(hIMC);
  941. fRet = TRUE;
  942. }
  943. ImmUnlockIMCC(lpIMC->hCompStr);
  944. }
  945. break;
  946. case NI_CLOSECANDIDATE:
  947. if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)
  948. {
  949. lpIMC->dwNumMsgBuf = 1;
  950. lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf);
  951. lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
  952. *lpdwMsgBuf++ = WM_IME_NOTIFY;
  953. *lpdwMsgBuf++ = IMN_CLOSECANDIDATE;
  954. *lpdwMsgBuf++ = 1L;
  955. ImmSetConversionStatus(hIMC,
  956. lpIMC->fdwConversion & ~IME_CMODE_HANJACONVERT,
  957. lpIMC->fdwSentence);
  958. ImmUnlockIMCC(lpIMC->hMsgBuf);
  959. ImmGenerateMessage(hIMC);
  960. fRet = TRUE;
  961. }
  962. break;
  963. case NI_SELECTCANDIDATESTR:
  964. case NI_SETCANDIDATE_PAGESTART:
  965. if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)
  966. {
  967. lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
  968. lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + sizeof(CANDIDATEINFO));
  969. if (lpCandInfo && dwValue < lpCandList->dwCount)
  970. {
  971. lpCandList->dwPageStart = (dwValue / lpCandList->dwPageSize) * lpCandList->dwPageSize;
  972. lpCandList->dwSelection = dwValue;
  973. lpIMC->dwNumMsgBuf = 1;
  974. lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf);
  975. lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
  976. *lpdwMsgBuf++ = WM_IME_NOTIFY;
  977. *lpdwMsgBuf++ = IMN_CHANGECANDIDATE;
  978. *lpdwMsgBuf++ = 1L;
  979. ImmUnlockIMCC(lpIMC->hMsgBuf);
  980. ImmGenerateMessage(hIMC);
  981. fRet = TRUE;
  982. }
  983. ImmUnlockIMCC(lpIMC->hCandInfo);
  984. }
  985. break;
  986. case NI_CONTEXTUPDATED:
  987. switch (dwValue)
  988. {
  989. case IMC_SETOPENSTATUS:
  990. case IMC_SETCONVERSIONMODE:
  991. UpdateOpenCloseState(hIMC);
  992. // fall thru...
  993. case IMC_SETCANDIDATEPOS:
  994. case IMC_SETCOMPOSITIONFONT:
  995. case IMC_SETCOMPOSITIONWINDOW:
  996. fRet = TRUE;
  997. break;
  998. }
  999. break;
  1000. case NI_CHANGECANDIDATELIST:
  1001. case NI_FINALIZECONVERSIONRESULT:
  1002. case NI_SETCANDIDATE_PAGESIZE:
  1003. break;
  1004. }
  1005. ImmUnlockIMC(hIMC);
  1006. }
  1007. return fRet;
  1008. }
  1009. BOOL WINAPI ImeRegisterWord(LPCTSTR lpszReading, DWORD dwStyle, LPCTSTR lpszString)
  1010. {
  1011. FUNCTIONLOG("ImeRegisterWord");
  1012. return FALSE;
  1013. UNREFERENCED_PARAMETER(lpszReading);
  1014. UNREFERENCED_PARAMETER(dwStyle);
  1015. UNREFERENCED_PARAMETER(lpszString);
  1016. }
  1017. BOOL WINAPI ImeUnregisterWord(LPCTSTR lpszReading, DWORD dwStyle, LPCTSTR lpszString)
  1018. {
  1019. FUNCTIONLOG("ImeUnregisterWord");
  1020. return FALSE;
  1021. UNREFERENCED_PARAMETER(lpszReading);
  1022. UNREFERENCED_PARAMETER(dwStyle);
  1023. UNREFERENCED_PARAMETER(lpszString);
  1024. }
  1025. UINT WINAPI ImeGetRegisterWordStyle(UINT nItem, LPSTYLEBUF lpStyleBuf)
  1026. {
  1027. FUNCTIONLOG("ImeGetRegisterWordStyle");
  1028. return 0;
  1029. UNREFERENCED_PARAMETER(nItem);
  1030. UNREFERENCED_PARAMETER(lpStyleBuf);
  1031. }
  1032. UINT WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
  1033. LPCTSTR lpszReading, DWORD dwStyle, LPCTSTR lpszString, LPVOID lpData)
  1034. {
  1035. FUNCTIONLOG("ImeEnumRegisterWord");
  1036. return 0;
  1037. UNREFERENCED_PARAMETER(lpfnRegisterWordEnumProc);
  1038. UNREFERENCED_PARAMETER(lpszReading);
  1039. UNREFERENCED_PARAMETER(dwStyle);
  1040. UNREFERENCED_PARAMETER(lpszString);
  1041. UNREFERENCED_PARAMETER(lpData);
  1042. }
  1043. BOOL WINAPI ImeSetCompositionString(HIMC hIMC, DWORD dwIndex, LPVOID lpComp,
  1044. DWORD dwComp, LPVOID lpRead, DWORD dwRead)
  1045. {
  1046. LPINPUTCONTEXT lpIMC;
  1047. LPCOMPOSITIONSTRING lpCompStr;
  1048. LPDWORD lpdwMsgBuf;
  1049. BOOL fSendStart,
  1050. fRet = FALSE;
  1051. FUNCTIONLOG("ImeSetCompositionString");
  1052. MyDebugOut(MDB_LOG, "hIMC = 0x%08lX, dwIndex = 0x%04X", hIMC, dwIndex);
  1053. if (lpComp && *(LPBYTE)lpComp != '\0' && IsDBCSLeadByte(*(LPBYTE)lpComp) == FALSE)
  1054. return FALSE;
  1055. if (dwIndex == SCS_SETSTR && hIMC && (lpIMC = ImmLockIMC(hIMC)))
  1056. {
  1057. lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
  1058. fSendStart = (lpCompStr->dwCompStrLen)? FALSE: TRUE;
  1059. if (lpComp != NULL && *(LPBYTE)lpComp != '\0' && dwComp != 0)
  1060. {
  1061. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 2;
  1062. WansungChar.e.high = *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset)
  1063. = *(LPSTR)lpComp;
  1064. WansungChar.e.low = *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1)
  1065. = *((LPSTR)lpComp + 1);
  1066. }
  1067. else
  1068. {
  1069. lpCompStr->dwCompStrLen = lpCompStr->dwCompAttrLen = 0;
  1070. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset) = 0;
  1071. *((LPSTR)lpCompStr + lpCompStr->dwCompAttrOffset + 1) = 0;
  1072. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset) = 0;
  1073. *((LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + 1) = 0;
  1074. WansungChar.w = 0;
  1075. }
  1076. ImmUnlockIMCC(lpIMC->hCompStr);
  1077. lpIMC->dwNumMsgBuf = (fSendStart)? 2: 1;
  1078. if (WansungChar.w == 0)
  1079. lpIMC->dwNumMsgBuf++;
  1080. lpIMC->hMsgBuf = ImmReSizeIMCC(lpIMC->hMsgBuf, sizeof(DWORD)*3 * lpIMC->dwNumMsgBuf);
  1081. lpdwMsgBuf = (LPDWORD)ImmLockIMCC(lpIMC->hMsgBuf);
  1082. if (fSendStart)
  1083. {
  1084. *lpdwMsgBuf++ = WM_IME_STARTCOMPOSITION;
  1085. *lpdwMsgBuf++ = 0L;
  1086. *lpdwMsgBuf++ = 0L;
  1087. }
  1088. *lpdwMsgBuf++ = WM_IME_COMPOSITION;
  1089. *lpdwMsgBuf++ = (DWORD)WansungChar.w;
  1090. *lpdwMsgBuf++ = GCS_COMPSTR | GCS_COMPATTR | CS_INSERTCHAR | CS_NOMOVECARET;
  1091. if (WansungChar.w == 0)
  1092. {
  1093. *lpdwMsgBuf++ = WM_IME_ENDCOMPOSITION;
  1094. *lpdwMsgBuf++ = 0L;
  1095. *lpdwMsgBuf++ = 0L;
  1096. }
  1097. ImmUnlockIMCC(lpIMC->hMsgBuf);
  1098. ImmUnlockIMC(hIMC);
  1099. ImmGenerateMessage(hIMC);
  1100. Code2Automata();
  1101. fRet = TRUE;
  1102. }
  1103. return fRet;
  1104. UNREFERENCED_PARAMETER(lpRead);
  1105. UNREFERENCED_PARAMETER(dwRead);
  1106. }
  1107. void AddPage(LPPROPSHEETHEADER ppsh, UINT id, DLGPROC pfn)
  1108. {
  1109. if (ppsh->nPages < MAX_PAGES) {
  1110. PROPSHEETPAGE psp;
  1111. psp.dwSize = sizeof(psp);
  1112. psp.dwFlags = PSP_DEFAULT;
  1113. psp.hInstance = hInst;
  1114. psp.pszTemplate = MAKEINTRESOURCE(id);
  1115. psp.pfnDlgProc = pfn;
  1116. psp.lParam = 0;
  1117. ppsh->phpage[ppsh->nPages] = CreatePropertySheetPage(&psp);
  1118. if (ppsh->phpage[ppsh->nPages])
  1119. ppsh->nPages++;
  1120. }
  1121. }
  1122. #ifdef XWANSUNG_IME
  1123. void RegisterNewUHCValue(HWND hDlg)
  1124. {
  1125. HIMC hIMC;
  1126. LPINPUTCONTEXT lpIMC;
  1127. LPDWORD lpdw;
  1128. TCHAR szModuleName[MAX_PATH];
  1129. BOOL fUseXW = FALSE;
  1130. HKEY hKey;
  1131. DWORD dwBuf, dwCb;
  1132. hIMC = ImmGetContext(hDlg);
  1133. if (hIMC && (lpIMC = ImmLockIMC(hIMC)))
  1134. {
  1135. if (RegOpenKey(HKEY_CURRENT_USER, szIMEKey, &hKey) == ERROR_SUCCESS)
  1136. {
  1137. if (lpIMC->hPrivate && (lpdw = (LPDWORD)ImmLockIMCC(lpIMC->hPrivate)))
  1138. {
  1139. if (RegQueryValueEx(hKey, szUseXW, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
  1140. == ERROR_SUCCESS)
  1141. fUseXW = dwBuf;
  1142. GetModuleFileName(NULL, szModuleName, sizeof(szModuleName));
  1143. *lpdw = GetProfileInt(szUseXW, PathFindFileName((LPCSTR)szModuleName), fUseXW);
  1144. ImmUnlockIMCC(lpIMC->hPrivate);
  1145. }
  1146. }
  1147. RegCloseKey(hKey);
  1148. }
  1149. ImmUnlockIMC(hIMC);
  1150. ImmReleaseContext(hDlg, hIMC);
  1151. }
  1152. #endif
  1153. BOOL CALLBACK GeneralDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
  1154. {
  1155. HKEY hKey;
  1156. DWORD dwBuf, dwCb;
  1157. static UINT uInputMethod;
  1158. static BOOL fCompDel;
  1159. #ifdef XWANSUNG_IME
  1160. static BOOL fUHCChar;
  1161. #endif
  1162. FUNCTIONLOG("GeneralDlgProc");
  1163. switch(message)
  1164. {
  1165. case WM_NOTIFY:
  1166. switch (((NMHDR FAR *)lParam)->code)
  1167. {
  1168. case PSN_APPLY:
  1169. uCurrentInputMethod = uInputMethod;
  1170. fCurrentCompDel = fCompDel;
  1171. if (RegCreateKey(HKEY_CURRENT_USER, szIMEKey, &hKey) == ERROR_SUCCESS)
  1172. {
  1173. dwCb = sizeof(dwBuf);
  1174. dwBuf = uCurrentInputMethod;
  1175. RegSetValueEx(hKey, szInputMethod, 0, REG_DWORD, (LPBYTE)&dwBuf, dwCb);
  1176. dwCb = sizeof(dwBuf);
  1177. dwBuf = fCurrentCompDel;
  1178. RegSetValueEx(hKey, szCompDel, 0, REG_DWORD, (LPBYTE)&dwBuf, dwCb);
  1179. #ifdef XWANSUNG_IME
  1180. if ( IsPossibleToUseUHC() ) {
  1181. fCurrentUseXW = fUHCChar;
  1182. dwCb = sizeof(dwBuf);
  1183. dwBuf = fCurrentUseXW;
  1184. RegSetValueEx(hKey, szUseXW, 0, REG_DWORD, (LPBYTE)&dwBuf, dwCb);
  1185. }
  1186. #endif
  1187. RegCloseKey(hKey);
  1188. #ifdef XWANSUNG_IME
  1189. if ( IsPossibleToUseUHC() )
  1190. RegisterNewUHCValue(hDlg);
  1191. #endif
  1192. }
  1193. break;
  1194. default:
  1195. return FALSE;
  1196. }
  1197. break;
  1198. case WM_INITDIALOG:
  1199. uInputMethod = uCurrentInputMethod;
  1200. fCompDel = fCurrentCompDel;
  1201. CheckRadioButton(hDlg, IDD_2BEOL, IDD_3BEOL2, uInputMethod);
  1202. CheckDlgButton(hDlg, IDD_COMPDEL, fCompDel);
  1203. #ifdef XWANSUNG_IME
  1204. if ( IsPossibleToUseUHC() ) {
  1205. fUHCChar = fCurrentUseXW;
  1206. CheckDlgButton(hDlg, IDD_UHCCHAR, fUHCChar);
  1207. EnableWindow(GetDlgItem(hDlg, IDD_UHCCHAR), TRUE);
  1208. }
  1209. else
  1210. EnableWindow(GetDlgItem(hDlg, IDD_UHCCHAR), FALSE);
  1211. #endif
  1212. SetFocus(GetDlgItem(hDlg, uInputMethod));
  1213. return FALSE;
  1214. case WM_COMMAND:
  1215. switch (wParam)
  1216. {
  1217. case IDD_2BEOL:
  1218. case IDD_3BEOL1:
  1219. case IDD_3BEOL2:
  1220. uInputMethod = wParam;
  1221. CheckRadioButton(hDlg, IDD_2BEOL, IDD_3BEOL2, uInputMethod);
  1222. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  1223. break;
  1224. case IDD_COMPDEL:
  1225. fCompDel = !IsDlgButtonChecked(hDlg, IDD_COMPDEL);
  1226. CheckDlgButton(hDlg, IDD_COMPDEL, fCompDel);
  1227. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  1228. break;
  1229. #ifdef XWANSUNG_IME
  1230. case IDD_UHCCHAR:
  1231. fUHCChar = !IsDlgButtonChecked(hDlg, IDD_UHCCHAR);
  1232. CheckDlgButton(hDlg, IDD_UHCCHAR, fUHCChar);
  1233. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  1234. RegisterNewUHCValue(hDlg);
  1235. break;
  1236. #endif
  1237. default:
  1238. return FALSE;
  1239. }
  1240. break;
  1241. default:
  1242. return FALSE;
  1243. }
  1244. return TRUE;
  1245. }
  1246. #ifdef DEBUG
  1247. void _cdecl _MyDebugOut(UINT uFlag, LPCSTR lpsz, ...)
  1248. {
  1249. #ifdef LATER
  1250. BYTE lpOutput[255];
  1251. int iCount;
  1252. if (fFuncLog)
  1253. {
  1254. lstrcpy(lpOutput, "WANSUNG: ");
  1255. iCount = lstrlen(lpOutput);
  1256. wvsprintf(lpOutput + iCount, lpsz, ((BYTE*)&lpsz) + sizeof(lpsz));
  1257. lstrcat(lpOutput, "\r\n");
  1258. OutputDebugString(lpOutput);
  1259. }
  1260. TRAP(uFlag & MDB_ERROR);
  1261. #endif
  1262. return;
  1263. }
  1264. #endif // DEBUG