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.

529 lines
18 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. UISTATE.C
  5. ++*/
  6. /**********************************************************************/
  7. #include "windows.h"
  8. #include "immdev.h"
  9. #include "fakeime.h"
  10. #include "resource.h"
  11. /**********************************************************************/
  12. /* */
  13. /* StatusWndProc() */
  14. /* IME UI window procedure */
  15. /* */
  16. /**********************************************************************/
  17. LRESULT CALLBACK StatusWndProc( hWnd, message, wParam, lParam )
  18. HWND hWnd;
  19. UINT message;
  20. WPARAM wParam;
  21. LPARAM lParam;
  22. {
  23. PAINTSTRUCT ps;
  24. HWND hUIWnd;
  25. HDC hDC;
  26. HBITMAP hbmpStatus;
  27. switch (message)
  28. {
  29. case WM_UI_UPDATE:
  30. InvalidateRect(hWnd,NULL,FALSE);
  31. break;
  32. case WM_PAINT:
  33. hDC = BeginPaint(hWnd,&ps);
  34. PaintStatus(hWnd,hDC,NULL,0);
  35. EndPaint(hWnd,&ps);
  36. break;
  37. case WM_MOUSEMOVE:
  38. case WM_SETCURSOR:
  39. case WM_LBUTTONUP:
  40. case WM_RBUTTONUP:
  41. ButtonStatus(hWnd,message,wParam,lParam);
  42. if ((message == WM_SETCURSOR) &&
  43. (HIWORD(lParam) != WM_LBUTTONDOWN) &&
  44. (HIWORD(lParam) != WM_RBUTTONDOWN))
  45. return DefWindowProc(hWnd,message,wParam,lParam);
  46. if ((message == WM_LBUTTONUP) || (message == WM_RBUTTONUP))
  47. {
  48. SetWindowLong(hWnd,FIGWL_MOUSE,0L);
  49. SetWindowLong(hWnd,FIGWL_PUSHSTATUS,0L);
  50. }
  51. break;
  52. case WM_MOVE:
  53. hUIWnd = (HWND)GetWindowLongPtr(hWnd,FIGWL_SVRWND);
  54. if (IsWindow(hUIWnd))
  55. SendMessage(hUIWnd,WM_UI_STATEMOVE,wParam,lParam);
  56. break;
  57. case WM_CREATE:
  58. hbmpStatus = LoadBitmap(hInst,TEXT("STATUSBMP"));
  59. SetWindowLongPtr(hWnd,FIGWL_STATUSBMP,(LONG_PTR)hbmpStatus);
  60. hbmpStatus = LoadBitmap(hInst,TEXT("CLOSEBMP"));
  61. SetWindowLongPtr(hWnd,FIGWL_CLOSEBMP,(LONG_PTR)hbmpStatus);
  62. break;
  63. case WM_DESTROY:
  64. hbmpStatus = (HBITMAP)GetWindowLongPtr(hWnd,FIGWL_STATUSBMP);
  65. DeleteObject(hbmpStatus);
  66. hbmpStatus = (HBITMAP)GetWindowLongPtr(hWnd,FIGWL_CLOSEBMP);
  67. DeleteObject(hbmpStatus);
  68. break;
  69. default:
  70. if (!MyIsIMEMessage(message))
  71. return DefWindowProc(hWnd,message,wParam,lParam);
  72. break;
  73. }
  74. return 0;
  75. }
  76. /**********************************************************************/
  77. /* */
  78. /* CheckPushedStatus() */
  79. /* */
  80. /**********************************************************************/
  81. DWORD PASCAL CheckPushedStatus( HWND hStatusWnd, LPPOINT lppt)
  82. {
  83. POINT pt;
  84. RECT rc;
  85. if (lppt)
  86. {
  87. pt = *lppt;
  88. ScreenToClient(hStatusWnd,&pt);
  89. GetClientRect(hStatusWnd,&rc);
  90. if (!PtInRect(&rc,pt))
  91. return 0;
  92. if (pt.y > GetSystemMetrics(SM_CYSMCAPTION))
  93. {
  94. if (pt.x < BTX)
  95. return PUSHED_STATUS_HDR;
  96. else if (pt.x < (BTX * 2))
  97. return PUSHED_STATUS_MODE;
  98. else if (pt.x < (BTX * 3))
  99. return PUSHED_STATUS_ROMAN;
  100. }
  101. else
  102. {
  103. RECT rc;
  104. rc.left = STCLBT_X;
  105. rc.top = STCLBT_Y;
  106. rc.right = STCLBT_X + STCLBT_DX;
  107. rc.bottom = STCLBT_Y + STCLBT_DY;
  108. if (PtInRect(&rc,pt))
  109. return PUSHED_STATUS_CLOSE;
  110. }
  111. }
  112. return 0;
  113. }
  114. /**********************************************************************/
  115. /* */
  116. /* BTXFromCmode() */
  117. /* */
  118. /**********************************************************************/
  119. int PASCAL BTXFromCmode( DWORD dwCmode)
  120. {
  121. if (dwCmode & IME_CMODE_FULLSHAPE)
  122. {
  123. if (!(dwCmode & IME_CMODE_LANGUAGE))
  124. return BTFALPH;
  125. else if ((dwCmode & IME_CMODE_LANGUAGE) == IME_CMODE_NATIVE)
  126. return BTFHIRA;
  127. else
  128. return BTFKATA;
  129. }
  130. else
  131. {
  132. if ((dwCmode & IME_CMODE_LANGUAGE) == IME_CMODE_ALPHANUMERIC)
  133. return BTHALPH;
  134. else
  135. return BTHKATA;
  136. }
  137. }
  138. /**********************************************************************/
  139. /* */
  140. /* PaintStatus() */
  141. /* */
  142. /**********************************************************************/
  143. void PASCAL PaintStatus( HWND hStatusWnd , HDC hDC, LPPOINT lppt, DWORD dwPushedStatus)
  144. {
  145. HIMC hIMC;
  146. LPINPUTCONTEXT lpIMC;
  147. HDC hMemDC;
  148. HBITMAP hbmpOld;
  149. int x;
  150. HWND hSvrWnd;
  151. hSvrWnd = (HWND)GetWindowLongPtr(hStatusWnd,FIGWL_SVRWND);
  152. if (hIMC = (HIMC)GetWindowLongPtr(hSvrWnd,IMMGWLP_IMC))
  153. {
  154. HBITMAP hbmpStatus;
  155. HBRUSH hOldBrush,hBrush;
  156. int nCyCap = GetSystemMetrics(SM_CYSMCAPTION);
  157. RECT rc;
  158. lpIMC = ImmLockIMC(hIMC);
  159. hMemDC = CreateCompatibleDC(hDC);
  160. // Paint Caption.
  161. hBrush = CreateSolidBrush(GetSysColor(COLOR_ACTIVECAPTION));
  162. hOldBrush = SelectObject(hDC,hBrush);
  163. rc.top = rc.left = 0;
  164. rc.right = BTX*3;
  165. rc.bottom = nCyCap;
  166. FillRect(hDC,&rc,hBrush);
  167. SelectObject(hDC,hOldBrush);
  168. DeleteObject(hBrush);
  169. // Paint CloseButton.
  170. hbmpStatus = (HBITMAP)GetWindowLongPtr(hStatusWnd,FIGWL_CLOSEBMP);
  171. hbmpOld = SelectObject(hMemDC,hbmpStatus);
  172. if (!(dwPushedStatus & PUSHED_STATUS_CLOSE))
  173. BitBlt(hDC,STCLBT_X,STCLBT_Y,STCLBT_DX,STCLBT_DY,
  174. hMemDC,0,0,SRCCOPY);
  175. else
  176. BitBlt(hDC,STCLBT_X,STCLBT_Y,STCLBT_DX,STCLBT_DY,
  177. hMemDC,STCLBT_DX,0,SRCCOPY);
  178. hbmpStatus = (HBITMAP)GetWindowLongPtr(hStatusWnd,FIGWL_STATUSBMP);
  179. SelectObject(hMemDC,hbmpStatus);
  180. // Paint HDR.
  181. x = BTEMPT;
  182. if (lpIMC->fOpen)
  183. x = 0;
  184. if (!(dwPushedStatus & PUSHED_STATUS_HDR))
  185. BitBlt(hDC,0,nCyCap,BTX,BTY,hMemDC,x,0,SRCCOPY);
  186. else
  187. BitBlt(hDC,0,nCyCap,BTX,BTY,hMemDC,x,BTY,SRCCOPY);
  188. // Paint MODE.
  189. x = BTXFromCmode(lpIMC->fdwConversion);
  190. if (!(dwPushedStatus & PUSHED_STATUS_MODE))
  191. BitBlt(hDC,BTX,nCyCap,BTX,BTY,hMemDC,x,0,SRCCOPY);
  192. else
  193. BitBlt(hDC,BTX,nCyCap,BTX,BTY,hMemDC,x,BTY,SRCCOPY);
  194. // Paint Roman MODE.
  195. x = BTEMPT;
  196. if (lpIMC->fdwConversion & IME_CMODE_ROMAN)
  197. x = BTROMA;
  198. if (!(dwPushedStatus & PUSHED_STATUS_ROMAN))
  199. BitBlt(hDC,BTX*2,nCyCap,BTX,BTY,hMemDC,x,0,SRCCOPY);
  200. else
  201. BitBlt(hDC,BTX*2,nCyCap,BTX,BTY,hMemDC,x,BTY,SRCCOPY);
  202. SelectObject(hMemDC,hbmpOld);
  203. DeleteDC(hMemDC);
  204. ImmUnlockIMC(hIMC);
  205. }
  206. }
  207. /**********************************************************************/
  208. /* */
  209. /* GetUINextMode(hWnd,message,wParam,lParam) */
  210. /* */
  211. /**********************************************************************/
  212. DWORD PASCAL GetUINextMode( DWORD fdwConversion, DWORD dwPushed)
  213. {
  214. DWORD dwTemp;
  215. BOOL fFullShape = ((fdwConversion & IME_CMODE_FULLSHAPE) != 0);
  216. //
  217. // When the mode button is pushed, the convmode will be chage as follow
  218. // rotation.
  219. //
  220. // FULLSHAPE,HIRAGANA ->
  221. // FULLSHAPE,KATAKANA ->
  222. // FULLSHAPE,ALPHANUMERIC ->
  223. // HALFSHAPE,KATAKANA ->
  224. // HALFSHAPE,ALPHANUMERIC ->
  225. // FULLSHAPE,HIRAGANA
  226. //
  227. if (dwPushed == PUSHED_STATUS_MODE)
  228. {
  229. dwTemp = fdwConversion & IME_CMODE_LANGUAGE;
  230. if ((fFullShape) && (dwTemp == IME_CMODE_NATIVE))
  231. return (fdwConversion & ~IME_CMODE_LANGUAGE) | IME_CMODE_KATAKANA | IME_CMODE_NATIVE;
  232. if ((fFullShape) && (dwTemp == (IME_CMODE_KATAKANA | IME_CMODE_NATIVE)))
  233. return (fdwConversion & ~IME_CMODE_LANGUAGE);
  234. if ((fFullShape) && (dwTemp == 0))
  235. {
  236. fdwConversion &= ~IME_CMODE_FULLSHAPE;
  237. return (fdwConversion & ~IME_CMODE_LANGUAGE)
  238. | IME_CMODE_KATAKANA | IME_CMODE_NATIVE;
  239. }
  240. if ((!fFullShape) && (dwTemp == (IME_CMODE_KATAKANA | IME_CMODE_NATIVE)))
  241. return (fdwConversion & ~IME_CMODE_LANGUAGE);
  242. if ((!fFullShape) && (!dwTemp))
  243. {
  244. fdwConversion |= IME_CMODE_FULLSHAPE;
  245. return (fdwConversion & ~IME_CMODE_LANGUAGE) | IME_CMODE_NATIVE;
  246. }
  247. }
  248. if (dwPushed == PUSHED_STATUS_ROMAN)
  249. {
  250. if (fdwConversion & IME_CMODE_ROMAN)
  251. return fdwConversion & ~IME_CMODE_ROMAN;
  252. else
  253. return fdwConversion | IME_CMODE_ROMAN;
  254. }
  255. return fdwConversion;
  256. }
  257. /**********************************************************************/
  258. /* */
  259. /* ButtonStatus(hStatusWnd,message,wParam,lParam) */
  260. /* */
  261. /**********************************************************************/
  262. void PASCAL ButtonStatus( HWND hStatusWnd, UINT message, WPARAM wParam, LPARAM lParam)
  263. {
  264. POINT pt;
  265. HDC hDC;
  266. DWORD dwMouse;
  267. DWORD dwPushedStatus;
  268. DWORD dwTemp;
  269. DWORD fdwConversion;
  270. HIMC hIMC;
  271. HWND hSvrWnd;
  272. BOOL fOpen;
  273. HMENU hMenu;
  274. static POINT ptdif;
  275. static RECT drc;
  276. static RECT rc;
  277. static DWORD dwCurrentPushedStatus;
  278. hDC = GetDC(hStatusWnd);
  279. switch (message)
  280. {
  281. case WM_SETCURSOR:
  282. if ( HIWORD(lParam) == WM_LBUTTONDOWN
  283. || HIWORD(lParam) == WM_RBUTTONDOWN )
  284. {
  285. GetCursorPos( &pt );
  286. SetCapture(hStatusWnd);
  287. GetWindowRect(hStatusWnd,&drc);
  288. ptdif.x = pt.x - drc.left;
  289. ptdif.y = pt.y - drc.top;
  290. rc = drc;
  291. rc.right -= rc.left;
  292. rc.bottom -= rc.top;
  293. SetWindowLong(hStatusWnd,FIGWL_MOUSE,FIM_CAPUTURED);
  294. SetWindowLong(hStatusWnd, FIGWL_PUSHSTATUS, dwPushedStatus = CheckPushedStatus(hStatusWnd,&pt));
  295. PaintStatus(hStatusWnd,hDC,&pt, dwPushedStatus);
  296. dwCurrentPushedStatus = dwPushedStatus;
  297. }
  298. break;
  299. case WM_MOUSEMOVE:
  300. dwMouse = GetWindowLong(hStatusWnd,FIGWL_MOUSE);
  301. if (!(dwPushedStatus = GetWindowLong(hStatusWnd, FIGWL_PUSHSTATUS)))
  302. {
  303. if (dwMouse & FIM_MOVED)
  304. {
  305. DrawUIBorder(&drc);
  306. GetCursorPos( &pt );
  307. drc.left = pt.x - ptdif.x;
  308. drc.top = pt.y - ptdif.y;
  309. drc.right = drc.left + rc.right;
  310. drc.bottom = drc.top + rc.bottom;
  311. DrawUIBorder(&drc);
  312. }
  313. else if (dwMouse & FIM_CAPUTURED)
  314. {
  315. DrawUIBorder(&drc);
  316. SetWindowLong(hStatusWnd,FIGWL_MOUSE,dwMouse | FIM_MOVED);
  317. }
  318. }
  319. else
  320. {
  321. GetCursorPos(&pt);
  322. dwTemp = CheckPushedStatus(hStatusWnd,&pt);
  323. if ((dwTemp ^ dwCurrentPushedStatus) & dwPushedStatus)
  324. PaintStatus(hStatusWnd,hDC,&pt, dwPushedStatus & dwTemp);
  325. dwCurrentPushedStatus = dwTemp;
  326. }
  327. break;
  328. case WM_RBUTTONUP:
  329. dwMouse = GetWindowLong(hStatusWnd,FIGWL_MOUSE);
  330. if (dwMouse & FIM_CAPUTURED)
  331. {
  332. ReleaseCapture();
  333. if (dwMouse & FIM_MOVED)
  334. {
  335. DrawUIBorder(&drc);
  336. GetCursorPos( &pt );
  337. MoveWindow(hStatusWnd,pt.x - ptdif.x,
  338. pt.y - ptdif.y,
  339. rc.right,
  340. rc.bottom,TRUE);
  341. }
  342. }
  343. PaintStatus(hStatusWnd,hDC,NULL,0);
  344. hSvrWnd = (HWND)GetWindowLongPtr(hStatusWnd,FIGWL_SVRWND);
  345. hMenu = LoadMenu(hInst, TEXT("RIGHTCLKMENU"));
  346. if (hMenu && (hIMC = (HIMC)GetWindowLongPtr(hSvrWnd,IMMGWLP_IMC)))
  347. {
  348. int cmd;
  349. POINT pt;
  350. HMENU hSubMenu = GetSubMenu(hMenu, 0);
  351. pt.x = (int)LOWORD(lParam),
  352. pt.y = (int)HIWORD(lParam),
  353. ClientToScreen(hStatusWnd, &pt);
  354. cmd = TrackPopupMenu(hSubMenu,
  355. TPM_RETURNCMD,
  356. pt.x,
  357. pt.y,
  358. 0,
  359. hStatusWnd,
  360. NULL);
  361. switch (cmd)
  362. {
  363. case IDM_RECONVERT:
  364. {
  365. DWORD dwSize = (DWORD) MyImmRequestMessage(hIMC, IMR_RECONVERTSTRING, 0);
  366. if (dwSize)
  367. {
  368. LPRECONVERTSTRING lpRS;
  369. lpRS = (LPRECONVERTSTRING)GlobalAlloc(GPTR, dwSize);
  370. lpRS->dwSize = dwSize;
  371. if (dwSize = (DWORD) MyImmRequestMessage(hIMC, IMR_RECONVERTSTRING, (LPARAM)lpRS)) {
  372. #ifdef DEBUG
  373. {
  374. TCHAR szDev[80];
  375. LPMYSTR lpDump= (LPMYSTR)(((LPSTR)lpRS) + lpRS->dwStrOffset);
  376. *(LPMYSTR)(lpDump + lpRS->dwStrLen) = MYTEXT('\0');
  377. OutputDebugString(TEXT("IMR_RECONVERTSTRING\r\n"));
  378. wsprintf(szDev, TEXT("dwSize %x\r\n"), lpRS->dwSize);
  379. OutputDebugString(szDev);
  380. wsprintf(szDev, TEXT("dwVersion %x\r\n"), lpRS->dwVersion);
  381. OutputDebugString(szDev);
  382. wsprintf(szDev, TEXT("dwStrLen %x\r\n"), lpRS->dwStrLen);
  383. OutputDebugString(szDev);
  384. wsprintf(szDev, TEXT("dwStrOffset %x\r\n"), lpRS->dwStrOffset);
  385. OutputDebugString(szDev);
  386. wsprintf(szDev, TEXT("dwCompStrLen %x\r\n"), lpRS->dwCompStrLen);
  387. OutputDebugString(szDev);
  388. wsprintf(szDev, TEXT("dwCompStrOffset %x\r\n"), lpRS->dwCompStrOffset);
  389. OutputDebugString(szDev);
  390. wsprintf(szDev, TEXT("dwTargetStrLen %x\r\n"), lpRS->dwTargetStrLen);
  391. OutputDebugString(szDev);
  392. wsprintf(szDev, TEXT("dwTargetStrOffset %x\r\n"), lpRS->dwTargetStrOffset);
  393. OutputDebugString(szDev);
  394. MyOutputDebugString(lpDump);
  395. OutputDebugString(TEXT("\r\n"));
  396. }
  397. #endif
  398. MyImmRequestMessage(hIMC, IMR_CONFIRMRECONVERTSTRING, (LPARAM)lpRS);
  399. }
  400. #ifdef DEBUG
  401. else
  402. OutputDebugString(TEXT("ImmRequestMessage returned 0\r\n"));
  403. #endif
  404. GlobalFree((HANDLE)lpRS);
  405. }
  406. break;
  407. }
  408. case IDM_ABOUT:
  409. ImmConfigureIME(GetKeyboardLayout(0), NULL, IME_CONFIG_GENERAL, 0);
  410. break;
  411. default:
  412. break;
  413. }
  414. }
  415. if (hMenu)
  416. DestroyMenu(hMenu);
  417. break;
  418. case WM_LBUTTONUP:
  419. dwMouse = GetWindowLong(hStatusWnd,FIGWL_MOUSE);
  420. if (dwMouse & FIM_CAPUTURED)
  421. {
  422. ReleaseCapture();
  423. if (dwMouse & FIM_MOVED)
  424. {
  425. DrawUIBorder(&drc);
  426. GetCursorPos( &pt );
  427. MoveWindow(hStatusWnd,pt.x - ptdif.x,
  428. pt.y - ptdif.y,
  429. rc.right,
  430. rc.bottom,TRUE);
  431. }
  432. }
  433. hSvrWnd = (HWND)GetWindowLongPtr(hStatusWnd,FIGWL_SVRWND);
  434. if (hIMC = (HIMC)GetWindowLongPtr(hSvrWnd,IMMGWLP_IMC))
  435. {
  436. GetCursorPos(&pt);
  437. dwPushedStatus = GetWindowLong(hStatusWnd, FIGWL_PUSHSTATUS);
  438. dwPushedStatus &= CheckPushedStatus(hStatusWnd,&pt);
  439. if (!dwPushedStatus) {
  440. } else if (dwPushedStatus == PUSHED_STATUS_CLOSE) {
  441. } else if (dwPushedStatus == PUSHED_STATUS_HDR)
  442. {
  443. fOpen = ImmGetOpenStatus(hIMC);
  444. fOpen = !fOpen;
  445. ImmSetOpenStatus(hIMC,fOpen);
  446. }
  447. else
  448. {
  449. ImmGetConversionStatus(hIMC,&fdwConversion,&dwTemp);
  450. fdwConversion = GetUINextMode(fdwConversion,dwPushedStatus);
  451. ImmSetConversionStatus(hIMC,fdwConversion,dwTemp);
  452. }
  453. }
  454. PaintStatus(hStatusWnd,hDC,NULL,0);
  455. break;
  456. }
  457. ReleaseDC(hStatusWnd,hDC);
  458. }
  459. /**********************************************************************/
  460. /* */
  461. /* UpdateStatusWindow(lpUIExtra) */
  462. /* */
  463. /**********************************************************************/
  464. void PASCAL UpdateStatusWindow(LPUIEXTRA lpUIExtra)
  465. {
  466. if (IsWindow(lpUIExtra->uiStatus.hWnd))
  467. SendMessage(lpUIExtra->uiStatus.hWnd,WM_UI_UPDATE,0,0L);
  468. }