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.

758 lines
22 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. STATUSUI.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include "imeattr.h"
  9. #include "imedefs.h"
  10. #include "imerc.h"
  11. #if defined(UNIIME)
  12. #include "uniime.h"
  13. #endif
  14. /**********************************************************************/
  15. /* GetStatusWnd */
  16. /* Return Value : */
  17. /* window handle of status window */
  18. /**********************************************************************/
  19. HWND PASCAL GetStatusWnd(
  20. HWND hUIWnd) // UI window
  21. {
  22. HGLOBAL hUIPrivate;
  23. LPUIPRIV lpUIPrivate;
  24. HWND hStatusWnd;
  25. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  26. if (!hUIPrivate) { // can not darw status window
  27. return (HWND)NULL;
  28. }
  29. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  30. if (!lpUIPrivate) { // can not draw status window
  31. return (HWND)NULL;
  32. }
  33. hStatusWnd = lpUIPrivate->hStatusWnd;
  34. GlobalUnlock(hUIPrivate);
  35. return (hStatusWnd);
  36. }
  37. /**********************************************************************/
  38. /* AdjustStatusBoundary() */
  39. /**********************************************************************/
  40. void PASCAL AdjustStatusBoundary(
  41. #if defined(UNIIME)
  42. LPIMEL lpImeL,
  43. #endif
  44. LPPOINT lppt)
  45. {
  46. RECT rcWorkArea;
  47. #if 1 // MultiMonitor support
  48. {
  49. RECT rcStatusWnd;
  50. *(LPPOINT)&rcStatusWnd = *lppt;
  51. rcStatusWnd.right = rcStatusWnd.left + lpImeL->xStatusWi;
  52. rcStatusWnd.bottom = rcStatusWnd.top + lpImeL->yStatusHi;
  53. rcWorkArea = ImeMonitorWorkAreaFromRect(&rcStatusWnd);
  54. }
  55. #else
  56. rcWorkArea = sImeG.rcWorkArea;
  57. #endif
  58. // display boundary check
  59. if (lppt->x < rcWorkArea.left) {
  60. lppt->x = rcWorkArea.left;
  61. } else if (lppt->x + lpImeL->xStatusWi > rcWorkArea.right) {
  62. lppt->x = (rcWorkArea.right - lpImeL->xStatusWi);
  63. }
  64. if (lppt->y < rcWorkArea.top) {
  65. lppt->y = rcWorkArea.top;
  66. } else if (lppt->y + lpImeL->yStatusHi > rcWorkArea.bottom) {
  67. lppt->y = (rcWorkArea.bottom - lpImeL->yStatusHi);
  68. }
  69. return;
  70. }
  71. /**********************************************************************/
  72. /* SetStatusWindowPos() */
  73. /**********************************************************************/
  74. LRESULT PASCAL SetStatusWindowPos(
  75. #if defined(UNIIME)
  76. LPIMEL lpImeL,
  77. #endif
  78. HWND hStatusWnd)
  79. {
  80. HWND hUIWnd;
  81. HIMC hIMC;
  82. LPINPUTCONTEXT lpIMC;
  83. RECT rcStatusWnd;
  84. POINT ptPos;
  85. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  86. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  87. if (!hIMC) {
  88. return (1L);
  89. }
  90. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  91. if (!lpIMC) { // Oh! Oh!
  92. return (1L);
  93. }
  94. GetWindowRect(hStatusWnd, &rcStatusWnd);
  95. if (lpIMC->ptStatusWndPos.x != rcStatusWnd.left) {
  96. } else if (lpIMC->ptStatusWndPos.y != rcStatusWnd.top) {
  97. } else {
  98. ImmUnlockIMC(hIMC);
  99. return (0L);
  100. }
  101. ptPos = lpIMC->ptStatusWndPos;
  102. // display boundary adjust
  103. AdjustStatusBoundary(
  104. #if defined(UNIIME)
  105. lpImeL,
  106. #endif
  107. &ptPos);
  108. SetWindowPos(hStatusWnd, NULL,
  109. ptPos.x, ptPos.y,
  110. 0, 0, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOSIZE|SWP_NOZORDER);
  111. ImmUnlockIMC(hIMC);
  112. return (0L);
  113. }
  114. /**********************************************************************/
  115. /* ShowStatus() */
  116. /**********************************************************************/
  117. void PASCAL ShowStatus( // Show the status window - shape / soft KBD
  118. // alphanumeric ...
  119. #if defined(UNIIME)
  120. LPIMEL lpImeL,
  121. #endif
  122. HWND hUIWnd,
  123. int nShowStatusCmd)
  124. {
  125. HGLOBAL hUIPrivate;
  126. LPUIPRIV lpUIPrivate;
  127. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  128. if (!hUIPrivate) { // can not darw status window
  129. return;
  130. }
  131. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  132. if (!lpUIPrivate) { // can not draw status window
  133. return;
  134. }
  135. if (!lpUIPrivate->hStatusWnd) {
  136. // not in show status window mode
  137. } else if (lpUIPrivate->nShowStatusCmd == nShowStatusCmd) {
  138. } else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  139. int nCurrShowState;
  140. lpUIPrivate->nShowStatusCmd = nShowStatusCmd;
  141. #if defined(ROMANIME)
  142. nCurrShowState = SW_HIDE;
  143. #else
  144. nCurrShowState = lpUIPrivate->nShowCompCmd;
  145. nCurrShowState |= lpUIPrivate->nShowCandCmd;
  146. #endif
  147. if (nCurrShowState == SW_HIDE) {
  148. // if other two are hide, the current show state is determined
  149. // by this status section
  150. ShowWindow(lpUIPrivate->hStatusWnd, nShowStatusCmd);
  151. }
  152. } else {
  153. ShowWindow(lpUIPrivate->hStatusWnd, nShowStatusCmd);
  154. lpUIPrivate->nShowStatusCmd = nShowStatusCmd;
  155. }
  156. GlobalUnlock(hUIPrivate);
  157. return;
  158. }
  159. /**********************************************************************/
  160. /* OpenStatus() */
  161. /**********************************************************************/
  162. void PASCAL OpenStatus( // open status window
  163. #if defined(UNIIME)
  164. LPINSTDATAL lpInstL,
  165. LPIMEL lpImeL,
  166. #endif
  167. HWND hUIWnd)
  168. {
  169. HGLOBAL hUIPrivate;
  170. LPUIPRIV lpUIPrivate;
  171. HIMC hIMC;
  172. LPINPUTCONTEXT lpIMC;
  173. POINT ptPos;
  174. int nShowStatusCmd;
  175. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  176. if (!hUIPrivate) { // can not darw status window
  177. return;
  178. }
  179. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  180. if (!lpUIPrivate) { // can not draw status window
  181. return;
  182. }
  183. // in the timing of the transition, we will wait
  184. if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
  185. if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)) {
  186. PostMessage(hUIWnd, WM_USER_UICHANGE, 0, 0);
  187. goto OpenStatusUnlockUIPriv;
  188. }
  189. } else {
  190. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  191. PostMessage(hUIWnd, WM_USER_UICHANGE, 0, 0);
  192. goto OpenStatusUnlockUIPriv;
  193. }
  194. }
  195. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  196. if (!hIMC) {
  197. ptPos.x = sImeG.rcWorkArea.left;
  198. ptPos.y = sImeG.rcWorkArea.bottom - lpImeL->yStatusHi;
  199. nShowStatusCmd = SW_HIDE;
  200. } else if (lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)) {
  201. AdjustStatusBoundary(
  202. #if defined(UNIIME)
  203. lpImeL,
  204. #endif
  205. &lpIMC->ptStatusWndPos);
  206. ptPos = lpIMC->ptStatusWndPos;
  207. ImmUnlockIMC(hIMC);
  208. nShowStatusCmd = SW_SHOWNOACTIVATE;
  209. } else {
  210. ptPos.x = sImeG.rcWorkArea.left;
  211. ptPos.y = sImeG.rcWorkArea.bottom - lpImeL->yStatusHi;
  212. nShowStatusCmd = SW_HIDE;
  213. }
  214. #if !defined(ROMANIME)
  215. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  216. if (lpUIPrivate->hStatusWnd) {
  217. } else if (lpUIPrivate->hCompWnd) {
  218. lpUIPrivate->hStatusWnd = lpUIPrivate->hCompWnd;
  219. lpUIPrivate->nShowStatusCmd = lpUIPrivate->nShowCompCmd;
  220. } else if (lpUIPrivate->hCandWnd) {
  221. lpUIPrivate->hStatusWnd = lpUIPrivate->hCandWnd;
  222. lpUIPrivate->nShowStatusCmd = lpUIPrivate->nShowCandCmd;
  223. } else {
  224. }
  225. }
  226. #endif
  227. if (lpUIPrivate->hStatusWnd) {
  228. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  229. RECT rcRect;
  230. rcRect = lpImeL->rcStatusText;
  231. // off by 1
  232. rcRect.right += 1;
  233. rcRect.bottom += 1;
  234. RedrawWindow(lpUIPrivate->hStatusWnd, &rcRect, NULL,
  235. RDW_INVALIDATE);
  236. } else {
  237. SetWindowPos(lpUIPrivate->hStatusWnd, NULL,
  238. ptPos.x, ptPos.y,
  239. 0, 0,
  240. SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  241. }
  242. } else { // create status window
  243. if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
  244. lpUIPrivate->hStatusWnd = CreateWindowEx(
  245. WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,
  246. lpImeL->szOffCaretClassName, NULL,
  247. WS_POPUP|WS_DISABLED,
  248. ptPos.x, ptPos.y,
  249. lpImeL->xStatusWi, lpImeL->yStatusHi,
  250. hUIWnd, (HMENU)NULL, lpInstL->hInst, NULL);
  251. #if !defined(ROMANIME) && !defined(WINAR30)
  252. if (lpUIPrivate->hSoftKbdWnd) {
  253. // insert soft keyboard in front of other UI
  254. SetWindowPos(lpUIPrivate->hStatusWnd,
  255. lpUIPrivate->hSoftKbdWnd,
  256. 0, 0, 0, 0,
  257. SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE);
  258. }
  259. #endif
  260. } else {
  261. lpUIPrivate->hStatusWnd = CreateWindowEx(
  262. WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,
  263. lpImeL->szStatusClassName, NULL,
  264. WS_POPUP|WS_DISABLED,
  265. ptPos.x, ptPos.y,
  266. lpImeL->xStatusWi, lpImeL->yStatusHi,
  267. hUIWnd, (HMENU)NULL, lpInstL->hInst, NULL);
  268. }
  269. if (!lpUIPrivate->hStatusWnd) {
  270. goto OpenStatusUnlockUIPriv;
  271. }
  272. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_OFFSET,
  273. WINDOW_NOT_DRAG);
  274. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_XY, 0L);
  275. }
  276. lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
  277. if (hIMC) {
  278. ShowStatus(
  279. #if defined(UNIIME)
  280. lpImeL,
  281. #endif
  282. hUIWnd, SW_SHOWNOACTIVATE);
  283. }
  284. OpenStatusUnlockUIPriv:
  285. GlobalUnlock(hUIPrivate);
  286. return;
  287. }
  288. /**********************************************************************/
  289. /* DestroyStatusWindow() */
  290. /**********************************************************************/
  291. void PASCAL DestroyStatusWindow(
  292. HWND hStatusWnd)
  293. {
  294. HWND hUIWnd;
  295. HGLOBAL hUIPrivate;
  296. LPUIPRIV lpUIPrivate;
  297. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  298. // undo the drag border
  299. DrawDragBorder(hStatusWnd,
  300. GetWindowLong(hStatusWnd, UI_MOVE_XY),
  301. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  302. }
  303. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  304. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  305. if (!hUIPrivate) { // can not darw status window
  306. return;
  307. }
  308. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  309. if (!lpUIPrivate) { // can not draw status window
  310. return;
  311. }
  312. lpUIPrivate->nShowStatusCmd = SW_HIDE;
  313. lpUIPrivate->hStatusWnd = (HWND)NULL;
  314. GlobalUnlock(hUIPrivate);
  315. return;
  316. }
  317. /**********************************************************************/
  318. /* SetStatus */
  319. /**********************************************************************/
  320. void PASCAL SetStatus(
  321. #if defined(UNIIME)
  322. LPIMEL lpImeL,
  323. #endif
  324. HWND hStatusWnd,
  325. LPPOINT lpptCursor)
  326. {
  327. HWND hUIWnd;
  328. HIMC hIMC;
  329. LPINPUTCONTEXT lpIMC;
  330. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  331. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  332. if (!hIMC) {
  333. return;
  334. }
  335. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  336. if (!lpIMC) {
  337. return;
  338. }
  339. if (!lpIMC->fOpen) {
  340. ImmSetOpenStatus(hIMC, TRUE);
  341. } else if (PtInRect(&lpImeL->rcInputText, *lpptCursor)) {
  342. #if defined(ROMANIME)
  343. MessageBeep((UINT)-1);
  344. #else
  345. DWORD fdwConversion;
  346. if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  347. if (lpIMC->fdwConversion & (IME_CMODE_CHARCODE|
  348. IME_CMODE_NOCONVERSION|IME_CMODE_EUDC|IME_CMODE_SYMBOL)) {
  349. // change to native mode
  350. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  351. ~(IME_CMODE_CHARCODE|IME_CMODE_NOCONVERSION|
  352. IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  353. } else {
  354. // change to alphanumeric mode
  355. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_NATIVE|
  356. IME_CMODE_CHARCODE|IME_CMODE_NOCONVERSION|
  357. IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  358. }
  359. } else {
  360. // change to native mode
  361. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  362. ~(IME_CMODE_CHARCODE|IME_CMODE_NOCONVERSION|
  363. IME_CMODE_EUDC|IME_CMODE_SYMBOL);
  364. }
  365. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  366. #endif
  367. } else if (PtInRect(&lpImeL->rcShapeText, *lpptCursor)) {
  368. DWORD dwConvMode;
  369. if (lpIMC->fdwConversion & IME_CMODE_CHARCODE) {
  370. MessageBeep((UINT)-1);
  371. } else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  372. MessageBeep((UINT)-1);
  373. } else {
  374. dwConvMode = lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE;
  375. ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
  376. }
  377. } else {
  378. MessageBeep((UINT)-1);
  379. }
  380. ImmUnlockIMC(hIMC);
  381. return;
  382. }
  383. /**********************************************************************/
  384. /* ResourceLocked() */
  385. /**********************************************************************/
  386. void PASCAL ResourceLocked(
  387. #if defined(UNIIME)
  388. LPIMEL lpImeL,
  389. #endif
  390. HWND hWnd)
  391. {
  392. TCHAR szErrMsg[32];
  393. LoadString(hInst, IDS_SHARE_VIOLATION, szErrMsg, sizeof(szErrMsg)/sizeof(TCHAR));
  394. MessageBeep((UINT)-1);
  395. MessageBox(hWnd, szErrMsg, lpImeL->szIMEName,
  396. MB_OK|MB_ICONHAND|MB_TASKMODAL|MB_TOPMOST);
  397. return;
  398. }
  399. /**********************************************************************/
  400. /* StatusSetCursor() */
  401. /**********************************************************************/
  402. void PASCAL StatusSetCursor(
  403. #if defined(UNIIME)
  404. LPINSTDATAL lpInstL,
  405. LPIMEL lpImeL,
  406. #endif
  407. HWND hStatusWnd,
  408. LPARAM lParam)
  409. {
  410. POINT ptCursor, ptSavCursor;
  411. RECT rcWnd;
  412. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  413. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  414. return;
  415. }
  416. GetCursorPos(&ptCursor);
  417. ptSavCursor = ptCursor;
  418. ScreenToClient(hStatusWnd, &ptCursor);
  419. if (PtInRect(&lpImeL->rcStatusText, ptCursor)) {
  420. SetCursor(LoadCursor(hInst, MAKEINTRESOURCE(IDCR_HAND_CURSOR)));
  421. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  422. SetStatus(
  423. #if defined(UNIIME)
  424. lpImeL,
  425. #endif
  426. hStatusWnd, &ptCursor);
  427. } else if (HIWORD(lParam) == WM_RBUTTONUP) {
  428. static BOOL fImeConfigure = FALSE;
  429. // prevent recursive
  430. if (fImeConfigure) {
  431. // configuration already bring up
  432. return;
  433. }
  434. fImeConfigure = TRUE;
  435. ContextMenu(
  436. #if defined(UNIIME)
  437. lpInstL, lpImeL,
  438. #endif
  439. hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  440. fImeConfigure = FALSE;
  441. } else {
  442. }
  443. return;
  444. } else {
  445. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  446. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  447. // start drag
  448. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  449. } else {
  450. return;
  451. }
  452. }
  453. SetCapture(hStatusWnd);
  454. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  455. MAKELONG(ptSavCursor.x, ptSavCursor.y));
  456. GetWindowRect(hStatusWnd, &rcWnd);
  457. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
  458. MAKELONG(ptSavCursor.x - rcWnd.left, ptSavCursor.y - rcWnd.top));
  459. DrawDragBorder(hStatusWnd, MAKELONG(ptSavCursor.x, ptSavCursor.y),
  460. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  461. return;
  462. }
  463. /**********************************************************************/
  464. /* PaintStatusWindow() */
  465. /**********************************************************************/
  466. void PASCAL PaintStatusWindow(
  467. #if defined(UNIIME)
  468. LPINSTDATAL lpInstL,
  469. LPIMEL lpImeL,
  470. #endif
  471. HWND hStatusWnd,
  472. HDC hDC)
  473. {
  474. HWND hUIWnd;
  475. HIMC hIMC;
  476. LPINPUTCONTEXT lpIMC;
  477. HBITMAP hInputBmp, hShapeBmp;
  478. HBITMAP hOldBmp;
  479. HDC hMemDC;
  480. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  481. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  482. if (!hIMC) {
  483. return;
  484. }
  485. if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  486. #ifdef DEBUG
  487. MessageBeep((UINT)-1);
  488. #endif
  489. return;
  490. }
  491. hInputBmp = (HBITMAP)NULL;
  492. hShapeBmp = (HBITMAP)NULL;
  493. if (!lpIMC->fOpen) {
  494. hInputBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_NONE));
  495. hShapeBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_NONE));
  496. #if !defined(ROMANIME)
  497. } else if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
  498. hInputBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_ALPHANUMERIC));
  499. #if !defined(WINIME) && !defined(UNICDIME)
  500. } else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  501. hInputBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_EUDC));
  502. hShapeBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_NONE));
  503. #endif
  504. } else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  505. hInputBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_SYMBOL));
  506. #endif
  507. } else {
  508. hInputBmp = LoadBitmap(lpInstL->hInst,
  509. MAKEINTRESOURCE(IDBM_CMODE_NATIVE));
  510. }
  511. if (!hShapeBmp) {
  512. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
  513. hShapeBmp = LoadBitmap(hInst,
  514. MAKEINTRESOURCE(IDBM_CMODE_FULLSHAPE));
  515. } else {
  516. hShapeBmp = LoadBitmap(hInst,
  517. MAKEINTRESOURCE(IDBM_CMODE_HALFSHAPE));
  518. }
  519. }
  520. ImmUnlockIMC(hIMC);
  521. hMemDC = CreateCompatibleDC(hDC);
  522. if ( hMemDC == NULL )
  523. {
  524. if ( hInputBmp != NULL)
  525. DeleteObject(hInputBmp);
  526. if ( hShapeBmp != NULL)
  527. DeleteObject(hShapeBmp);
  528. return;
  529. }
  530. hOldBmp = SelectObject(hMemDC, hInputBmp);
  531. BitBlt(hDC, lpImeL->rcInputText.left, lpImeL->rcInputText.top,
  532. lpImeL->rcInputText.right - lpImeL->rcInputText.left,
  533. lpImeL->rcInputText.bottom - lpImeL->rcInputText.top,
  534. hMemDC, 0, 0, SRCCOPY);
  535. SelectObject(hMemDC, hShapeBmp);
  536. BitBlt(hDC, lpImeL->rcShapeText.left, lpImeL->rcShapeText.top,
  537. lpImeL->rcShapeText.right - lpImeL->rcShapeText.left,
  538. lpImeL->rcShapeText.bottom - lpImeL->rcShapeText.top,
  539. hMemDC, 0, 0, SRCCOPY);
  540. SelectObject(hMemDC, hOldBmp);
  541. DeleteDC(hMemDC);
  542. DeleteObject(hInputBmp);
  543. DeleteObject(hShapeBmp);
  544. return;
  545. }
  546. /**********************************************************************/
  547. /* StatusWndProc() */
  548. /**********************************************************************/
  549. #if defined(UNIIME)
  550. LRESULT CALLBACK UniStatusWndProc(
  551. LPINSTDATAL lpInstL,
  552. LPIMEL lpImeL,
  553. #else
  554. LRESULT CALLBACK StatusWndProc(
  555. #endif
  556. HWND hStatusWnd,
  557. UINT uMsg,
  558. WPARAM wParam,
  559. LPARAM lParam)
  560. {
  561. switch (uMsg) {
  562. case WM_DESTROY:
  563. DestroyStatusWindow(hStatusWnd);
  564. break;
  565. case WM_SETCURSOR:
  566. StatusSetCursor(
  567. #if defined(UNIIME)
  568. lpInstL, lpImeL,
  569. #endif
  570. hStatusWnd, lParam);
  571. break;
  572. case WM_MOUSEMOVE:
  573. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  574. POINT ptCursor;
  575. DrawDragBorder(hStatusWnd,
  576. GetWindowLong(hStatusWnd, UI_MOVE_XY),
  577. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  578. GetCursorPos(&ptCursor);
  579. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  580. MAKELONG(ptCursor.x, ptCursor.y));
  581. DrawDragBorder(hStatusWnd, MAKELONG(ptCursor.x, ptCursor.y),
  582. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  583. } else {
  584. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  585. }
  586. break;
  587. case WM_LBUTTONUP:
  588. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  589. LONG lTmpCursor, lTmpOffset;
  590. POINT ptCursor;
  591. HWND hUIWnd;
  592. lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
  593. // calculate the org by the offset
  594. lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  595. DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
  596. ptCursor.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x;
  597. ptCursor.y = (*(LPPOINTS)&lTmpCursor).y - (*(LPPOINTS)&lTmpOffset).y;
  598. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  599. ReleaseCapture();
  600. AdjustStatusBoundary(
  601. #if defined(UNIIME)
  602. lpImeL,
  603. #endif
  604. &ptCursor);
  605. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  606. ImmSetStatusWindowPos((HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC),
  607. &ptCursor);
  608. } else {
  609. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  610. }
  611. break;
  612. case WM_IME_NOTIFY:
  613. if (wParam == IMN_SETSTATUSWINDOWPOS) {
  614. SetStatusWindowPos(
  615. #if defined(UNIIME)
  616. lpImeL,
  617. #endif
  618. hStatusWnd);
  619. }
  620. break;
  621. case WM_PAINT:
  622. {
  623. HDC hDC;
  624. PAINTSTRUCT ps;
  625. hDC = BeginPaint(hStatusWnd, &ps);
  626. PaintStatusWindow(
  627. #if defined(UNIIME)
  628. lpInstL,
  629. lpImeL,
  630. #endif
  631. hStatusWnd, hDC);
  632. EndPaint(hStatusWnd, &ps);
  633. }
  634. break;
  635. case WM_MOUSEACTIVATE:
  636. return (MA_NOACTIVATE);
  637. default:
  638. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  639. }
  640. return (0L);
  641. }