Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1243 lines
46 KiB

  1. /****************************************************************************
  2. STATUSUI.CPP
  3. Owner: cslim
  4. Copyright (c) 1997-1999 Microsoft Corporation
  5. Status window UI functions
  6. History:
  7. 14-JUL-1999 cslim Copied from IME98 source tree
  8. *****************************************************************************/
  9. #include "precomp.h"
  10. #include "ui.h"
  11. #include "config.h"
  12. #include "names.h"
  13. #include "escape.h"
  14. #include "winex.h"
  15. #include "cpadsvr.h"
  16. #include "debug.h"
  17. #define ABS(A) ((A) < 0 ? -(A) : (A))
  18. inline BOOL IsValidButton(INT iButton)
  19. {
  20. return (iButton>=0 && iButton<MAX_NUM_OF_STATUS_BUTTONS);
  21. }
  22. ///////////////////////////////////////////////////////////////////////////////
  23. PRIVATE VOID PASCAL FrameControl(HDC hDC, RECT* pRc, INT iState);
  24. PRIVATE VOID PASCAL PaintStatusWindow(HWND hStatusWnd, HDC hDC);
  25. PRIVATE BOOL StatusOnSetCursor(HWND, HWND, UINT, UINT);
  26. PRIVATE VOID StatusOnLButtonUp(HWND, INT, INT, UINT);
  27. PRIVATE VOID StatusOnMouseMove(HWND, INT, INT, UINT);
  28. PRIVATE VOID PASCAL DestroyStatusWindow(HWND hStatusWnd);
  29. PRIVATE VOID PASCAL AdjustStatusBoundary(LPPOINT lppt);
  30. PRIVATE VOID PASCAL UpdateStatusTooltip(HWND hStatusWnd, HWND hStatusTTWnd);
  31. PRIVATE BOOL vfAnyButtonDown=fFalse;
  32. PRIVATE BOOL vfPrevButton=-1;
  33. PRIVATE POINT vfptDown;
  34. ///////////////////////////////////////////////////////////////////////////////
  35. struct _StatusButtonInfo
  36. {
  37. int m_Width, m_Height;
  38. WORD m_BmpNormalID[MAX_NUM_OF_STATUS_BUTTONS];
  39. WORD m_BmpOnMouseID[MAX_NUM_OF_STATUS_BUTTONS];
  40. WORD m_BmpPushedID[MAX_NUM_OF_STATUS_BUTTONS];
  41. WORD m_BmpDownOnMouseID[MAX_NUM_OF_STATUS_BUTTONS];
  42. WORD m_ToolTipStrID[MAX_NUM_OF_STATUS_BUTTONS];
  43. };
  44. static _StatusButtonInfo StatusButtonInfo[NUM_OF_BUTTON_SIZE] =
  45. {
  46. // Small size button
  47. { 0, 0, },
  48. // Medium size button
  49. { 19, 19, // Bitmap size
  50. #if !defined(_WIN64)
  51. // Normal buttons images
  52. {IDB_STAT_HANGUL, IDB_STAT_BANJA, IDB_STAT_CHINESEOFF, IDB_STAT_IMEPAD},
  53. // Pushed and mouse hover images
  54. {IDB_STAT_ON_ENGLISH, IDB_STAT_ON_JUNJA, IDB_STAT_CHINESEOFF, IDB_STAT_IMEPAD},
  55. // Pushed buttons
  56. {IDB_STAT_ENGLISH, IDB_STAT_JUNJA, IDB_STAT_CHINESEOFF, IDB_STAT_IMEPAD_DOWN},
  57. // Pushed and mouse down images
  58. {IDB_STAT_ENGLISH_ONDOWN, IDB_STAT_JUNJA_ONDOWN, IDB_STAT_CHINESEOFF, IDB_STAT_IMEPAD/*IDB_STAT_IMEPAD_DOWNHOVER*/},
  59. // Tooltips string
  60. {IDS_STATUS_TT_HAN_ENG, IDS_STATUS_TT_JUN_BAN, IDS_STATUS_TT_HANJA_CONV, IDS_STATUS_TT_IME_PAD},
  61. #else
  62. // Normal buttons images
  63. {IDB_STAT_HANGUL, IDB_STAT_BANJA, IDB_STAT_CHINESEOFF },
  64. // Pushed and mouse hover images
  65. {IDB_STAT_ON_ENGLISH, IDB_STAT_ON_JUNJA, IDB_STAT_CHINESEOFF },
  66. // Pushed buttons
  67. {IDB_STAT_ENGLISH, IDB_STAT_JUNJA, IDB_STAT_CHINESEOFF },
  68. // Pushed and mouse down images
  69. {IDB_STAT_ENGLISH_ONDOWN, IDB_STAT_JUNJA_ONDOWN, IDB_STAT_CHINESEOFF },
  70. // Tooltips string
  71. {IDS_STATUS_TT_HAN_ENG, IDS_STATUS_TT_JUN_BAN, IDS_STATUS_TT_HANJA_CONV },
  72. #endif
  73. },
  74. // Large size button
  75. { 0, 0, }
  76. };
  77. void UpdateStatusButtons(CIMEData &ImeData)
  78. {
  79. UINT i;
  80. INT iButtonSize;
  81. INT iButtonType;
  82. iButtonSize = ImeData->iCurButtonSize;
  83. #ifdef DEBUG
  84. OutputDebugString(TEXT("UpdateStatusButtons():\r\n"));
  85. #endif
  86. ImeData->xButtonWi = StatusButtonInfo[iButtonSize].m_Width;
  87. ImeData->yButtonHi = StatusButtonInfo[iButtonSize].m_Height;
  88. DbgAssert(ImeData->uNumOfButtons <= MAX_NUM_OF_STATUS_BUTTONS);
  89. for (i=0; i<ImeData->uNumOfButtons; i++)
  90. {
  91. iButtonType = ImeData->StatusButtons[i].m_ButtonType;
  92. ImeData->StatusButtons[i].m_BmpNormalID = StatusButtonInfo[iButtonSize].m_BmpNormalID[iButtonType];
  93. ImeData->StatusButtons[i].m_BmpOnMouseID = StatusButtonInfo[iButtonSize].m_BmpOnMouseID[iButtonType];
  94. ImeData->StatusButtons[i].m_BmpPushedID = StatusButtonInfo[iButtonSize].m_BmpPushedID[iButtonType];
  95. ImeData->StatusButtons[i].m_BmpDownOnMouseID = StatusButtonInfo[iButtonSize].m_BmpDownOnMouseID[iButtonType];
  96. ImeData->StatusButtons[i].m_ToolTipStrID = StatusButtonInfo[iButtonSize].m_ToolTipStrID[iButtonType];
  97. // Default value is enabled
  98. ImeData->StatusButtons[i].m_fEnable = fTrue;
  99. }
  100. }
  101. void UpdateStatusWinDimension()
  102. {
  103. CIMEData ImeData(CIMEData::SMReadWrite);
  104. // Caculate status window size
  105. ImeData->xStatusWi = ImeData->cxStatLeftMargin + ImeData->cxStatRightMargin
  106. + ImeData->xButtonWi * ImeData->uNumOfButtons;
  107. //+ ImeData->cxStatMargin*2;//62;
  108. ImeData->yStatusHi = ImeData->cyStatMargin*2
  109. + ImeData->yButtonHi;
  110. //+ pImeData->cyCaptionHeight;// + 2;
  111. //+ pImeData->cyStatMargin; //24;
  112. // Caculate button area.
  113. ImeData->rcButtonArea.left = ImeData->cxStatLeftMargin;
  114. ImeData->rcButtonArea.top = ImeData->cyStatButton;
  115. ImeData->rcButtonArea.right = ImeData->xButtonWi*ImeData->uNumOfButtons
  116. + ImeData->rcButtonArea.left;
  117. ImeData->rcButtonArea.bottom = /*ImeData->cyStatMargin*2 +*/ ImeData->cyStatButton + ImeData->yButtonHi;
  118. }
  119. ///////////////////////////////////////////////////////////////////////////////
  120. LRESULT CALLBACK StatusWndProc(HWND hStatusWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
  121. {
  122. POINT ptCursor;
  123. Dbg(DBGID_UI, TEXT("StatusWndProc():uMessage = 0x%08lX, wParam = 0x%04X, lParam = 0x%08lX"), uMessage, wParam, lParam);
  124. switch (uMessage)
  125. {
  126. case WM_IME_CHAR: case WM_IME_COMPOSITIONFULL:
  127. case WM_IME_COMPOSITION: case WM_IME_CONTROL:
  128. case WM_IME_SELECT:
  129. case WM_IME_SETCONTEXT: case WM_IME_STARTCOMPOSITION:
  130. case WM_IME_ENDCOMPOSITION:
  131. return (0L);
  132. HANDLE_MSG(hStatusWnd, WM_SETCURSOR, StatusOnSetCursor);
  133. HANDLE_MSG(hStatusWnd, WM_LBUTTONUP, StatusOnLButtonUp);
  134. HANDLE_MSG(hStatusWnd, WM_MOUSEMOVE, StatusOnMouseMove);
  135. case WM_DESTROY:
  136. DestroyStatusWindow(hStatusWnd);
  137. break;
  138. case WM_PAINT:
  139. {
  140. HDC hDC;
  141. PAINTSTRUCT ps;
  142. hDC = BeginPaint(hStatusWnd, &ps);
  143. PaintStatusWindow(hStatusWnd, hDC);
  144. EndPaint(hStatusWnd, &ps);
  145. }
  146. break;
  147. case WM_TIMER:
  148. {
  149. CIMEData ImeData;
  150. GetCursorPos(&ptCursor);
  151. ScreenToClient(hStatusWnd, &ptCursor);
  152. if ( PtInRect(&ImeData->rcButtonArea, ptCursor) == fFalse )
  153. {
  154. InitButtonState();
  155. KillTimer( hStatusWnd, TIMER_UIBUTTON );
  156. InvalidateRect( hStatusWnd, &ImeData->rcButtonArea, fFalse );
  157. }
  158. }
  159. break;
  160. default :
  161. return DefWindowProc(hStatusWnd, uMessage, wParam, lParam);
  162. }
  163. return (0L);
  164. }
  165. ///////////////////////////////////////////////////////////////////////////////
  166. // S T A T U S W I N D O W M S G R O U T I N E S
  167. BOOL StatusOnSetCursor(HWND hStatusWnd, HWND hWndCursor, UINT codeHitTest, UINT message)
  168. {
  169. POINT ptCursor, ptSavCursor;
  170. RECT rcWnd;
  171. BOOL fDragArea = fFalse;
  172. int iCurButton;
  173. HWND hUIWnd;
  174. CIMEData ImeData(CIMEData::SMReadWrite);
  175. GetCursorPos(&ptCursor);
  176. ptSavCursor = ptCursor;
  177. ScreenToClient(hStatusWnd, &ptCursor);
  178. Dbg(DBGID_UI, TEXT("StatusOnSetCursor(): ptCursor.x = %d, ptCursor.y = %d"), ptCursor.x, ptCursor.y);
  179. SetCursor(LoadCursor(NULL, IDC_ARROW));
  180. if (PtInRect(&ImeData->rcButtonArea, ptCursor))
  181. {
  182. //SetCursor(LoadCursor(NULL, IDC_ARROW));
  183. }
  184. else
  185. {
  186. // SetCursor(LoadCursor(vpInstData->hInst, MAKEINTRESOURCE(IDC_IME_HAND)));
  187. fDragArea = fTrue;
  188. }
  189. switch (message)
  190. {
  191. case WM_LBUTTONDOWN:
  192. SetCapture(hStatusWnd);
  193. if (fDragArea) // if drag start
  194. {
  195. SystemParametersInfo(SPI_GETWORKAREA, 0, &ImeData->rcWorkArea, 0);
  196. SetWindowLong(hStatusWnd, UI_MOVE_XY, MAKELONG(ptSavCursor.x, ptSavCursor.y));
  197. GetWindowRect(hStatusWnd, &rcWnd);
  198. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
  199. MAKELONG(ptSavCursor.x - rcWnd.left, ptSavCursor.y - rcWnd.top));
  200. }
  201. else
  202. {
  203. InitButtonState();
  204. if (!ImeData->StatusButtons[(ptCursor.x-ImeData->cxStatLeftMargin)/ImeData->xButtonWi].m_fEnable)
  205. {
  206. ReleaseCapture();
  207. break;
  208. }
  209. vfPrevButton = (ptCursor.x-ImeData->cxStatLeftMargin)/ImeData->xButtonWi;
  210. vfptDown = ptSavCursor;
  211. ImeData->StatusButtons[vfPrevButton].m_uiButtonState = BTNSTATE_ONMOUSE | BTNSTATE_DOWN;
  212. vfAnyButtonDown = fTrue;
  213. InvalidateRect(hStatusWnd, &ImeData->rcButtonArea, fFalse);
  214. }
  215. break;
  216. case WM_LBUTTONUP:
  217. // if ((fdwUIFlags & UIF_CHIPRESS) && PtInRect((LPRECT)&rcChi, ptPos)) {
  218. // keybd_event(VK_HANJA, 0, 0, 0);
  219. // keybd_event(VK_HANJA, 0, KEYEVENTF_KEYUP, 0);
  220. // fdwUIFlags &= ~UIF_CHIPRESS;
  221. // }
  222. break;
  223. case WM_RBUTTONDOWN:
  224. // if right button click, finalize interim
  225. HIMC hIMC;
  226. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  227. hIMC = GethImcFromHwnd(hUIWnd);
  228. if (hIMC)
  229. OurImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
  230. break;
  231. case WM_RBUTTONUP:
  232. //UIPopupMenu(GetWindow(hStatusWnd, GW_OWNER));
  233. OurPostMessage(GetWindow(hStatusWnd, GW_OWNER), WM_MSIME_OPENMENU, 0, 0);
  234. break;
  235. case WM_MOUSEMOVE:
  236. iCurButton = (ptCursor.x-ImeData->cxStatLeftMargin)/ImeData->xButtonWi;
  237. if (!IsValidButton(iCurButton))
  238. break;
  239. if (!ImeData->StatusButtons[iCurButton].m_fEnable)
  240. break;
  241. if (fDragArea)
  242. {
  243. if (vfPrevButton != -1 &&
  244. (ImeData->StatusButtons[vfPrevButton].m_uiButtonState & BTNSTATE_ONMOUSE))
  245. {
  246. ImeData->StatusButtons[vfPrevButton].m_uiButtonState &= ~BTNSTATE_ONMOUSE;
  247. InvalidateRect( hStatusWnd, &ImeData->rcButtonArea, fFalse );
  248. }
  249. }
  250. else
  251. {
  252. if (!(ImeData->StatusButtons[iCurButton].m_uiButtonState & BTNSTATE_ONMOUSE))
  253. {
  254. ImeData->StatusButtons[iCurButton].m_uiButtonState |= BTNSTATE_ONMOUSE;
  255. if (vfPrevButton != -1)
  256. ImeData->StatusButtons[vfPrevButton].m_uiButtonState = BTNSTATE_NORMAL;
  257. vfPrevButton = iCurButton;
  258. SetTimer(hStatusWnd, TIMER_UIBUTTON, 200, NULL);
  259. InvalidateRect( hStatusWnd, &ImeData->rcButtonArea, fFalse );
  260. }
  261. }
  262. break;
  263. }
  264. if (hStatusWnd)
  265. {
  266. // Send Tooltip relay msg
  267. HGLOBAL hUIPrivate;
  268. LPUIPRIV lpUIPrivate;
  269. MSG msg;
  270. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  271. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  272. if (!hUIPrivate)
  273. return fTrue;
  274. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  275. if (!lpUIPrivate) // can not draw candidate window
  276. return fTrue;
  277. if (lpUIPrivate->hStatusTTWnd)
  278. {
  279. ZeroMemory(&msg, sizeof(MSG));
  280. msg.message = message;
  281. msg.hwnd = hStatusWnd;
  282. msg.wParam = 0;
  283. msg.lParam = MAKELONG(ptCursor.x, ptCursor.y);
  284. OurSendMessage(lpUIPrivate->hStatusTTWnd, TTM_RELAYEVENT, 0, (LPARAM) (LPMSG) &msg);
  285. }
  286. GlobalUnlock(hUIPrivate);
  287. }
  288. return fTrue;
  289. }
  290. // if mouse down, and user move mouse cursor
  291. void StatusOnMouseMove(HWND hStatusWnd, int xPos, int yPos, UINT wParam)
  292. {
  293. POINT ptCursor;
  294. int iCurButton;
  295. RECT rcWnd;
  296. LONG lCursorOffset;
  297. CIMEData ImeData(CIMEData::SMReadWrite);
  298. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG)
  299. {
  300. GetCursorPos(&ptCursor);
  301. SetWindowLong(hStatusWnd, UI_MOVE_XY, MAKELONG(ptCursor.x, ptCursor.y));
  302. lCursorOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  303. // calculate the org by the offset
  304. ptCursor.x -= (*(LPPOINTS)&lCursorOffset).x;
  305. ptCursor.y -= (*(LPPOINTS)&lCursorOffset).y;
  306. fSetStatusWindowPos(hStatusWnd, &ptCursor);
  307. }
  308. else
  309. {
  310. GetCursorPos(&ptCursor);
  311. if (vfAnyButtonDown &&
  312. (ABS(vfptDown.x - ptCursor.x)>3 || ABS(vfptDown.y - ptCursor.y)>3) )
  313. {
  314. SystemParametersInfo(SPI_GETWORKAREA, 0, &ImeData->rcWorkArea, 0);
  315. SetWindowLong(hStatusWnd, UI_MOVE_XY, MAKELONG(vfptDown.x, vfptDown.y));
  316. GetWindowRect(hStatusWnd, &rcWnd);
  317. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
  318. MAKELONG(vfptDown.x - rcWnd.left, vfptDown.y - rcWnd.top));
  319. lCursorOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  320. // calculate the org by the offset
  321. ptCursor.x -= (*(LPPOINTS)&lCursorOffset).x;
  322. ptCursor.y -= (*(LPPOINTS)&lCursorOffset).y;
  323. fSetStatusWindowPos(hStatusWnd, &ptCursor);
  324. InitButtonState();
  325. }
  326. else
  327. {
  328. ptCursor.x = xPos; ptCursor.y = yPos;
  329. iCurButton = (ptCursor.x-ImeData->cxStatLeftMargin)/ImeData->xButtonWi;
  330. if (IsValidButton(iCurButton))
  331. {
  332. if (PtInRect(&ImeData->rcButtonArea, ptCursor))
  333. {
  334. if ( !(ImeData->StatusButtons[iCurButton].m_uiButtonState & BTNSTATE_ONMOUSE) )
  335. {
  336. ImeData->StatusButtons[iCurButton].m_uiButtonState |= BTNSTATE_ONMOUSE;
  337. if (vfPrevButton != -1)
  338. {
  339. ImeData->StatusButtons[vfPrevButton].m_uiButtonState = BTNSTATE_NORMAL;
  340. vfPrevButton = iCurButton;
  341. }
  342. InvalidateRect( hStatusWnd, &ImeData->rcButtonArea, fFalse );
  343. }
  344. }
  345. else
  346. {
  347. InitButtonState();
  348. InvalidateRect( hStatusWnd, &ImeData->rcButtonArea, fFalse );
  349. }
  350. }
  351. }
  352. }
  353. }
  354. void StatusOnLButtonUp(HWND hStatusWnd, int x, int y, UINT keyFlags)
  355. {
  356. POINT ptCursor;
  357. int iCurButton;
  358. CIMEData ImeData(CIMEData::SMReadWrite);
  359. Dbg(DBGID_UI, TEXT("StatusOnLButtonUp() : x=%d, y=%d"), x, y);
  360. vfAnyButtonDown = fFalse;
  361. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG)
  362. {
  363. Dbg(DBGID_UI, TEXT("StatusOnLButtonUp() : Dragging mode"));
  364. LPARAM lTmpCursor, lTmpOffset;
  365. lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
  366. lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  367. // calculate the org by the offset
  368. ptCursor.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x;
  369. ptCursor.y = (*(LPPOINTS)&lTmpCursor).y - (*(LPPOINTS)&lTmpOffset).y;
  370. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  371. ReleaseCapture();
  372. fSetStatusWindowPos(hStatusWnd, &ptCursor);
  373. }
  374. else
  375. {
  376. Dbg(DBGID_UI, TEXT("StatusOnLButtonUp() : Non-Dragging mode. Button check"));
  377. ReleaseCapture();
  378. ptCursor.x = x; ptCursor.y = y;
  379. if (!PtInRect(&ImeData->rcButtonArea, ptCursor))
  380. {
  381. InitButtonState();
  382. goto StatusOnLButtonUpExit;
  383. }
  384. iCurButton = (x-ImeData->cxStatLeftMargin)/ImeData->xButtonWi;
  385. if (IsValidButton(iCurButton))
  386. {
  387. ImeData->StatusButtons[vfPrevButton].m_uiButtonState &= ~BTNSTATE_DOWN;
  388. switch (ImeData->StatusButtons[iCurButton].m_ButtonType)
  389. {
  390. case HAN_ENG_TOGGLE_BUTTON:
  391. //if (lpIMC->fdwConversion & IME_CMODE_HANGUL)
  392. // ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
  393. //fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_HANGUL;
  394. //OurImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  395. keybd_event(VK_HANGUL, 0, 0, 0);
  396. keybd_event(VK_HANGUL, 0, KEYEVENTF_KEYUP, 0);
  397. //ImeData->StatusButtons[iCurButton].m_uiButtonState = BTNSTATE_ONMOUSE;
  398. break;
  399. case JUNJA_BANJA_TOGGLE_BUTTON:
  400. //fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE;
  401. //OurImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  402. keybd_event(VK_JUNJA, 0, 0, 0);
  403. keybd_event(VK_JUNJA, 0, KEYEVENTF_KEYUP, 0);
  404. break;
  405. case HANJA_CONV_BUTTON:
  406. //fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_HANJACONVERT;
  407. keybd_event(VK_HANJA, 0, 0, 0);
  408. keybd_event(VK_HANJA, 0, KEYEVENTF_KEYUP, 0);
  409. break;
  410. case IME_PAD_BUTTON:
  411. OurPostMessage(GetWindow(hStatusWnd, GW_OWNER), WM_MSIME_IMEPAD, 0, 0);
  412. break;
  413. default:
  414. DbgAssert(0); // impossible
  415. }
  416. }
  417. }
  418. StatusOnLButtonUpExit:
  419. InvalidateRect( hStatusWnd, &ImeData->rcButtonArea, fFalse );
  420. }
  421. ///////////////////////////////////////////////////////////////////////////////
  422. // Static functions
  423. void PASCAL DestroyStatusWindow(HWND hStatusWnd)
  424. {
  425. HWND hUIWnd;
  426. HGLOBAL hUIPrivate;
  427. LPUIPRIV lpUIPrivate;
  428. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  429. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  430. if (!hUIPrivate) // can not darw status window
  431. return;
  432. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  433. if (!lpUIPrivate) // can not draw status window
  434. return;
  435. lpUIPrivate->nShowStatusCmd = SW_HIDE;
  436. lpUIPrivate->hStatusWnd = (HWND)NULL;
  437. GlobalUnlock(hUIPrivate);
  438. return;
  439. }
  440. // open status window
  441. void PASCAL OpenStatus(HWND hUIWnd)
  442. {
  443. HGLOBAL hUIPrivate;
  444. LPUIPRIV lpUIPrivate;
  445. HIMC hIMC;
  446. PCIMECtx pImeCtx;
  447. CIMEData ImeData(CIMEData::SMReadWrite);
  448. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  449. if (!hUIPrivate) // can not darw status window
  450. return;
  451. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  452. if (!lpUIPrivate) // can not draw status window
  453. return;
  454. if (ImeData->ptStatusPos.x == -1)
  455. GetRegValues(GETSET_REG_STATUSPOS|GETSET_REG_STATUS_BUTTONS);
  456. // if fail to read reg
  457. if (ImeData->ptStatusPos.x == -1)
  458. {
  459. // DbgAssert(0);
  460. // Default position
  461. ImeData->ptStatusPos.x = ImeData->rcWorkArea.right - ImeData->xStatusWi;
  462. ImeData->ptStatusPos.y = ImeData->rcWorkArea.bottom - ImeData->yStatusHi;
  463. }
  464. hIMC = GethImcFromHwnd(hUIWnd);
  465. if (pImeCtx = GetIMECtx(hIMC))
  466. {
  467. // Adjust Status window position force to whithin work area
  468. AdjustStatusBoundary(&ImeData->ptStatusPos);
  469. pImeCtx->SetStatusWndPos(ImeData->ptStatusPos);
  470. }
  471. if (lpUIPrivate->hStatusWnd)
  472. {
  473. SetWindowPos(lpUIPrivate->hStatusWnd, 0,
  474. ImeData->ptStatusPos.x, ImeData->ptStatusPos.y,
  475. ImeData->xStatusWi, ImeData->yStatusHi,
  476. SWP_NOACTIVATE|SWP_NOZORDER);
  477. }
  478. else
  479. { // create status window
  480. lpUIPrivate->hStatusWnd = CreateWindowEx(
  481. 0,
  482. szStatusClassName, TEXT("\0"),
  483. WS_POPUP|WS_DISABLED,
  484. ImeData->ptStatusPos.x, ImeData->ptStatusPos.y,
  485. ImeData->xStatusWi, ImeData->yStatusHi,
  486. hUIWnd, (HMENU)NULL, vpInstData->hInst, NULL);
  487. if (!lpUIPrivate->hStatusWnd)
  488. goto OpenStatusUnlockUIPriv;
  489. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  490. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_XY, 0L);
  491. // Create Tooltip window
  492. if (IsWinNT())
  493. lpUIPrivate->hStatusTTWnd = CreateWindowW(wszTooltipClassName, NULL,
  494. TTS_ALWAYSTIP|WS_DISABLED,
  495. CW_USEDEFAULT, CW_USEDEFAULT,
  496. CW_USEDEFAULT, CW_USEDEFAULT,
  497. lpUIPrivate->hStatusWnd, (HMENU) NULL, vpInstData->hInst, NULL);
  498. else
  499. lpUIPrivate->hStatusTTWnd = CreateWindow(szTooltipClassName, NULL,
  500. TTS_ALWAYSTIP|WS_DISABLED,
  501. CW_USEDEFAULT, CW_USEDEFAULT,
  502. CW_USEDEFAULT, CW_USEDEFAULT,
  503. lpUIPrivate->hStatusWnd, (HMENU) NULL, vpInstData->hInst, NULL);
  504. DbgAssert(lpUIPrivate->hStatusTTWnd != 0);
  505. }
  506. // Check if Pad button disable state
  507. for (UINT iButton=0; iButton<(ImeData->uNumOfButtons); iButton++)
  508. {
  509. if ((ImeData->StatusButtons[iButton].m_ButtonType == IME_PAD_BUTTON))
  510. {
  511. if ((vpInstData->dwSystemInfoFlags & IME_SYSINFO_WINLOGON) != 0)
  512. ImeData->StatusButtons[iButton].m_fEnable = fFalse;
  513. else
  514. ImeData->StatusButtons[iButton].m_fEnable = fTrue;
  515. }
  516. }
  517. // Draw status button tooltip
  518. UpdateStatusTooltip(lpUIPrivate->hStatusWnd, lpUIPrivate->hStatusTTWnd);
  519. ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
  520. OpenStatusUnlockUIPriv:
  521. GlobalUnlock(hUIPrivate);
  522. return;
  523. }
  524. // Show the status window
  525. void ShowStatus(HWND hUIWnd, int nShowStatusCmd)
  526. {
  527. HGLOBAL hUIPrivate;
  528. LPUIPRIV lpUIPrivate;
  529. Dbg(DBGID_UI, TEXT("ShowStatus(): hUIWnd = 0x%X, nShowStatusCmd = %d"), hUIWnd, nShowStatusCmd);
  530. hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
  531. if (!hUIPrivate) // can not darw status window
  532. {
  533. DbgAssert(0);
  534. return;
  535. }
  536. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  537. if (!lpUIPrivate) // can not draw status window
  538. {
  539. DbgAssert(0);
  540. return;
  541. }
  542. //
  543. if (nShowStatusCmd == SW_SHOWNOACTIVATE)
  544. nShowStatusCmd = vfWndOpen[STATE_WINDOW] ? SW_SHOWNOACTIVATE : SW_HIDE;
  545. if (!lpUIPrivate->hStatusWnd)
  546. {
  547. // DbgAssert(0); This occurs if IME status win hide mode
  548. // not in show status window mode
  549. }
  550. else
  551. if (lpUIPrivate->nShowStatusCmd == nShowStatusCmd)
  552. {
  553. // Aleady show/hide status mode
  554. Dbg(DBGID_UI, TEXT("ShowStatus(): Already Show/Hide mode. No update"));
  555. }
  556. else
  557. {
  558. CIMEData ImeData;
  559. // Bug: In Win98. close/open status window msg sequence is cause problem
  560. // when IME config DLG popup
  561. AdjustStatusBoundary(&ImeData->ptStatusPos);
  562. SetWindowPos(lpUIPrivate->hStatusWnd, 0,
  563. ImeData->ptStatusPos.x, ImeData->ptStatusPos.y,
  564. ImeData->xStatusWi, ImeData->yStatusHi,
  565. SWP_NOACTIVATE|SWP_NOZORDER);
  566. ShowWindow(lpUIPrivate->hStatusWnd, nShowStatusCmd);
  567. lpUIPrivate->nShowStatusCmd = nShowStatusCmd;
  568. }
  569. GlobalUnlock(hUIPrivate);
  570. return;
  571. }
  572. void PASCAL FrameControl(HDC hDC, RECT* pRc, int iState)
  573. {
  574. HPEN hPenHigh = 0;
  575. HPEN hPenShadow = 0;
  576. switch( iState )
  577. {
  578. case BTNSTATE_PUSHED:
  579. case BTNSTATE_HANJACONV:
  580. hPenHigh = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW) );
  581. hPenShadow = CreatePen( PS_SOLID, 1, RGB(255,255,255) );
  582. break;
  583. case BTNSTATE_ONMOUSE:
  584. hPenHigh = CreatePen( PS_SOLID, 1, RGB(255,255,255) );
  585. hPenShadow = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW) );
  586. break;
  587. default:
  588. break;
  589. }
  590. //FillRect( hDC, pRc, GetSysColorBrush(COLOR_3DFACE) ); // base
  591. if( iState == BTNSTATE_PUSHED || iState == BTNSTATE_ONMOUSE || iState == BTNSTATE_HANJACONV)
  592. {
  593. HPEN hPenOld = (HPEN)SelectObject( hDC, hPenHigh );
  594. MoveToEx( hDC, pRc->left, pRc->bottom, NULL );
  595. LineTo( hDC, pRc->left, pRc->top );
  596. LineTo( hDC, pRc->right, pRc->top );
  597. SelectObject( hDC, hPenShadow );
  598. LineTo( hDC, pRc->right, pRc->bottom );
  599. LineTo( hDC, pRc->left-1, pRc->bottom );
  600. SelectObject( hDC, hPenOld );
  601. DeleteObject( hPenHigh );
  602. DeleteObject( hPenShadow );
  603. }
  604. }
  605. // Raster Ops
  606. #define ROP_PSDPxax 0x00B8074AL
  607. void PASCAL PaintStatusWindow(HWND hStatusWnd, HDC hDC)
  608. {
  609. HWND hUIWnd;
  610. HIMC hIMC;
  611. PCIMECtx pImeCtx;
  612. //DWORD dwCMode, dwSent;
  613. //BOOL fOpen;
  614. UINT uiButtonState, uiDrawButtonShape;
  615. //HBRUSH hCaptionBrush;
  616. HBITMAP /*hBMStatusWin, hBMOld,*/ hBMButtonOld, /*hBMClient,*/ hBMTmpButton;
  617. RECT rcFrame, rcButton;//, rcCaption;
  618. int ixButton, iyButton;
  619. CIMEData ImeData;
  620. // to prevent blinking, use second buffer
  621. HDC hDCMem = CreateCompatibleDC(hDC);
  622. HBITMAP hBmpShow = CreateCompatibleBitmap(hDC, ImeData->xStatusWi, ImeData->yStatusHi);
  623. HBITMAP hBmpOldShow = (HBITMAP)SelectObject( hDCMem, hBmpShow );
  624. HDC hButtonMemDC = CreateCompatibleDC(hDC);
  625. LPCTSTR lpszBtnResouceName;
  626. Dbg(DBGID_UI, TEXT("PaintStatusWindow(): hStatusWnd = 0x%X"), hStatusWnd);
  627. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  628. hIMC = GethImcFromHwnd(hUIWnd);
  629. //if (!hIMC)
  630. // {
  631. // DbgAssert(0);
  632. // return;
  633. // }
  634. if ((pImeCtx = GetIMECtx(hIMC))==NULL)
  635. return;
  636. // Get conversion and open status and
  637. // fOpen = OurImmGetOpenStatus(hIMC);
  638. // OurImmGetConversionStatus(hIMC, &dwCMode, &dwSent);
  639. // Draw Frame
  640. GetClientRect( hStatusWnd, &rcFrame );
  641. DbgAssert(ImeData->xStatusWi == rcFrame.right);
  642. FillRect(hDCMem, &rcFrame, GetSysColorBrush(COLOR_3DFACE));
  643. DrawEdge(hDCMem, &rcFrame, EDGE_RAISED, BF_RECT);
  644. #if NOTUSED
  645. // Draw left two verticals
  646. ::SetRect(&rcButton, 2, ImeData->cyStatMargin-1, 4, ImeData->yStatusHi - ImeData->cyStatMargin);
  647. FrameControl(hDCMem, &rcButton, BTNSTATE_ONMOUSE);
  648. ::SetRect(&rcButton, 6, ImeData->cyStatMargin-1, 8, ImeData->yStatusHi - ImeData->cyStatMargin);
  649. FrameControl(hDCMem, &rcButton, BTNSTATE_ONMOUSE);
  650. #endif
  651. // Button 1 : This button Always Han/Eng toggle button.
  652. ixButton = ImeData->cxStatLeftMargin; iyButton = ImeData->cyStatButton;
  653. for (UINT iButton=0; iButton<ImeData->uNumOfButtons; iButton++)
  654. {
  655. uiButtonState = ImeData->StatusButtons[iButton].m_uiButtonState;
  656. uiDrawButtonShape = BTNSTATE_NORMAL;
  657. switch (ImeData->StatusButtons[iButton].m_ButtonType)
  658. {
  659. case HAN_ENG_TOGGLE_BUTTON :
  660. // if English mode
  661. if (!(pImeCtx->GetConversionMode() & IME_CMODE_HANGUL))
  662. {
  663. // English button always pushed
  664. uiDrawButtonShape = BTNSTATE_PUSHED;
  665. // Down and hovering
  666. if (uiButtonState & BTNSTATE_DOWN) // if BTNSTATE_DOWN set, always BTNSTATE_ONMOUSE set too
  667. lpszBtnResouceName = // Dented white gray GA
  668. MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpDownOnMouseID);
  669. else
  670. // If just mouse cursor hovering
  671. if (uiButtonState & BTNSTATE_ONMOUSE)
  672. {
  673. lpszBtnResouceName = // Dented white gray GA
  674. MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpOnMouseID);
  675. }
  676. // No mouse
  677. else
  678. lpszBtnResouceName = // Dented gray GA
  679. MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  680. }
  681. else
  682. {
  683. // Down and hovering
  684. if (uiButtonState & BTNSTATE_DOWN) // if BTNSTATE_DOWN set, always BTNSTATE_ONMOUSE set too
  685. {
  686. uiDrawButtonShape = BTNSTATE_PUSHED;
  687. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  688. }
  689. else
  690. {
  691. // Down or hovering
  692. if (uiButtonState & BTNSTATE_ONMOUSE)
  693. uiDrawButtonShape = BTNSTATE_ONMOUSE;
  694. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpNormalID);
  695. }
  696. }
  697. break;
  698. case JUNJA_BANJA_TOGGLE_BUTTON:
  699. if (pImeCtx->IsOpen() && (pImeCtx->GetConversionMode() & IME_CMODE_FULLSHAPE))
  700. {
  701. uiDrawButtonShape = BTNSTATE_PUSHED;
  702. if (uiButtonState & BTNSTATE_DOWN) // if BTNSTATE_DOWN set, always BTNSTATE_ONMOUSE set too
  703. lpszBtnResouceName = // Dented white gray GA
  704. MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpDownOnMouseID);
  705. else
  706. if (uiButtonState & BTNSTATE_ONMOUSE)
  707. lpszBtnResouceName =
  708. MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpOnMouseID);
  709. else
  710. lpszBtnResouceName =
  711. MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  712. }
  713. else
  714. {
  715. if (uiButtonState & BTNSTATE_DOWN)
  716. {
  717. uiDrawButtonShape = BTNSTATE_PUSHED;
  718. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  719. }
  720. else
  721. {
  722. if (uiButtonState & BTNSTATE_ONMOUSE)
  723. uiDrawButtonShape = BTNSTATE_ONMOUSE;
  724. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpNormalID);
  725. }
  726. }
  727. break;
  728. case HANJA_CONV_BUTTON:
  729. if ((pImeCtx->GetConversionMode() & IME_CMODE_HANJACONVERT))
  730. {
  731. uiDrawButtonShape = BTNSTATE_PUSHED;
  732. if (uiButtonState & BTNSTATE_ONMOUSE)
  733. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpOnMouseID);
  734. else
  735. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  736. }
  737. else
  738. {
  739. if (uiButtonState & BTNSTATE_DOWN)
  740. {
  741. uiDrawButtonShape = BTNSTATE_PUSHED;
  742. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  743. }
  744. else
  745. {
  746. if (uiButtonState & BTNSTATE_ONMOUSE)
  747. uiDrawButtonShape = BTNSTATE_ONMOUSE;
  748. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpNormalID);
  749. }
  750. }
  751. break;
  752. case IME_PAD_BUTTON:
  753. LPCImePadSvr lpCImePadSvr;
  754. BOOL fVisible;
  755. lpCImePadSvr = CImePadSvr::GetCImePadSvr();
  756. fVisible = fFalse;
  757. if (lpCImePadSvr)
  758. lpCImePadSvr->IsVisible(&fVisible);
  759. if (lpCImePadSvr && fVisible)
  760. {
  761. uiDrawButtonShape = BTNSTATE_PUSHED;
  762. if (uiButtonState & BTNSTATE_ONMOUSE)
  763. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpOnMouseID);
  764. else
  765. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  766. }
  767. else
  768. {
  769. if (uiButtonState & BTNSTATE_DOWN)
  770. {
  771. uiDrawButtonShape = BTNSTATE_PUSHED;
  772. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpPushedID);
  773. }
  774. else
  775. {
  776. if (uiButtonState & BTNSTATE_ONMOUSE)
  777. uiDrawButtonShape = BTNSTATE_ONMOUSE;
  778. lpszBtnResouceName = MAKEINTRESOURCE(ImeData->StatusButtons[iButton].m_BmpNormalID);
  779. }
  780. }
  781. break;
  782. default:
  783. DbgAssert(0);
  784. }
  785. // use LoadImage instead LoadBitmap to change button face color according to system setting
  786. // LR_LOADMAP3DCOLORS flag does it.
  787. hBMTmpButton = (HBITMAP)OurLoadImage(lpszBtnResouceName, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADMAP3DCOLORS );
  788. hBMButtonOld = (HBITMAP)SelectObject(hButtonMemDC, hBMTmpButton);
  789. if (ImeData->StatusButtons[iButton].m_fEnable)
  790. {
  791. if ( ImeData->StatusButtons[iButton].m_uiButtonState==BTNSTATE_PUSHED
  792. || ImeData->StatusButtons[iButton].m_uiButtonState==BTNSTATE_HANJACONV)
  793. {
  794. BitBlt(hDCMem, ixButton+1, iyButton+1, ImeData->xButtonWi, ImeData->yButtonHi, hButtonMemDC, 0, 0, SRCCOPY);
  795. }
  796. else
  797. BitBlt(hDCMem, ixButton, iyButton, ImeData->xButtonWi, ImeData->yButtonHi, hButtonMemDC, 0, 0, SRCCOPY);
  798. }
  799. else
  800. {
  801. BITMAP bmp;
  802. HDC hDCMono;
  803. HBITMAP hBmpMono, hBmpOldMono;
  804. HBRUSH hBr, hOldBr;
  805. GetObject(hBMTmpButton, sizeof(BITMAP), &bmp);
  806. // mono bitmap
  807. hDCMono = CreateCompatibleDC(hDC);
  808. hBmpMono = CreateBitmap(bmp.bmWidth/*-2*/, bmp.bmHeight/*-2*/, 1, 1, NULL);
  809. hBmpOldMono = (HBITMAP)SelectObject(hDCMono, hBmpMono);
  810. // initalize whole area with 0's
  811. PatBlt(hDCMono, 0, 0, bmp.bmWidth-2, bmp.bmHeight-2, WHITENESS);
  812. SetBkColor(hButtonMemDC, GetSysColor(COLOR_3DFACE));
  813. BitBlt(hDCMono, 0, 0, bmp.bmWidth, bmp.bmHeight, hButtonMemDC, 0, 0, SRCCOPY);
  814. SetBkColor(hButtonMemDC, GetSysColor(COLOR_3DHILIGHT));
  815. // OR in the new 1's
  816. BitBlt(hDCMono, 0, 0, bmp.bmWidth, bmp.bmHeight, hButtonMemDC, 0, 0, SRCPAINT);
  817. // - mask proc end
  818. SetTextColor(hDCMem, 0L); // 0's in mono -> 0 (for ROP)
  819. SetBkColor(hDCMem, (COLORREF)0x00FFFFFFL); // 1's in mono -> 1
  820. // disabled - draw the hilighted shadow
  821. hBr = GetSysColorBrush(COLOR_3DHILIGHT);
  822. hOldBr = (HBRUSH)SelectObject(hDCMem, hBr);
  823. if (hBr && hOldBr)
  824. {
  825. // draw hilight color where we have 0's in the mask
  826. BitBlt(hDCMem, ixButton, iyButton, ImeData->xButtonWi, ImeData->yButtonHi, hDCMono, 0, 0, ROP_PSDPxax);
  827. SelectObject(hDCMem, hOldBr);
  828. DeleteObject(hBr);
  829. }
  830. hBr = GetSysColorBrush(COLOR_3DSHADOW);
  831. hOldBr = (HBRUSH)SelectObject(hDCMem, hBr);
  832. if (hBr && hOldBr)
  833. {
  834. // draw the shadow color where we have 0's in the mask
  835. BitBlt(hDCMem, ixButton-1, iyButton-1, ImeData->xButtonWi, ImeData->yButtonHi, hDCMono, 0, 0, ROP_PSDPxax);
  836. SelectObject(hDCMem, hOldBr);
  837. DeleteObject(hBr);
  838. }
  839. if (hBmpMono)
  840. {
  841. SelectObject(hDCMono, hBmpOldMono);
  842. DeleteObject(hBmpMono);
  843. DeleteDC(hDCMono);
  844. }
  845. }
  846. SelectObject(hButtonMemDC, hBMButtonOld);
  847. DeleteObject(hBMTmpButton);
  848. //
  849. ::SetRect(&rcButton, ixButton, iyButton, ixButton+ImeData->xButtonWi-1, iyButton+ImeData->yButtonHi-1);
  850. FrameControl(hDCMem, &rcButton, uiDrawButtonShape);
  851. //
  852. ixButton += ImeData->xButtonWi;
  853. }
  854. BitBlt(hDC, 0, 0, ImeData->xStatusWi, ImeData->yStatusHi, hDCMem, 0, 0, SRCCOPY);
  855. DeleteObject(hButtonMemDC);
  856. SelectObject(hDCMem, hBmpOldShow);
  857. DeleteObject(hDCMem);
  858. DeleteObject(hBmpShow);
  859. }
  860. void PASCAL AdjustStatusBoundary(LPPOINT lppt)
  861. {
  862. CIMEData ImeData(CIMEData::SMReadWrite);
  863. #if 1 // MultiMonitor support
  864. RECT rcWorkArea;//, rcMonitorWorkArea;
  865. {
  866. RECT rcStatusWnd;
  867. *(LPPOINT)&rcStatusWnd = *lppt;
  868. rcStatusWnd.right = rcStatusWnd.left + ImeData->xStatusWi;
  869. rcStatusWnd.bottom = rcStatusWnd.top + ImeData->yStatusHi;
  870. ImeMonitorWorkAreaFromRect(&rcStatusWnd, &rcWorkArea);
  871. }
  872. // display boundary check
  873. if (lppt->x < rcWorkArea.left)
  874. lppt->x = rcWorkArea.left;
  875. else
  876. if (lppt->x + ImeData->xStatusWi > rcWorkArea.right)
  877. lppt->x = (rcWorkArea.right - ImeData->xStatusWi);
  878. if (lppt->y < rcWorkArea.top)
  879. lppt->y = rcWorkArea.top;
  880. else
  881. if (lppt->y + ImeData->yStatusHi + 1 > rcWorkArea.bottom)
  882. lppt->y = rcWorkArea.bottom - ImeData->yStatusHi + 1;
  883. //rcMonitorWorkArea = rcWorkArea;
  884. //OffsetRect(&rcMonitorWorkArea, -rcMonitorWorkArea.left, -rcMonitorWorkArea.top);
  885. //DbgAssert(rcMonitorWorkArea.right!=0);
  886. //DbgAssert(rcMonitorWorkArea.bottom!=0);
  887. if (rcWorkArea.right-rcWorkArea.left != 0)
  888. ImeData->xStatusRel = ( ((long)(lppt->x+ImeData->xStatusWi-rcWorkArea.left))<<16 )
  889. / (rcWorkArea.right-rcWorkArea.left);
  890. if (rcWorkArea.bottom-rcWorkArea.top != 0)
  891. ImeData->yStatusRel = ( ((long)(lppt->y+ImeData->yStatusHi-rcWorkArea.top))<<16 )
  892. / (rcWorkArea.bottom-rcWorkArea.top);
  893. #else
  894. // display boundary check
  895. if (lppt->x < ImeData->rcWorkArea.left)
  896. lppt->x = ImeData->rcWorkArea.left;
  897. else
  898. if (lppt->x + ImeData->xStatusWi > ImeData->rcWorkArea.right)
  899. lppt->x = (ImeData->rcWorkArea.right - ImeData->xStatusWi);
  900. if (lppt->y < ImeData->rcWorkArea.top)
  901. lppt->y = ImeData->rcWorkArea.top;
  902. else
  903. if (lppt->y + ImeData->yStatusHi > ImeData->rcWorkArea.bottom)
  904. lppt->y = (ImeData->rcWorkArea.bottom - ImeData->yStatusHi);
  905. #endif
  906. return;
  907. }
  908. BOOL fSetStatusWindowPos(HWND hStatusWnd, POINT *ptStatusWndPos)
  909. {
  910. HWND hUIWnd;
  911. HIMC hIMC;
  912. PCIMECtx pImeCtx;
  913. // LPINPUTCONTEXT lpIMC;
  914. POINT ptCtxStatusWnd;
  915. RECT rcStatusWnd;
  916. CIMEData ImeData(CIMEData::SMReadWrite);
  917. Dbg(DBGID_UI, TEXT("fSetStatusWindowPos(): hStatusWnd=0x%X, ptStatusWndPos = 0x%08lX"), hStatusWnd, ptStatusWndPos);
  918. DbgAssert(hStatusWnd != 0);
  919. if (hStatusWnd == 0)
  920. {
  921. DbgAssert(0);
  922. return fFalse;
  923. }
  924. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  925. GetWindowRect(hStatusWnd, &rcStatusWnd);
  926. hIMC = GethImcFromHwnd(hUIWnd);
  927. //if (hIMC == 0)
  928. // {
  929. // DbgAssert(0);
  930. // return fFalse;
  931. // }
  932. //lpIMC = (LPINPUTCONTEXT)OurImmLockIMC(hIMC);
  933. //if (lpIMC == 0)
  934. // {
  935. // DbgAssert(0);
  936. // return fFalse;
  937. // }
  938. if ((pImeCtx = GetIMECtx(hIMC))==NULL)
  939. return fFalse;
  940. pImeCtx->GetStatusWndPos(&ptCtxStatusWnd);
  941. // if ptStatusWndPos is NULL, Set current IMC value
  942. // IMN_SETSTATUSWINDOWPOS
  943. if (ptStatusWndPos == NULL)
  944. {
  945. if ( ptCtxStatusWnd.x != rcStatusWnd.left
  946. || ptCtxStatusWnd.y != rcStatusWnd.top)
  947. {
  948. // display boundary adjust
  949. AdjustStatusBoundary(&ptCtxStatusWnd);
  950. ImeData->ptStatusPos = ptCtxStatusWnd;
  951. }
  952. }
  953. else // Set ptStatusWndPos to IMC. StatusOnLButtonUp()
  954. {
  955. if ( ptStatusWndPos->x != rcStatusWnd.left
  956. || ptStatusWndPos->y != rcStatusWnd.top)
  957. {
  958. // display boundary adjust
  959. AdjustStatusBoundary(ptStatusWndPos);
  960. ImeData->ptStatusPos = *ptStatusWndPos;
  961. pImeCtx->SetStatusWndPos(*ptStatusWndPos);
  962. }
  963. }
  964. ///////////////////////////////////////////////////////////////////////////
  965. SetWindowPos(hStatusWnd, 0,
  966. ImeData->ptStatusPos.x, ImeData->ptStatusPos.y,
  967. 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  968. // Set reg value
  969. SetRegValues(GETSET_REG_STATUSPOS);
  970. return (fTrue);
  971. }
  972. void InitButtonState()
  973. {
  974. CIMEData ImeData(CIMEData::SMReadWrite);
  975. for (int i=0; i<MAX_NUM_OF_STATUS_BUTTONS;i++)
  976. ImeData->StatusButtons[i].m_uiButtonState = BTNSTATE_NORMAL;
  977. vfPrevButton = -1;
  978. }
  979. void StatusDisplayChange(HWND hUIWnd)
  980. {
  981. RECT rcMonitorWorkArea, rcMonitorWorkArea2;
  982. POINT ptNewStatus;
  983. HIMC hIMC;
  984. PCIMECtx pImeCtx;
  985. CIMEData ImeData;
  986. hIMC = GethImcFromHwnd(hUIWnd);
  987. //if (hIMC == 0)
  988. // {
  989. // DbgAssert(0);
  990. // return;
  991. // }
  992. //lpIMC = OurImmLockIMC(hIMC);
  993. if ((pImeCtx = GetIMECtx(hIMC))==NULL)
  994. return;
  995. // If still not initialized, skip status win pos adjust.
  996. if (ImeData->ptStatusPos.x == -1)
  997. return;
  998. ImeMonitorWorkAreaFromWindow(pImeCtx->GetAppWnd(), &rcMonitorWorkArea);
  999. rcMonitorWorkArea2 = rcMonitorWorkArea;
  1000. OffsetRect(&rcMonitorWorkArea2, -rcMonitorWorkArea2.left, -rcMonitorWorkArea2.top);
  1001. ptNewStatus.x = ((rcMonitorWorkArea2.right * ImeData->xStatusRel + 0x8000)>>16) + rcMonitorWorkArea.left
  1002. -ImeData->xStatusWi;
  1003. if (ptNewStatus.x < 0)
  1004. ptNewStatus.x = 0;
  1005. ptNewStatus.y = ((rcMonitorWorkArea2.bottom * ImeData->yStatusRel + 0x8000)>>16) + rcMonitorWorkArea.top
  1006. -ImeData->yStatusHi;
  1007. if (ptNewStatus.y < 0)
  1008. ptNewStatus.y = 0;
  1009. Dbg(DBGID_UI, TEXT("StatusDisplayChange() : xStatusRel = %d, yStatusRel=%d, newX=%d, newY=%d"), (int)(ImeData->xStatusRel), (int)(ImeData->yStatusRel), ptNewStatus.x, ptNewStatus.y);
  1010. ImeData->ptStatusPos = ptNewStatus;
  1011. SetRegValues(GETSET_REG_STATUSPOS);
  1012. }
  1013. void PASCAL UpdateStatusTooltip(HWND hStatusWnd, HWND hStatusTTWnd)
  1014. {
  1015. TOOLINFO ti;
  1016. CHAR szTooltip[80];
  1017. WCHAR wszTooltip[80];
  1018. CIMEData ImeData;
  1019. UINT uiMsgAdd = TTM_ADDTOOLW;
  1020. if (IsWin(hStatusWnd) && IsWin(hStatusTTWnd))
  1021. {
  1022. ZeroMemory(&ti, sizeof(TOOLINFO));
  1023. ti.cbSize = sizeof(TOOLINFO);
  1024. ti.uFlags = 0;
  1025. ti.hwnd = hStatusWnd;
  1026. ti.hinst = vpInstData->hInst;
  1027. //
  1028. ti.rect.left = ImeData->cxStatLeftMargin;
  1029. ti.rect.right = ti.rect.left + ImeData->xButtonWi;
  1030. ti.rect.top = ImeData->cyStatButton;
  1031. ti.rect.bottom = ti.rect.top + ImeData->yButtonHi;
  1032. if (!IsWinNT())
  1033. uiMsgAdd = TTM_ADDTOOL;
  1034. // Set Button text
  1035. for (UINT i=0; i<ImeData->uNumOfButtons; i++)
  1036. {
  1037. ti.uId = i;
  1038. if (IsWinNT())
  1039. {
  1040. OurLoadStringW(vpInstData->hInst, ImeData->StatusButtons[i].m_ToolTipStrID,
  1041. wszTooltip, sizeof(wszTooltip)/sizeof(WCHAR));
  1042. ti.lpszText = (LPSTR)wszTooltip;
  1043. }
  1044. else
  1045. {
  1046. OurLoadStringA(vpInstData->hInst, ImeData->StatusButtons[i].m_ToolTipStrID,
  1047. szTooltip, sizeof(szTooltip)/sizeof(CHAR));
  1048. ti.lpszText = szTooltip;
  1049. }
  1050. OurSendMessage(hStatusTTWnd, uiMsgAdd, 0, (LPARAM)(LPTOOLINFO)&ti);
  1051. // Next Button area
  1052. ti.rect.left += ImeData->xButtonWi;
  1053. ti.rect.right += ImeData->xButtonWi;
  1054. }
  1055. }
  1056. }