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.

1952 lines
51 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. UI.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #if defined(UNIIME)
  11. #include "uniime.h"
  12. #endif
  13. /**********************************************************************/
  14. /* CreateUIWindow() */
  15. /**********************************************************************/
  16. void PASCAL CreateUIWindow( // create composition window
  17. #if defined(UNIIME)
  18. LPIMEL lpImeL,
  19. #endif
  20. HWND hUIWnd)
  21. {
  22. HGLOBAL hUIPrivate;
  23. LPUIPRIV lpUIPrivate;
  24. // create storage for UI setting
  25. hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV));
  26. if (!hUIPrivate) { // Oh! Oh!
  27. return;
  28. }
  29. SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)hUIPrivate);
  30. // set the default position for UI window, it is hide now
  31. SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER);
  32. ShowWindow(hUIWnd, SW_SHOWNOACTIVATE);
  33. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  34. if (!lpUIPrivate) { // can not draw candidate window
  35. return;
  36. }
  37. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  38. lpUIPrivate->fdwSetContext |= ISC_OFF_CARET_UI;
  39. }
  40. GlobalUnlock(hUIPrivate);
  41. return;
  42. }
  43. /**********************************************************************/
  44. /* DestroyUIWindow() */
  45. /**********************************************************************/
  46. void PASCAL DestroyUIWindow( // destroy composition window
  47. HWND hUIWnd)
  48. {
  49. HGLOBAL hUIPrivate;
  50. LPUIPRIV lpUIPrivate;
  51. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  52. if (!hUIPrivate) { // Oh! Oh!
  53. return;
  54. }
  55. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  56. if (!lpUIPrivate) { // Oh! Oh!
  57. return;
  58. }
  59. if (lpUIPrivate->hCMenuWnd) {
  60. SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_HUIWND,(LONG_PTR)0);
  61. PostMessage(lpUIPrivate->hCMenuWnd, WM_USER_DESTROY, 0, 0);
  62. }
  63. #if !defined(ROMANIME)
  64. // composition window need to be destroyed
  65. if (lpUIPrivate->hCompWnd) {
  66. DestroyWindow(lpUIPrivate->hCompWnd);
  67. }
  68. // candidate window need to be destroyed
  69. if (lpUIPrivate->hCandWnd) {
  70. DestroyWindow(lpUIPrivate->hCandWnd);
  71. }
  72. #endif
  73. // status window need to be destroyed
  74. if (lpUIPrivate->hStatusWnd) {
  75. DestroyWindow(lpUIPrivate->hStatusWnd);
  76. }
  77. #if !defined(ROMANIME) && !defined(WINAR30)
  78. // soft keyboard window need to be destroyed
  79. if (lpUIPrivate->hSoftKbdWnd) {
  80. ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
  81. }
  82. #endif
  83. GlobalUnlock(hUIPrivate);
  84. // free storage for UI settings
  85. GlobalFree(hUIPrivate);
  86. return;
  87. }
  88. #if !defined(ROMANIME) && !defined(WINAR30)
  89. /**********************************************************************/
  90. /* GetSoftKbdWnd */
  91. /* Return Value : */
  92. /* window handle of composition */
  93. /**********************************************************************/
  94. HWND PASCAL GetSoftKbdWnd(
  95. HWND hUIWnd) // UI window
  96. {
  97. HGLOBAL hUIPrivate;
  98. LPUIPRIV lpUIPrivate;
  99. HWND hSoftKbdWnd;
  100. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  101. if (!hUIPrivate) { // can not darw candidate window
  102. return (HWND)NULL;
  103. }
  104. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  105. if (!lpUIPrivate) { // can not draw candidate window
  106. return (HWND)NULL;
  107. }
  108. hSoftKbdWnd = lpUIPrivate->hSoftKbdWnd;
  109. GlobalUnlock(hUIPrivate);
  110. return (hSoftKbdWnd);
  111. }
  112. /**********************************************************************/
  113. /* ShowSoftKbd */
  114. /**********************************************************************/
  115. void PASCAL ShowSoftKbd( // Show the soft keyboard window
  116. HWND hUIWnd,
  117. int nShowSoftKbdCmd)
  118. {
  119. HGLOBAL hUIPrivate;
  120. LPUIPRIV lpUIPrivate;
  121. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  122. if (!hUIPrivate) { // can not darw status window
  123. return;
  124. }
  125. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  126. if (!lpUIPrivate) { // can not draw status window
  127. return;
  128. }
  129. if (lpUIPrivate->nShowSoftKbdCmd == nShowSoftKbdCmd) {
  130. goto SwSftKbNoChange;
  131. }
  132. if (nShowSoftKbdCmd == SW_HIDE) {
  133. lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
  134. }
  135. if (!lpUIPrivate->hSoftKbdWnd) {
  136. // not in show status window mode
  137. } else {
  138. ImmShowSoftKeyboard(lpUIPrivate->hSoftKbdWnd, nShowSoftKbdCmd);
  139. lpUIPrivate->nShowSoftKbdCmd = nShowSoftKbdCmd;
  140. }
  141. SwSftKbNoChange:
  142. GlobalUnlock(hUIPrivate);
  143. return;
  144. }
  145. /**********************************************************************/
  146. /* CheckSoftKbdPosition() */
  147. /**********************************************************************/
  148. void PASCAL CheckSoftKbdPosition(
  149. LPUIPRIV lpUIPrivate,
  150. LPINPUTCONTEXT lpIMC)
  151. {
  152. #if 0 // MultiMonitor support
  153. UINT fPortionBits = 0;
  154. UINT fPortionTest;
  155. int xPortion, yPortion, nPortion;
  156. RECT rcWnd;
  157. // portion of dispaly
  158. // 0 1
  159. // 2 3
  160. if (lpUIPrivate->hCompWnd) {
  161. GetWindowRect(lpUIPrivate->hCompWnd, &rcWnd);
  162. if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
  163. xPortion = 1;
  164. } else {
  165. xPortion = 0;
  166. }
  167. if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
  168. yPortion = 1;
  169. } else {
  170. yPortion = 0;
  171. }
  172. fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
  173. }
  174. if (lpUIPrivate->hStatusWnd) {
  175. GetWindowRect(lpUIPrivate->hStatusWnd, &rcWnd);
  176. if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
  177. xPortion = 1;
  178. } else {
  179. xPortion = 0;
  180. }
  181. if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
  182. yPortion = 1;
  183. } else {
  184. yPortion = 0;
  185. }
  186. fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
  187. }
  188. GetWindowRect(lpUIPrivate->hSoftKbdWnd, &rcWnd);
  189. // start from portion 3
  190. for (nPortion = 3, fPortionTest = 0x0008; fPortionTest;
  191. nPortion--, fPortionTest >>= 1) {
  192. if (fPortionTest & fPortionBits) {
  193. // someone here!
  194. continue;
  195. }
  196. if (nPortion % 2) {
  197. lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.right -
  198. (rcWnd.right - rcWnd.left) - UI_MARGIN;
  199. } else {
  200. lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.left;
  201. }
  202. if (nPortion / 2) {
  203. lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.bottom -
  204. (rcWnd.bottom - rcWnd.top) - UI_MARGIN;
  205. } else {
  206. lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.top;
  207. }
  208. lpIMC->fdwInit |= INIT_SOFTKBDPOS;
  209. break;
  210. }
  211. #else
  212. RECT rcWorkArea, rcWnd;
  213. GetWindowRect(lpUIPrivate->hSoftKbdWnd, &rcWnd);
  214. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  215. lpIMC->ptSoftKbdPos.x = rcWorkArea.right -
  216. (rcWnd.right - rcWnd.left) - UI_MARGIN;
  217. lpIMC->ptSoftKbdPos.y = rcWorkArea.bottom -
  218. (rcWnd.bottom - rcWnd.top) - UI_MARGIN;
  219. #endif
  220. return;
  221. }
  222. /**********************************************************************/
  223. /* SetSoftKbdData() */
  224. /**********************************************************************/
  225. void PASCAL SetSoftKbdData(
  226. #if defined(UNIIME)
  227. LPIMEL lpImeL,
  228. #endif
  229. HWND hSoftKbdWnd,
  230. LPINPUTCONTEXT lpIMC)
  231. {
  232. int i;
  233. SOFTKBDDATA sSoftKbdData;
  234. sSoftKbdData.uCount = 1;
  235. // initialize the char array to 0s
  236. for (i = 0; i < sizeof(sSoftKbdData.wCode)/sizeof(WORD); i++) {
  237. sSoftKbdData.wCode[0][i] = 0;
  238. }
  239. for (i = 0; i < 0x41; i++) {
  240. BYTE bVirtKey;
  241. bVirtKey = bChar2VirtKey[i];
  242. if (!bVirtKey) {
  243. continue;
  244. }
  245. #if defined(ROMANIME) || defined(WINAR30)
  246. {
  247. #else
  248. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  249. sSoftKbdData.wCode[0][bVirtKey] = sImeG.wSymbol[i];
  250. } else {
  251. #endif
  252. #if defined(PHON)
  253. BYTE bStandardChar;
  254. #endif
  255. register short iSeq;
  256. #if defined(PHON)
  257. {
  258. bStandardChar = bStandardLayout[lpImeL->nReadLayout][i];
  259. }
  260. iSeq = lpImeL->wChar2SeqTbl[bStandardChar - ' '];
  261. #else
  262. iSeq = lpImeL->wChar2SeqTbl[i];
  263. #endif
  264. if (!iSeq) {
  265. continue;
  266. }
  267. sSoftKbdData.wCode[0][bVirtKey] =
  268. #ifdef UNICODE
  269. lpImeL->wSeq2CompTbl[iSeq];
  270. #else
  271. HIBYTE(lpImeL->wSeq2CompTbl[iSeq]) |
  272. (LOBYTE(lpImeL->wSeq2CompTbl[iSeq]) << 8);
  273. #endif
  274. }
  275. }
  276. if (sImeG.fDiffSysCharSet) {
  277. LOGFONT lfFont;
  278. GetObject(GetStockObject(SYSTEM_FONT), sizeof(lfFont), &lfFont);
  279. lfFont.lfCharSet = NATIVE_CHARSET;
  280. lfFont.lfFaceName[0] = TEXT('\0');
  281. SendMessage(hSoftKbdWnd, WM_IME_CONTROL, IMC_SETSOFTKBDFONT,
  282. (LPARAM)&lfFont);
  283. }
  284. SendMessage(hSoftKbdWnd, WM_IME_CONTROL, IMC_SETSOFTKBDDATA,
  285. (LPARAM)&sSoftKbdData);
  286. #if defined(PHON)
  287. SendMessage(hSoftKbdWnd, WM_IME_CONTROL, IMC_SETSOFTKBDSUBTYPE,
  288. lpImeL->nReadLayout);
  289. #endif
  290. return;
  291. }
  292. /**********************************************************************/
  293. /* UpdateSoftKbd() */
  294. /**********************************************************************/
  295. void PASCAL UpdateSoftKbd(
  296. #if defined(UNIIME)
  297. LPIMEL lpImeL,
  298. #endif
  299. HWND hUIWnd)
  300. {
  301. HIMC hIMC;
  302. LPINPUTCONTEXT lpIMC;
  303. HGLOBAL hUIPrivate;
  304. LPUIPRIV lpUIPrivate;
  305. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  306. if (!hIMC) {
  307. return;
  308. }
  309. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  310. if (!lpIMC) {
  311. return;
  312. }
  313. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  314. if (!hUIPrivate) { // can not darw soft keyboard window
  315. ImmUnlockIMC(hIMC);
  316. return;
  317. }
  318. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  319. if (!lpUIPrivate) { // can not draw soft keyboard window
  320. ImmUnlockIMC(hIMC);
  321. return;
  322. }
  323. if (!(lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
  324. if (lpUIPrivate->hSoftKbdWnd) {
  325. ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
  326. lpUIPrivate->hSoftKbdWnd = NULL;
  327. }
  328. lpUIPrivate->nShowSoftKbdCmd = SW_HIDE;
  329. } else if (!lpIMC->fOpen) {
  330. if (lpUIPrivate->nShowSoftKbdCmd != SW_HIDE) {
  331. ShowSoftKbd(hUIWnd, SW_HIDE);
  332. }
  333. } else if ((lpIMC->fdwConversion & (IME_CMODE_NATIVE|IME_CMODE_CHARCODE|
  334. IME_CMODE_NOCONVERSION)) == IME_CMODE_NATIVE) {
  335. if (!lpUIPrivate->hSoftKbdWnd) {
  336. HWND hInsertWnd;
  337. // create soft keyboard
  338. lpUIPrivate->hSoftKbdWnd =
  339. ImmCreateSoftKeyboard(SOFTKEYBOARD_TYPE_T1, hUIWnd,
  340. 0, 0);
  341. if (lpUIPrivate->hStatusWnd) {
  342. hInsertWnd = lpUIPrivate->hStatusWnd;
  343. } else if (lpUIPrivate->hCompWnd) {
  344. hInsertWnd = lpUIPrivate->hCompWnd;
  345. } else if (lpUIPrivate->hCandWnd) {
  346. hInsertWnd = lpUIPrivate->hCandWnd;
  347. } else {
  348. hInsertWnd = NULL;
  349. }
  350. if (!hInsertWnd) {
  351. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  352. // insert soft keyboard in front of other UI
  353. SetWindowPos(hInsertWnd, lpUIPrivate->hSoftKbdWnd,
  354. 0, 0, 0, 0,
  355. SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
  356. } else {
  357. // insert soft keyboard behind other UI
  358. SetWindowPos(lpUIPrivate->hSoftKbdWnd, hInsertWnd,
  359. 0, 0, 0, 0,
  360. SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
  361. }
  362. }
  363. if (!(lpIMC->fdwInit & INIT_SOFTKBDPOS)) {
  364. CheckSoftKbdPosition(lpUIPrivate, lpIMC);
  365. }
  366. SetSoftKbdData(
  367. #if defined(UNIIME)
  368. lpImeL,
  369. #endif
  370. lpUIPrivate->hSoftKbdWnd, lpIMC);
  371. if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
  372. SetWindowPos(lpUIPrivate->hSoftKbdWnd, NULL,
  373. lpIMC->ptSoftKbdPos.x, lpIMC->ptSoftKbdPos.y,
  374. 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  375. // only show, if the application want to show it
  376. if (lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) {
  377. ShowSoftKbd(hUIWnd, SW_SHOWNOACTIVATE);
  378. }
  379. }
  380. } else {
  381. if (lpUIPrivate->nShowSoftKbdCmd != SW_HIDE) {
  382. ShowSoftKbd(hUIWnd, SW_HIDE);
  383. }
  384. }
  385. GlobalUnlock(hUIPrivate);
  386. ImmUnlockIMC(hIMC);
  387. return;
  388. }
  389. /**********************************************************************/
  390. /* SoftKbdDestryed() */
  391. /**********************************************************************/
  392. void PASCAL SoftKbdDestroyed( // soft keyboard window
  393. // already destroyed
  394. HWND hUIWnd)
  395. {
  396. HGLOBAL hUIPrivate;
  397. LPUIPRIV lpUIPrivate;
  398. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  399. if (!hUIPrivate) { // Oh! Oh!
  400. return;
  401. }
  402. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  403. if (!lpUIPrivate) { // Oh! Oh!
  404. return;
  405. }
  406. lpUIPrivate->hSoftKbdWnd = NULL;
  407. GlobalUnlock(hUIPrivate);
  408. }
  409. #endif
  410. /**********************************************************************/
  411. /* StatusWndMsg() */
  412. /**********************************************************************/
  413. void PASCAL StatusWndMsg( // set the show hide state and
  414. // show/hide the status window
  415. #if defined(UNIIME)
  416. LPINSTDATAL lpInstL,
  417. LPIMEL lpImeL,
  418. #endif
  419. HWND hUIWnd,
  420. BOOL fOn)
  421. {
  422. HGLOBAL hUIPrivate;
  423. HIMC hIMC;
  424. HWND hStatusWnd;
  425. register LPUIPRIV lpUIPrivate;
  426. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  427. if (!hUIPrivate) {
  428. return;
  429. }
  430. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  431. if (!lpUIPrivate) {
  432. return;
  433. }
  434. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  435. if (fOn) {
  436. lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
  437. if (!lpUIPrivate->hStatusWnd) {
  438. OpenStatus(
  439. #if defined(UNIIME)
  440. lpInstL, lpImeL,
  441. #endif
  442. hUIWnd);
  443. }
  444. } else {
  445. lpUIPrivate->fdwSetContext &= ~(ISC_OPEN_STATUS_WINDOW);
  446. }
  447. hStatusWnd = lpUIPrivate->hStatusWnd;
  448. GlobalUnlock(hUIPrivate);
  449. if (!hStatusWnd) {
  450. return;
  451. }
  452. if (!fOn) {
  453. #if !defined(ROMANIME)
  454. register DWORD fdwSetContext;
  455. fdwSetContext = lpUIPrivate->fdwSetContext &
  456. (ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);
  457. if (fdwSetContext == ISC_HIDE_COMP_WINDOW) {
  458. ShowComp(
  459. #if defined(UNIIME)
  460. lpImeL,
  461. #endif
  462. hUIWnd, SW_HIDE);
  463. }
  464. fdwSetContext = lpUIPrivate->fdwSetContext &
  465. (ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);
  466. if (fdwSetContext == ISC_HIDE_CAND_WINDOW) {
  467. ShowCand(
  468. #if defined(UNIIME)
  469. lpImeL,
  470. #endif
  471. hUIWnd, SW_HIDE);
  472. }
  473. #if !defined(WINAR30)
  474. fdwSetContext = lpUIPrivate->fdwSetContext &
  475. (ISC_SHOW_SOFTKBD|ISC_HIDE_SOFTKBD);
  476. if (fdwSetContext == ISC_HIDE_SOFTKBD) {
  477. lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
  478. ShowSoftKbd(hUIWnd, SW_HIDE);
  479. }
  480. #endif
  481. #endif
  482. ShowStatus(
  483. #if defined(UNIIME)
  484. lpImeL,
  485. #endif
  486. hUIWnd, SW_HIDE);
  487. } else if (hIMC) {
  488. ShowStatus(
  489. #if defined(UNIIME)
  490. lpImeL,
  491. #endif
  492. hUIWnd, SW_SHOWNOACTIVATE);
  493. } else {
  494. ShowStatus(
  495. #if defined(UNIIME)
  496. lpImeL,
  497. #endif
  498. hUIWnd, SW_HIDE);
  499. }
  500. return;
  501. }
  502. /**********************************************************************/
  503. /* ShowUI() */
  504. /**********************************************************************/
  505. void PASCAL ShowUI( // show the sub windows
  506. #if defined(UNIIME)
  507. LPINSTDATAL lpInstL,
  508. LPIMEL lpImeL,
  509. #endif
  510. HWND hUIWnd,
  511. int nShowCmd)
  512. {
  513. HIMC hIMC;
  514. LPINPUTCONTEXT lpIMC;
  515. LPPRIVCONTEXT lpImcP;
  516. HGLOBAL hUIPrivate;
  517. LPUIPRIV lpUIPrivate;
  518. if (nShowCmd == SW_HIDE) {
  519. } else if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))) {
  520. nShowCmd = SW_HIDE;
  521. } else if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  522. nShowCmd = SW_HIDE;
  523. } else if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
  524. ImmUnlockIMC(hIMC);
  525. nShowCmd = SW_HIDE;
  526. } else {
  527. }
  528. if (nShowCmd == SW_HIDE) {
  529. ShowStatus(
  530. #if defined(UNIIME)
  531. lpImeL,
  532. #endif
  533. hUIWnd, nShowCmd);
  534. #if !defined(ROMANIME)
  535. ShowComp(
  536. #if defined(UNIIME)
  537. lpImeL,
  538. #endif
  539. hUIWnd, nShowCmd);
  540. ShowCand(
  541. #if defined(UNIIME)
  542. lpImeL,
  543. #endif
  544. hUIWnd, nShowCmd);
  545. #if !defined(WINAR30)
  546. ShowSoftKbd(hUIWnd, nShowCmd);
  547. #endif
  548. #endif
  549. return;
  550. }
  551. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  552. if (!hUIPrivate) { // can not darw status window
  553. goto ShowUIUnlockIMCC;
  554. }
  555. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  556. if (!lpUIPrivate) { // can not draw status window
  557. goto ShowUIUnlockIMCC;
  558. }
  559. #if !defined(ROMANIME)
  560. if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW) &&
  561. (lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
  562. if (lpUIPrivate->hCompWnd) {
  563. if ((UINT)GetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_XY) !=
  564. lpImeL->nRevMaxKey) {
  565. ChangeCompositionSize(
  566. #if defined(UNIIME)
  567. lpImeL,
  568. #endif
  569. hUIWnd);
  570. }
  571. if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
  572. // some time the WM_ERASEBKGND is eaten by the app
  573. RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL,
  574. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  575. }
  576. SendMessage(lpUIPrivate->hCompWnd, WM_IME_NOTIFY,
  577. IMN_SETCOMPOSITIONWINDOW, 0);
  578. if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
  579. ShowComp(
  580. #if defined(UNIIME)
  581. lpImeL,
  582. #endif
  583. hUIWnd, nShowCmd);
  584. }
  585. } else {
  586. StartComp(
  587. #if defined(UNIIME)
  588. lpInstL, lpImeL,
  589. #endif
  590. hUIWnd);
  591. }
  592. } else if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
  593. } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  594. // delay the hide with status window
  595. lpUIPrivate->fdwSetContext |= ISC_HIDE_COMP_WINDOW;
  596. } else {
  597. ShowComp(
  598. #if defined(UNIIME)
  599. lpImeL,
  600. #endif
  601. hUIWnd, SW_HIDE);
  602. }
  603. if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW) &&
  604. (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)) {
  605. if (lpUIPrivate->hCandWnd) {
  606. if (lpUIPrivate->nShowCandCmd != SW_HIDE) {
  607. // some time the WM_ERASEBKGND is eaten by the app
  608. RedrawWindow(lpUIPrivate->hCandWnd, NULL, NULL,
  609. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  610. }
  611. SendMessage(lpUIPrivate->hCandWnd, WM_IME_NOTIFY,
  612. IMN_SETCANDIDATEPOS, 0x0001);
  613. if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
  614. ShowCand(
  615. #if defined(UNIIME)
  616. lpImeL,
  617. #endif
  618. hUIWnd, nShowCmd);
  619. }
  620. } else {
  621. OpenCand(
  622. #if defined(UNIIME)
  623. lpInstL, lpImeL,
  624. #endif
  625. hUIWnd);
  626. }
  627. } else if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
  628. } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  629. // delay the hide with status window
  630. lpUIPrivate->fdwSetContext |= ISC_HIDE_CAND_WINDOW;
  631. } else {
  632. ShowCand(
  633. #if defined(UNIIME)
  634. lpImeL,
  635. #endif
  636. hUIWnd, SW_HIDE);
  637. }
  638. if (lpIMC->fdwInit & INIT_SENTENCE) {
  639. // app set the sentence mode so we should not change it
  640. // with the configure option set by end user
  641. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) {
  642. if (!(lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT)) {
  643. DWORD fdwSentence;
  644. fdwSentence = lpIMC->fdwSentence;
  645. *(LPWORD)&fdwSentence |= IME_SMODE_PHRASEPREDICT;
  646. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
  647. }
  648. } else {
  649. if (lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT) {
  650. DWORD fdwSentence;
  651. fdwSentence = lpIMC->fdwSentence;
  652. *(LPWORD)&fdwSentence &= ~(IME_SMODE_PHRASEPREDICT);
  653. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
  654. }
  655. }
  656. #endif
  657. if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  658. if (!lpUIPrivate->hStatusWnd) {
  659. OpenStatus(
  660. #if defined(UNIIME)
  661. lpInstL, lpImeL,
  662. #endif
  663. hUIWnd);
  664. }
  665. if (lpUIPrivate->nShowStatusCmd != SW_HIDE) {
  666. // some time the WM_ERASEBKGND is eaten by the app
  667. RedrawWindow(lpUIPrivate->hStatusWnd, NULL, NULL,
  668. RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
  669. }
  670. SendMessage(lpUIPrivate->hStatusWnd, WM_IME_NOTIFY,
  671. IMN_SETSTATUSWINDOWPOS, 0);
  672. if (lpUIPrivate->nShowStatusCmd == SW_HIDE) {
  673. ShowStatus(
  674. #if defined(UNIIME)
  675. lpImeL,
  676. #endif
  677. hUIWnd, nShowCmd);
  678. }
  679. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  680. if (!lpUIPrivate->hStatusWnd) {
  681. #if !defined(ROMANIME)
  682. } else if (lpUIPrivate->hCompWnd || lpUIPrivate->hCandWnd) {
  683. int nCurrShowState;
  684. RECT rcRect;
  685. nCurrShowState = lpUIPrivate->nShowCompCmd;
  686. nCurrShowState |= lpUIPrivate->nShowCandCmd;
  687. if (nCurrShowState == SW_HIDE) {
  688. ShowStatus(
  689. #if defined(UNIIME)
  690. lpImeL,
  691. #endif
  692. hUIWnd, SW_HIDE);
  693. }
  694. rcRect = lpImeL->rcStatusText;
  695. // off by 1
  696. rcRect.right += 1;
  697. rcRect.bottom += 1;
  698. RedrawWindow(lpUIPrivate->hStatusWnd, &rcRect, NULL,
  699. RDW_FRAME|RDW_INVALIDATE);
  700. DestroyStatusWindow(lpUIPrivate->hStatusWnd);
  701. #endif
  702. } else {
  703. DestroyWindow(lpUIPrivate->hStatusWnd);
  704. }
  705. } else if (lpUIPrivate->hStatusWnd) {
  706. DestroyWindow(lpUIPrivate->hStatusWnd);
  707. } else {
  708. }
  709. #if !defined(ROMANIME)
  710. #if defined(WINAR30)
  711. if (lpImcP->iImeState == CST_INIT) {
  712. } else if (lpImcP->iImeState == CST_CHOOSE) {
  713. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_QUICK_KEY) {
  714. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  715. // turn off quick key candidate
  716. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  717. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  718. GenerateMessage(hIMC, lpIMC, lpImcP);
  719. } else if (lpImcP->fdwImeMsg & (MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE)) {
  720. // turn off quick key candidate
  721. lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  722. } else {
  723. }
  724. #else
  725. if (!lpIMC->fOpen) {
  726. if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
  727. ShowSoftKbd(hUIWnd, SW_HIDE);
  728. }
  729. } else if ((lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) &&
  730. (lpIMC->fdwConversion & (IME_CMODE_NATIVE|IME_CMODE_CHARCODE|
  731. IME_CMODE_NOCONVERSION|IME_CMODE_SOFTKBD)) ==
  732. (IME_CMODE_NATIVE|IME_CMODE_SOFTKBD)) {
  733. if (!lpUIPrivate->hSoftKbdWnd) {
  734. UpdateSoftKbd(
  735. #if defined(UNIIME)
  736. lpImeL,
  737. #endif
  738. hUIWnd);
  739. #if defined(PHON)
  740. } else if ((UINT)SendMessage(lpUIPrivate->hSoftKbdWnd,
  741. WM_IME_CONTROL, IMC_GETSOFTKBDSUBTYPE, 0) !=
  742. lpImeL->nReadLayout) {
  743. UpdateSoftKbd(hUIWnd);
  744. #endif
  745. } else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
  746. ShowSoftKbd(hUIWnd, nShowCmd);
  747. } else if (lpUIPrivate->hCacheIMC != hIMC) {
  748. UpdateSoftKbd(
  749. #if defined(UNIIME)
  750. lpImeL,
  751. #endif
  752. hUIWnd);
  753. } else {
  754. RedrawWindow(lpUIPrivate->hSoftKbdWnd, NULL, NULL,
  755. RDW_FRAME|RDW_INVALIDATE);
  756. }
  757. } else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
  758. } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  759. // delay the hide with status window
  760. lpUIPrivate->fdwSetContext |= ISC_HIDE_SOFTKBD;
  761. } else {
  762. ShowSoftKbd(hUIWnd, SW_HIDE);
  763. }
  764. #endif
  765. #endif
  766. // we switch to this hIMC
  767. lpUIPrivate->hCacheIMC = hIMC;
  768. GlobalUnlock(hUIPrivate);
  769. ShowUIUnlockIMCC:
  770. ImmUnlockIMCC(lpIMC->hPrivate);
  771. ImmUnlockIMC(hIMC);
  772. return;
  773. }
  774. /**********************************************************************/
  775. /* ShowGuideLine */
  776. /**********************************************************************/
  777. void PASCAL ShowGuideLine(
  778. #if defined(UNIIME)
  779. LPIMEL lpImeL,
  780. #endif
  781. HWND hUIWnd)
  782. {
  783. HIMC hIMC;
  784. LPINPUTCONTEXT lpIMC;
  785. LPGUIDELINE lpGuideLine;
  786. #if !defined(ROMANIME)
  787. HWND hCompWnd;
  788. #endif
  789. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  790. if (!hIMC) {
  791. return;
  792. }
  793. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  794. if (!lpIMC) {
  795. return;
  796. }
  797. lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
  798. if (!lpGuideLine) {
  799. } else if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
  800. MessageBeep((UINT)-1);
  801. MessageBeep((UINT)-1);
  802. } else if (lpGuideLine->dwLevel == GL_LEVEL_WARNING) {
  803. MessageBeep((UINT)-1);
  804. #if !defined(ROMANIME)
  805. } else if (hCompWnd = GetCompWnd(hUIWnd)) {
  806. RECT rcRect;
  807. rcRect = lpImeL->rcCompText;
  808. // off by 1
  809. rcRect.right += 1;
  810. rcRect.bottom += 1;
  811. RedrawWindow(hCompWnd, &rcRect, NULL, RDW_INVALIDATE);
  812. #endif
  813. } else {
  814. }
  815. ImmUnlockIMCC(lpIMC->hGuideLine);
  816. ImmUnlockIMC(hIMC);
  817. return;
  818. }
  819. #if !defined(ROMANIME)
  820. /**********************************************************************/
  821. /* UpdatePhrasePrediction() */
  822. /**********************************************************************/
  823. void PASCAL UpdatePhrasePrediction(
  824. #if defined(UNIIME)
  825. LPIMEL lpImeL,
  826. #endif
  827. HWND hUIWnd)
  828. {
  829. HIMC hIMC;
  830. LPINPUTCONTEXT lpIMC;
  831. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  832. if (!hIMC) {
  833. return;
  834. }
  835. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  836. if (!lpIMC) {
  837. return;
  838. }
  839. if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) {
  840. if (!(lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT)) {
  841. DWORD fdwSentence;
  842. fdwSentence = lpIMC->fdwSentence;
  843. *(LPWORD)&fdwSentence |= IME_SMODE_PHRASEPREDICT;
  844. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
  845. }
  846. } else {
  847. if (lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT) {
  848. DWORD fdwSentence;
  849. fdwSentence = lpIMC->fdwSentence;
  850. *(LPWORD)&fdwSentence &= ~(IME_SMODE_PHRASEPREDICT);
  851. ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
  852. }
  853. }
  854. ImmUnlockIMC(hIMC);
  855. return;
  856. }
  857. #if defined(WINAR30)
  858. /**********************************************************************/
  859. /* UpdateQuickKey() */
  860. /**********************************************************************/
  861. void PASCAL UpdateQuickKey(
  862. HWND hUIWnd)
  863. {
  864. HIMC hIMC;
  865. LPINPUTCONTEXT lpIMC;
  866. LPPRIVCONTEXT lpImcP;
  867. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  868. if (!hIMC) {
  869. return;
  870. }
  871. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  872. if (!lpIMC) {
  873. return;
  874. }
  875. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  876. if (lpImcP) {
  877. if (lpImcP->iImeState == CST_INIT) {
  878. } else if (lpImcP->iImeState == CST_CHOOSE) {
  879. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_QUICK_KEY) {
  880. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  881. // turn off quick key candidate
  882. lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
  883. ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  884. GenerateMessage(hIMC, lpIMC, lpImcP);
  885. } else if (lpImcP->fdwImeMsg & (MSG_OPEN_CANDIDATE|
  886. MSG_CHANGE_CANDIDATE)) {
  887. // turn off quick key candidate
  888. lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
  889. } else {
  890. }
  891. ImmUnlockIMCC(lpIMC->hPrivate);
  892. }
  893. ImmUnlockIMC(hIMC);
  894. return;
  895. }
  896. #endif
  897. #endif
  898. /**********************************************************************/
  899. /* CMenuDestryed() */
  900. /**********************************************************************/
  901. void PASCAL CMenuDestroyed( // context menu window
  902. // already destroyed
  903. HWND hUIWnd)
  904. {
  905. HGLOBAL hUIPrivate;
  906. LPUIPRIV lpUIPrivate;
  907. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  908. if (!hUIPrivate) { // Oh! Oh!
  909. return;
  910. }
  911. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  912. if (!lpUIPrivate) { // Oh! Oh!
  913. return;
  914. }
  915. lpUIPrivate->hCMenuWnd = NULL;
  916. GlobalUnlock(hUIPrivate);
  917. }
  918. /**********************************************************************/
  919. /* ToggleUI() */
  920. /**********************************************************************/
  921. void PASCAL ToggleUI(
  922. #if defined(UNIIME)
  923. LPINSTDATAL lpInstL,
  924. LPIMEL lpImeL,
  925. #endif
  926. HWND hUIWnd)
  927. {
  928. HGLOBAL hUIPrivate;
  929. LPUIPRIV lpUIPrivate;
  930. DWORD fdwFlag;
  931. HIMC hIMC;
  932. LPINPUTCONTEXT lpIMC;
  933. LPPRIVCONTEXT lpImcP;
  934. HWND hDestroyWnd;
  935. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  936. if (!hUIPrivate) {
  937. return;
  938. }
  939. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  940. if (!lpUIPrivate) {
  941. return;
  942. }
  943. if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
  944. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  945. goto ToggleUIOvr;
  946. } else {
  947. fdwFlag = 0;
  948. }
  949. } else {
  950. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  951. fdwFlag = ISC_OFF_CARET_UI;
  952. } else {
  953. goto ToggleUIOvr;
  954. }
  955. }
  956. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  957. if (!hIMC) {
  958. goto ToggleUIOvr;
  959. }
  960. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  961. if (!lpIMC) {
  962. goto ToggleUIOvr;
  963. }
  964. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  965. if (!lpImcP) {
  966. goto CreateUIOvr;
  967. }
  968. if (fdwFlag & ISC_OFF_CARET_UI) {
  969. lpUIPrivate->fdwSetContext |= (ISC_OFF_CARET_UI);
  970. } else {
  971. lpUIPrivate->fdwSetContext &= ~(ISC_OFF_CARET_UI);
  972. }
  973. hDestroyWnd = NULL;
  974. // we need to dsetroy status first because lpUIPrivate->hStatusWnd
  975. // may be NULL out in OffCreat UI destroy time
  976. if (lpUIPrivate->hStatusWnd) {
  977. if (lpUIPrivate->hStatusWnd != hDestroyWnd) {
  978. hDestroyWnd = lpUIPrivate->hStatusWnd;
  979. DestroyWindow(lpUIPrivate->hStatusWnd);
  980. }
  981. lpUIPrivate->hStatusWnd = NULL;
  982. }
  983. #if !defined(ROMANIME)
  984. // destroy all off caret UI
  985. if (lpUIPrivate->hCompWnd) {
  986. if (lpUIPrivate->hCompWnd != hDestroyWnd) {
  987. hDestroyWnd = lpUIPrivate->hCompWnd;
  988. DestroyWindow(lpUIPrivate->hCompWnd);
  989. }
  990. lpUIPrivate->hCompWnd = NULL;
  991. lpUIPrivate->nShowCompCmd = SW_HIDE;
  992. }
  993. if (lpUIPrivate->hCandWnd) {
  994. if (lpUIPrivate->hCandWnd != hDestroyWnd) {
  995. hDestroyWnd = lpUIPrivate->hCandWnd;
  996. DestroyWindow(lpUIPrivate->hCandWnd);
  997. }
  998. lpUIPrivate->hCandWnd = NULL;
  999. lpUIPrivate->nShowCandCmd = SW_HIDE;
  1000. }
  1001. #endif
  1002. if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
  1003. OpenStatus(
  1004. #if defined(UNIIME)
  1005. lpInstL, lpImeL,
  1006. #endif
  1007. hUIWnd);
  1008. }
  1009. #if !defined(ROMANIME)
  1010. if (!(lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW)) {
  1011. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
  1012. StartComp(
  1013. #if defined(UNIIME)
  1014. lpInstL, lpImeL,
  1015. #endif
  1016. hUIWnd);
  1017. } else {
  1018. }
  1019. if (!(lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW)) {
  1020. } else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
  1021. if (!(fdwFlag & ISC_OFF_CARET_UI)) {
  1022. #if defined(UNIIME)
  1023. UniNotifyIME(lpInstL, lpImeL, hIMC, NI_SETCANDIDATE_PAGESIZE,
  1024. 0, CANDPERPAGE);
  1025. #else
  1026. NotifyIME(hIMC, NI_SETCANDIDATE_PAGESIZE, 0, CANDPERPAGE);
  1027. #endif
  1028. }
  1029. OpenCand(
  1030. #if defined(UNIIME)
  1031. lpInstL, lpImeL,
  1032. #endif
  1033. hUIWnd);
  1034. } else {
  1035. }
  1036. #if !defined(WINAR30)
  1037. if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)) {
  1038. } else if (!lpUIPrivate->hSoftKbdWnd) {
  1039. } else {
  1040. HWND hInsertWnd;
  1041. if (lpUIPrivate->hStatusWnd) {
  1042. hInsertWnd = lpUIPrivate->hStatusWnd;
  1043. } else if (lpUIPrivate->hCompWnd) {
  1044. hInsertWnd = lpUIPrivate->hCompWnd;
  1045. } else if (lpUIPrivate->hCandWnd) {
  1046. hInsertWnd = lpUIPrivate->hCandWnd;
  1047. } else {
  1048. hInsertWnd = NULL;
  1049. }
  1050. if (hInsertWnd) {
  1051. // insert soft keyboard in front of other UI
  1052. SetWindowPos(hInsertWnd, lpUIPrivate->hSoftKbdWnd,
  1053. 0, 0, 0, 0,
  1054. SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
  1055. }
  1056. }
  1057. #endif
  1058. #endif
  1059. ImmUnlockIMCC(lpIMC->hPrivate);
  1060. CreateUIOvr:
  1061. ImmUnlockIMC(hIMC);
  1062. ToggleUIOvr:
  1063. GlobalUnlock(hUIPrivate);
  1064. return;
  1065. }
  1066. /**********************************************************************/
  1067. /* NotifyUI() */
  1068. /**********************************************************************/
  1069. void PASCAL NotifyUI(
  1070. #if defined(UNIIME)
  1071. LPINSTDATAL lpInstL,
  1072. LPIMEL lpImeL,
  1073. #endif
  1074. HWND hUIWnd,
  1075. WPARAM wParam,
  1076. LPARAM lParam)
  1077. {
  1078. HWND hStatusWnd;
  1079. switch (wParam) {
  1080. case IMN_OPENSTATUSWINDOW:
  1081. StatusWndMsg(
  1082. #if defined(UNIIME)
  1083. lpInstL, lpImeL,
  1084. #endif
  1085. hUIWnd, TRUE);
  1086. break;
  1087. case IMN_CLOSESTATUSWINDOW:
  1088. StatusWndMsg(
  1089. #if defined(UNIIME)
  1090. lpInstL, lpImeL,
  1091. #endif
  1092. hUIWnd, FALSE);
  1093. break;
  1094. #if !defined(ROMANIME)
  1095. case IMN_OPENCANDIDATE:
  1096. if (lParam & 0x00000001) {
  1097. OpenCand(
  1098. #if defined(UNIIME)
  1099. lpInstL, lpImeL,
  1100. #endif
  1101. hUIWnd);
  1102. }
  1103. break;
  1104. case IMN_CHANGECANDIDATE:
  1105. if (lParam & 0x00000001) {
  1106. HWND hCandWnd;
  1107. RECT rcRect;
  1108. hCandWnd = GetCandWnd(hUIWnd);
  1109. if (!hCandWnd) {
  1110. return;
  1111. }
  1112. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1113. CandPageSize(hUIWnd, TRUE);
  1114. }
  1115. rcRect = lpImeL->rcCandText;
  1116. // off by 1
  1117. rcRect.right += 1;
  1118. rcRect.bottom += 1;
  1119. InvalidateRect(hCandWnd, &rcRect, FALSE);
  1120. rcRect = lpImeL->rcCandPrompt;
  1121. // off by 1
  1122. rcRect.right += 1;
  1123. rcRect.bottom += 1;
  1124. InvalidateRect(hCandWnd, &rcRect, TRUE);
  1125. rcRect = lpImeL->rcCandPageText;
  1126. // off by 1
  1127. rcRect.right += 1;
  1128. rcRect.bottom += 1;
  1129. RedrawWindow(hCandWnd, &rcRect, NULL, RDW_INVALIDATE|RDW_ERASE);
  1130. }
  1131. break;
  1132. case IMN_CLOSECANDIDATE:
  1133. if (lParam & 0x00000001) {
  1134. CloseCand(
  1135. #if defined(UNIIME)
  1136. lpImeL,
  1137. #endif
  1138. hUIWnd);
  1139. }
  1140. break;
  1141. case IMN_SETSENTENCEMODE:
  1142. break;
  1143. #endif
  1144. case IMN_SETOPENSTATUS:
  1145. case IMN_SETCONVERSIONMODE:
  1146. hStatusWnd = GetStatusWnd(hUIWnd);
  1147. if (!hStatusWnd) {
  1148. return;
  1149. }
  1150. {
  1151. RECT rcRect;
  1152. rcRect = lpImeL->rcStatusText;
  1153. // off by 1
  1154. rcRect.right += 1;
  1155. rcRect.bottom += 1;
  1156. RedrawWindow(hStatusWnd, &rcRect, NULL, RDW_INVALIDATE);
  1157. }
  1158. break;
  1159. #if !defined(ROMANIME)
  1160. case IMN_SETCOMPOSITIONFONT:
  1161. // we are not going to change font, but an IME can do this if it want
  1162. break;
  1163. case IMN_SETCOMPOSITIONWINDOW:
  1164. if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)) {
  1165. HWND hCompWnd;
  1166. hCompWnd = GetCompWnd(hUIWnd);
  1167. if (!hCompWnd) {
  1168. return;
  1169. }
  1170. PostMessage(hCompWnd, WM_IME_NOTIFY, wParam, lParam);
  1171. }
  1172. break;
  1173. case IMN_SETCANDIDATEPOS:
  1174. if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)) {
  1175. HWND hCandWnd;
  1176. hCandWnd = GetCandWnd(hUIWnd);
  1177. if (!hCandWnd) {
  1178. return;
  1179. }
  1180. PostMessage(hCandWnd, WM_IME_NOTIFY, wParam, lParam);
  1181. }
  1182. break;
  1183. #endif
  1184. case IMN_SETSTATUSWINDOWPOS:
  1185. hStatusWnd = GetStatusWnd(hUIWnd);
  1186. if (hStatusWnd) {
  1187. PostMessage(hStatusWnd, WM_IME_NOTIFY, wParam, lParam);
  1188. #if !defined(ROMANIME)
  1189. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1190. if (hStatusWnd = GetCompWnd(hUIWnd)) {
  1191. } else if (hStatusWnd = GetCandWnd(hUIWnd)) {
  1192. } else {
  1193. return;
  1194. }
  1195. PostMessage(hStatusWnd, WM_IME_NOTIFY, wParam, lParam);
  1196. #endif
  1197. } else {
  1198. }
  1199. break;
  1200. case IMN_GUIDELINE:
  1201. ShowGuideLine(
  1202. #if defined(UNIIME)
  1203. lpImeL,
  1204. #endif
  1205. hUIWnd);
  1206. break;
  1207. case IMN_PRIVATE:
  1208. switch (lParam) {
  1209. #if !defined(ROMANIME)
  1210. case IMN_PRIVATE_COMPOSITION_SIZE:
  1211. ChangeCompositionSize(
  1212. #if defined(UNIIME)
  1213. lpImeL,
  1214. #endif
  1215. hUIWnd);
  1216. break;
  1217. case IMN_PRIVATE_UPDATE_PREDICT:
  1218. UpdatePhrasePrediction(
  1219. #if defined(UNIIME)
  1220. lpImeL,
  1221. #endif
  1222. hUIWnd);
  1223. break;
  1224. case IMN_PRIVATE_PAGEUP:
  1225. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1226. CandPageSize(hUIWnd, FALSE);
  1227. }
  1228. break;
  1229. #if defined(WINAR30)
  1230. case IMN_PRIVATE_UPDATE_QUICK_KEY:
  1231. UpdateQuickKey(hUIWnd);
  1232. break;
  1233. #else
  1234. case IMN_PRIVATE_UPDATE_SOFTKBD:
  1235. UpdateSoftKbd(
  1236. #if defined(UNIIME)
  1237. lpImeL,
  1238. #endif
  1239. hUIWnd);
  1240. break;
  1241. #endif
  1242. #endif
  1243. case IMN_PRIVATE_TOGGLE_UI:
  1244. ToggleUI(
  1245. #if defined(UNIIME)
  1246. lpInstL, lpImeL,
  1247. #endif
  1248. hUIWnd);
  1249. break;
  1250. case IMN_PRIVATE_CMENUDESTROYED:
  1251. CMenuDestroyed(hUIWnd);
  1252. break;
  1253. default:
  1254. break;
  1255. }
  1256. break;
  1257. #if !defined(ROMANIME) && !defined(WINAR30)
  1258. case IMN_SOFTKBDDESTROYED:
  1259. SoftKbdDestroyed(hUIWnd);
  1260. break;
  1261. #endif
  1262. default:
  1263. break;
  1264. }
  1265. return;
  1266. }
  1267. /**********************************************************************/
  1268. /* UIChange() */
  1269. /**********************************************************************/
  1270. LRESULT PASCAL UIChange(
  1271. #if defined(UNIIME)
  1272. LPINSTDATAL lpInstL,
  1273. LPIMEL lpImeL,
  1274. #endif
  1275. HWND hUIWnd)
  1276. {
  1277. HGLOBAL hUIPrivate;
  1278. LPUIPRIV lpUIPrivate;
  1279. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  1280. if (!hUIPrivate) {
  1281. return (0L);
  1282. }
  1283. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  1284. if (!lpUIPrivate) {
  1285. return (0L);
  1286. }
  1287. if (lpUIPrivate->fdwSetContext & ISC_SHOW_UI_ALL) {
  1288. if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
  1289. if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)) {
  1290. ToggleUI(
  1291. #if defined(UNIIME)
  1292. lpInstL, lpImeL,
  1293. #endif
  1294. hUIWnd);
  1295. }
  1296. } else {
  1297. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1298. ToggleUI(
  1299. #if defined(UNIIME)
  1300. lpInstL, lpImeL,
  1301. #endif
  1302. hUIWnd);
  1303. }
  1304. }
  1305. ShowUI(
  1306. #if defined(UNIIME)
  1307. lpInstL, lpImeL,
  1308. #endif
  1309. hUIWnd, SW_SHOWNOACTIVATE);
  1310. } else {
  1311. ShowUI(
  1312. #if defined(UNIIME)
  1313. lpInstL, lpImeL,
  1314. #endif
  1315. hUIWnd, SW_HIDE);
  1316. }
  1317. GlobalUnlock(hUIPrivate);
  1318. return (0L);
  1319. }
  1320. /**********************************************************************/
  1321. /* SetContext() */
  1322. /**********************************************************************/
  1323. void PASCAL SetContext( // the context activated/deactivated
  1324. #if defined(UNIIME)
  1325. LPINSTDATAL lpInstL,
  1326. LPIMEL lpImeL,
  1327. #endif
  1328. HWND hUIWnd,
  1329. BOOL fOn,
  1330. LPARAM lShowUI)
  1331. {
  1332. HGLOBAL hUIPrivate;
  1333. register LPUIPRIV lpUIPrivate;
  1334. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  1335. if (!hUIPrivate) {
  1336. return;
  1337. }
  1338. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  1339. if (!lpUIPrivate) {
  1340. return;
  1341. }
  1342. if (fOn) {
  1343. HIMC hIMC;
  1344. LPINPUTCONTEXT lpIMC;
  1345. #if !defined(ROMANIME)
  1346. register DWORD fdwSetContext;
  1347. lpUIPrivate->fdwSetContext = lpUIPrivate->fdwSetContext &
  1348. ~(ISC_SHOWUIALL|ISC_HIDE_SOFTKBD);
  1349. lpUIPrivate->fdwSetContext |= (lShowUI & ISC_SHOWUIALL) |
  1350. ISC_SHOW_SOFTKBD;
  1351. fdwSetContext = lpUIPrivate->fdwSetContext &
  1352. (ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);
  1353. if (fdwSetContext == ISC_HIDE_COMP_WINDOW) {
  1354. ShowComp(
  1355. #if defined(UNIIME)
  1356. lpImeL,
  1357. #endif
  1358. hUIWnd, SW_HIDE);
  1359. } else if (fdwSetContext & ISC_HIDE_COMP_WINDOW) {
  1360. lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_COMP_WINDOW);
  1361. } else {
  1362. }
  1363. fdwSetContext = lpUIPrivate->fdwSetContext &
  1364. (ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);
  1365. if (fdwSetContext == ISC_HIDE_CAND_WINDOW) {
  1366. ShowCand(
  1367. #if defined(UNIIME)
  1368. lpImeL,
  1369. #endif
  1370. hUIWnd, SW_HIDE);
  1371. } else if (fdwSetContext & ISC_HIDE_CAND_WINDOW) {
  1372. lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_CAND_WINDOW);
  1373. } else {
  1374. }
  1375. #endif
  1376. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1377. if (!hIMC) {
  1378. goto SetCxtUnlockUIPriv;
  1379. }
  1380. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1381. if (!lpIMC) {
  1382. goto SetCxtUnlockUIPriv;
  1383. }
  1384. if (lpIMC->cfCandForm[0].dwIndex != 0) {
  1385. lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
  1386. }
  1387. ImmUnlockIMC(hIMC);
  1388. } else {
  1389. lpUIPrivate->fdwSetContext &= ~ISC_SETCONTEXT_UI;
  1390. }
  1391. SetCxtUnlockUIPriv:
  1392. GlobalUnlock(hUIPrivate);
  1393. UIChange(
  1394. #if defined(UNIIME)
  1395. lpInstL, lpImeL,
  1396. #endif
  1397. hUIWnd);
  1398. return;
  1399. }
  1400. #if !defined(ROMANIME)
  1401. /**********************************************************************/
  1402. /* GetCandPos() */
  1403. /**********************************************************************/
  1404. LRESULT PASCAL GetCandPos(
  1405. HWND hUIWnd,
  1406. LPCANDIDATEFORM lpCandForm)
  1407. {
  1408. HWND hCandWnd;
  1409. RECT rcCandWnd;
  1410. HIMC hIMC;
  1411. LPINPUTCONTEXT lpIMC;
  1412. if (lpCandForm->dwIndex != 0) {
  1413. return (1L);
  1414. }
  1415. hCandWnd = GetCandWnd(hUIWnd);
  1416. if (!hCandWnd) {
  1417. return (1L);
  1418. }
  1419. if (!GetWindowRect(hCandWnd, &rcCandWnd)) {
  1420. return (1L);
  1421. }
  1422. lpCandForm->dwStyle = CFS_CANDIDATEPOS;
  1423. lpCandForm->ptCurrentPos = *(LPPOINT)&rcCandWnd;
  1424. lpCandForm->rcArea = rcCandWnd;
  1425. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1426. if (!hIMC) {
  1427. return (1L);
  1428. }
  1429. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1430. if (!lpIMC) {
  1431. return (1L);
  1432. }
  1433. ScreenToClient(lpIMC->hWnd, &lpCandForm->ptCurrentPos);
  1434. lpCandForm->rcArea.right += lpCandForm->ptCurrentPos.x -
  1435. lpCandForm->rcArea.left;
  1436. lpCandForm->rcArea.bottom += lpCandForm->ptCurrentPos.y -
  1437. lpCandForm->rcArea.top;
  1438. *(LPPOINT)&lpCandForm->rcArea = lpCandForm->ptCurrentPos;
  1439. ImmUnlockIMC(hIMC);
  1440. return (0L);
  1441. }
  1442. /**********************************************************************/
  1443. /* GetCompWindow() */
  1444. /**********************************************************************/
  1445. LRESULT PASCAL GetCompWindow(
  1446. HWND hUIWnd,
  1447. LPCOMPOSITIONFORM lpCompForm)
  1448. {
  1449. HWND hCompWnd;
  1450. RECT rcCompWnd;
  1451. HIMC hIMC;
  1452. LPINPUTCONTEXT lpIMC;
  1453. hCompWnd = GetCompWnd(hUIWnd);
  1454. if (!hCompWnd) {
  1455. return (1L);
  1456. }
  1457. if (!GetWindowRect(hCompWnd, &rcCompWnd)) {
  1458. return (1L);
  1459. }
  1460. lpCompForm->dwStyle = CFS_RECT;
  1461. lpCompForm->ptCurrentPos = *(LPPOINT)&rcCompWnd;
  1462. lpCompForm->rcArea = rcCompWnd;
  1463. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  1464. if (!hIMC) {
  1465. return (1L);
  1466. }
  1467. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  1468. if (!lpIMC) {
  1469. return (1L);
  1470. }
  1471. ScreenToClient(lpIMC->hWnd, &lpCompForm->ptCurrentPos);
  1472. lpCompForm->rcArea.right += lpCompForm->ptCurrentPos.x -
  1473. lpCompForm->rcArea.left;
  1474. lpCompForm->rcArea.bottom += lpCompForm->ptCurrentPos.y -
  1475. lpCompForm->rcArea.top;
  1476. *(LPPOINT)&lpCompForm->rcArea = lpCompForm->ptCurrentPos;
  1477. ImmUnlockIMC(hIMC);
  1478. return (0L);
  1479. }
  1480. #endif
  1481. #if 0 // try to use SetContext
  1482. /**********************************************************************/
  1483. /* SelectIME() */
  1484. /**********************************************************************/
  1485. void PASCAL SelectIME( // switch IMEs
  1486. HWND hUIWnd,
  1487. BOOL fSelect)
  1488. {
  1489. #if !defined(ROMANIME)
  1490. if (!fSelect) {
  1491. ShowUI(hUIWnd, SW_HIDE);
  1492. } else {
  1493. ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
  1494. }
  1495. #endif
  1496. return;
  1497. }
  1498. #endif
  1499. /**********************************************************************/
  1500. /* UIWndProc() / UniUIWndProc() */
  1501. /**********************************************************************/
  1502. #if defined(UNIIME)
  1503. LRESULT WINAPI UniUIWndProc(
  1504. LPINSTDATAL lpInstL,
  1505. LPIMEL lpImeL,
  1506. #else
  1507. LRESULT CALLBACK UIWndProc(
  1508. #endif
  1509. HWND hUIWnd,
  1510. UINT uMsg,
  1511. WPARAM wParam,
  1512. LPARAM lParam)
  1513. {
  1514. switch (uMsg) {
  1515. case WM_CREATE:
  1516. CreateUIWindow(
  1517. #if defined(UNIIME)
  1518. lpImeL,
  1519. #endif
  1520. hUIWnd);
  1521. break;
  1522. case WM_DESTROY:
  1523. DestroyUIWindow(hUIWnd);
  1524. break;
  1525. #if !defined(ROMANIME)
  1526. case WM_IME_STARTCOMPOSITION:
  1527. // you can create a window as the composition window here
  1528. StartComp(
  1529. #if defined(UNIIME)
  1530. lpInstL, lpImeL,
  1531. #endif
  1532. hUIWnd);
  1533. break;
  1534. case WM_IME_COMPOSITION:
  1535. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  1536. } else if (lParam & GCS_RESULTSTR) {
  1537. MoveDefaultCompPosition(
  1538. #if defined(UNIIME)
  1539. lpImeL,
  1540. #endif
  1541. hUIWnd);
  1542. } else {
  1543. }
  1544. {
  1545. HWND hCompWnd;
  1546. hCompWnd = GetCompWnd(hUIWnd);
  1547. if (hCompWnd) {
  1548. RECT rcRect;
  1549. rcRect = lpImeL->rcCompText;
  1550. // off by 1
  1551. rcRect.right += 1;
  1552. rcRect.bottom += 1;
  1553. RedrawWindow(hCompWnd, &rcRect, NULL, RDW_INVALIDATE);
  1554. }
  1555. }
  1556. break;
  1557. case WM_IME_ENDCOMPOSITION:
  1558. // you can destroy the composition window here
  1559. EndComp(
  1560. #if defined(UNIIME)
  1561. lpImeL,
  1562. #endif
  1563. hUIWnd);
  1564. break;
  1565. #else
  1566. //We shouldn't pass messages below. For FullShape IME.
  1567. case WM_IME_STARTCOMPOSITION:
  1568. case WM_IME_COMPOSITION:
  1569. case WM_IME_ENDCOMPOSITION:
  1570. return (0L);
  1571. #endif
  1572. case WM_IME_NOTIFY:
  1573. NotifyUI(
  1574. #if defined(UNIIME)
  1575. lpInstL, lpImeL,
  1576. #endif
  1577. hUIWnd, wParam, lParam);
  1578. break;
  1579. case WM_IME_SETCONTEXT:
  1580. SetContext(
  1581. #if defined(UNIIME)
  1582. lpInstL, lpImeL,
  1583. #endif
  1584. hUIWnd, (BOOL)wParam, lParam);
  1585. /*
  1586. // When dialog box is opened, IME is disappeded. Change IME Z-order again. bklee
  1587. if (wParam && GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))
  1588. SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOMOVE);
  1589. */
  1590. break;
  1591. case WM_IME_CONTROL:
  1592. switch (wParam) {
  1593. #if !defined(ROMANIME)
  1594. case IMC_GETCANDIDATEPOS:
  1595. return GetCandPos(hUIWnd, (LPCANDIDATEFORM)lParam);
  1596. case IMC_GETCOMPOSITIONWINDOW:
  1597. return GetCompWindow(hUIWnd, (LPCOMPOSITIONFORM)lParam);
  1598. #endif
  1599. case IMC_GETSOFTKBDPOS:
  1600. case IMC_SETSOFTKBDPOS:
  1601. #if !defined(ROMANIME) && !defined(WINAR30)
  1602. {
  1603. HWND hSoftKbdWnd;
  1604. hSoftKbdWnd = GetSoftKbdWnd(hUIWnd);
  1605. if (!hSoftKbdWnd) {
  1606. return (0L); // fail, return (0, 0)?
  1607. }
  1608. return SendMessage(hSoftKbdWnd, WM_IME_CONTROL,
  1609. wParam, lParam);
  1610. }
  1611. #endif
  1612. return (0L);
  1613. case IMC_GETSTATUSWINDOWPOS:
  1614. #if !defined(ROMANIME)
  1615. {
  1616. HWND hStatusWnd;
  1617. RECT rcStatusWnd;
  1618. LPARAM lParam;
  1619. hStatusWnd = GetStatusWnd(hUIWnd);
  1620. if (!hStatusWnd) {
  1621. return (0L); // fail, return (0, 0)?
  1622. }
  1623. if (!GetWindowRect(hStatusWnd, &rcStatusWnd)) {
  1624. return (0L); // fail, return (0, 0)?
  1625. }
  1626. lParam = MAKELRESULT(rcStatusWnd.left, rcStatusWnd.top);
  1627. return (lParam);
  1628. }
  1629. #endif
  1630. return (0L);
  1631. default:
  1632. return (1L);
  1633. }
  1634. break;
  1635. case WM_IME_COMPOSITIONFULL:
  1636. return (0L);
  1637. case WM_IME_SELECT:
  1638. // try to use SetContext
  1639. // SelectIME(hUIWnd, (BOOL)wParam);
  1640. SetContext(
  1641. #if defined(UNIIME)
  1642. lpInstL, lpImeL,
  1643. #endif
  1644. hUIWnd, (BOOL)wParam, 0);
  1645. return (0L);
  1646. case WM_MOUSEACTIVATE:
  1647. return (MA_NOACTIVATE);
  1648. case WM_USER_UICHANGE:
  1649. return UIChange(
  1650. #if defined(UNIIME)
  1651. lpInstL, lpImeL,
  1652. #endif
  1653. hUIWnd);
  1654. default:
  1655. return DefWindowProc(hUIWnd, uMsg, wParam, lParam);
  1656. }
  1657. return (0L);
  1658. }