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.

886 lines
26 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 <htmlhelp.h>
  9. #include <string.h>
  10. #include <regstr.h>
  11. #include <imedefs.h>
  12. #include <resource.h>
  13. extern HWND hCrtDlg;
  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. LPPOINTS lppt,
  42. HWND hUIWnd)
  43. {
  44. RECT rcWorkArea;
  45. #ifdef MUL_MONITOR
  46. {
  47. RECT rcStatusWnd;
  48. rcStatusWnd.left = lppt->x;
  49. rcStatusWnd.top = lppt->y;
  50. rcStatusWnd.right = rcStatusWnd.left + sImeG.xStatusWi;
  51. rcStatusWnd.bottom = rcStatusWnd.top + sImeG.yStatusHi;
  52. rcWorkArea = ImeMonitorWorkAreaFromRect(&rcStatusWnd);
  53. }
  54. #else
  55. rcWorkArea = sImeG.rcWorkArea;
  56. #endif
  57. // display boundary check
  58. if (lppt->x < rcWorkArea.left) {
  59. lppt->x = (short)rcWorkArea.left;
  60. } else if (lppt->x + sImeG.xStatusWi > rcWorkArea.right) {
  61. lppt->x = (short)(rcWorkArea.right - sImeG.xStatusWi);
  62. }
  63. if (lppt->y < rcWorkArea.top) {
  64. lppt->y = (short)rcWorkArea.top;
  65. } else if (lppt->y + sImeG.yStatusHi > rcWorkArea.bottom) {
  66. lppt->y = (short)(rcWorkArea.bottom - sImeG.yStatusHi);
  67. }
  68. if(sImeG.IC_Trace) {
  69. } else {
  70. int Comp_CandWndLen;
  71. Comp_CandWndLen = 0;
  72. if(uStartComp) {
  73. Comp_CandWndLen += lpImeL->xCompWi + UI_MARGIN;
  74. }
  75. if(uOpenCand) {
  76. Comp_CandWndLen += sImeG.xCandWi + UI_MARGIN;
  77. }
  78. if(lppt->x + sImeG.xStatusWi + Comp_CandWndLen > rcWorkArea.right) {
  79. lppt->x=(SHORT)(rcWorkArea.right-sImeG.xStatusWi-Comp_CandWndLen);
  80. }
  81. }
  82. return;
  83. }
  84. /**********************************************************************/
  85. /* SetStatusWindowPos() */
  86. /**********************************************************************/
  87. LRESULT PASCAL SetStatusWindowPos(
  88. HWND hStatusWnd)
  89. {
  90. HWND hUIWnd;
  91. HIMC hIMC;
  92. LPINPUTCONTEXT lpIMC;
  93. RECT rcStatusWnd;
  94. POINTS ptPos;
  95. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  96. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  97. if (!hIMC) {
  98. return (1L);
  99. }
  100. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  101. if (!lpIMC) { // Oh! Oh!
  102. return (1L);
  103. }
  104. ptPos.x = (short)lpIMC->ptStatusWndPos.x;
  105. ptPos.y = (short)lpIMC->ptStatusWndPos.y;
  106. // display boundary adjust
  107. AdjustStatusBoundary(&ptPos, hUIWnd);
  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. HWND hUIWnd,
  120. int nShowStatusCmd)
  121. {
  122. HGLOBAL hUIPrivate;
  123. LPUIPRIV lpUIPrivate;
  124. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  125. if (!hUIPrivate) { // can not darw status window
  126. return;
  127. }
  128. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  129. if (!lpUIPrivate) { // can not draw status window
  130. return;
  131. }
  132. if (!lpUIPrivate->hStatusWnd) {
  133. // not in show status window mode
  134. } else if (lpUIPrivate->nShowStatusCmd != nShowStatusCmd) {
  135. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  136. SetStatusWindowPos(lpUIPrivate->hStatusWnd);
  137. ShowWindow(lpUIPrivate->hStatusWnd, nShowStatusCmd);
  138. lpUIPrivate->nShowStatusCmd = nShowStatusCmd;
  139. } else {
  140. }
  141. GlobalUnlock(hUIPrivate);
  142. return;
  143. }
  144. /**********************************************************************/
  145. /* OpenStatus() */
  146. /**********************************************************************/
  147. void PASCAL OpenStatus( // open status window
  148. HWND hUIWnd)
  149. {
  150. HGLOBAL hUIPrivate;
  151. LPUIPRIV lpUIPrivate;
  152. HIMC hIMC;
  153. LPINPUTCONTEXT lpIMC;
  154. POINT ptPos;
  155. int nShowStatusCmd;
  156. RECT rcWorkArea;
  157. rcWorkArea = sImeG.rcWorkArea;
  158. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  159. if (!hUIPrivate) // can not darw status window
  160. return;
  161. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  162. if (!lpUIPrivate) // can not draw status window
  163. return;
  164. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  165. if (!hIMC) {
  166. ptPos.x = rcWorkArea.left;
  167. ptPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
  168. nShowStatusCmd = SW_HIDE;
  169. }
  170. else if (lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)) {
  171. #ifdef MUL_MONITOR
  172. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  173. #endif
  174. if (lpIMC->ptStatusWndPos.x < rcWorkArea.left) {
  175. lpIMC->ptStatusWndPos.x = rcWorkArea.left;
  176. }
  177. else if (lpIMC->ptStatusWndPos.x+sImeG.xStatusWi>rcWorkArea.right) {
  178. lpIMC->ptStatusWndPos.x = rcWorkArea.right - sImeG.xStatusWi;
  179. }
  180. if (lpIMC->ptStatusWndPos.y < rcWorkArea.top) {
  181. lpIMC->ptStatusWndPos.y = rcWorkArea.top;
  182. }
  183. else if (lpIMC->ptStatusWndPos.y+sImeG.yStatusHi>rcWorkArea.right) {
  184. lpIMC->ptStatusWndPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
  185. }
  186. if(sImeG.IC_Trace) {
  187. ptPos.x = lpIMC->ptStatusWndPos.x;
  188. ptPos.y = lpIMC->ptStatusWndPos.y;
  189. } else {
  190. ptPos.x = rcWorkArea.left;
  191. ptPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
  192. }
  193. ImmUnlockIMC(hIMC);
  194. nShowStatusCmd = SW_SHOWNOACTIVATE;
  195. } else {
  196. ptPos.x = rcWorkArea.left;
  197. ptPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
  198. nShowStatusCmd = SW_HIDE;
  199. }
  200. if (lpUIPrivate->hStatusWnd) {
  201. SetWindowPos(lpUIPrivate->hStatusWnd, NULL,
  202. ptPos.x, ptPos.y,
  203. 0, 0,
  204. SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  205. } else { // create status window
  206. lpUIPrivate->hStatusWnd = CreateWindowEx(
  207. WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,
  208. szStatusClassName, NULL,
  209. WS_POPUP|WS_DISABLED,
  210. ptPos.x, ptPos.y,
  211. sImeG.xStatusWi, sImeG.yStatusHi,
  212. hUIWnd, (HMENU)NULL, hInst, NULL);
  213. if ( lpUIPrivate->hStatusWnd != NULL )
  214. {
  215. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  216. SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_XY, 0L);
  217. }
  218. }
  219. lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
  220. if (hIMC) {
  221. ShowStatus( hUIWnd, SW_SHOWNOACTIVATE);
  222. }
  223. GlobalUnlock(hUIPrivate);
  224. return;
  225. }
  226. /**********************************************************************/
  227. /* DestroyStatusWindow() */
  228. /**********************************************************************/
  229. void PASCAL DestroyStatusWindow(
  230. HWND hStatusWnd)
  231. {
  232. HWND hUIWnd;
  233. HGLOBAL hUIPrivate;
  234. LPUIPRIV lpUIPrivate;
  235. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  236. // undo the drag border
  237. DrawDragBorder(hStatusWnd,
  238. GetWindowLong(hStatusWnd, UI_MOVE_XY),
  239. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  240. }
  241. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  242. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  243. if (!hUIPrivate) { // can not darw status window
  244. return;
  245. }
  246. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  247. if (!lpUIPrivate) { // can not draw status window
  248. return;
  249. }
  250. lpUIPrivate->nShowStatusCmd = SW_HIDE;
  251. lpUIPrivate->hStatusWnd = (HWND)NULL;
  252. GlobalUnlock(hUIPrivate);
  253. return;
  254. }
  255. /**********************************************************************/
  256. /* SetStatus */
  257. /**********************************************************************/
  258. void PASCAL SetStatus(
  259. HWND hStatusWnd,
  260. LPPOINT lpptCursor)
  261. {
  262. HWND hUIWnd;
  263. HIMC hIMC;
  264. LPINPUTCONTEXT lpIMC;
  265. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  266. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  267. if (!hIMC) {
  268. return;
  269. }
  270. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  271. if (!lpIMC) {
  272. return;
  273. }
  274. if (!lpIMC->fOpen) {
  275. ImmSetOpenStatus(hIMC, TRUE);
  276. } else if (PtInRect(&sImeG.rcImeIcon, *lpptCursor)) {
  277. DWORD fdwConversion;
  278. if (lpIMC->fdwConversion & (IME_CMODE_CHARCODE|IME_CMODE_EUDC)) {
  279. // change to native mode
  280. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  281. ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC);
  282. } else if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  283. // change to alphanumeric mode
  284. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_CHARCODE |
  285. IME_CMODE_NATIVE | IME_CMODE_EUDC);
  286. } else {
  287. BYTE lpbKeyState[256];
  288. GetKeyboardState(lpbKeyState);
  289. if (lpbKeyState[VK_CAPITAL] & 1)
  290. {
  291. // Simulate a key press
  292. keybd_event( VK_CAPITAL,
  293. 0x3A,
  294. KEYEVENTF_EXTENDEDKEY | 0,
  295. 0 );
  296. // Simulate a key release
  297. keybd_event( VK_CAPITAL,
  298. 0x3A,
  299. KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
  300. 0);
  301. }
  302. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  303. ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC);
  304. // 10.11 add
  305. uCaps = 0;
  306. }
  307. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  308. } else if (PtInRect(&sImeG.rcImeName, *lpptCursor)) {
  309. #if defined(COMBO_IME)
  310. DWORD dwConvMode;
  311. int cxBorder, cyBorder;
  312. HKEY hKeyCurrVersion;
  313. HKEY hKeyGB;
  314. DWORD retCode;
  315. //change current IME index
  316. dwConvMode = lpIMC->fdwConversion ^ (IME_CMODE_INDEX_FIRST << sImeL.dwRegImeIndex);
  317. sImeL.dwRegImeIndex = (sImeL.dwRegImeIndex+1) % IMEINDEXNUM;
  318. szImeName = pszImeName[sImeL.dwRegImeIndex];
  319. dwConvMode |= (IME_CMODE_INDEX_FIRST << sImeL.dwRegImeIndex);
  320. // re-caculate statusuidata
  321. cxBorder = GetSystemMetrics(SM_CXBORDER);
  322. cyBorder = GetSystemMetrics(SM_CYBORDER);
  323. InitStatusUIData(cxBorder, cyBorder);
  324. ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
  325. //set IME index in registry
  326. retCode = OpenReg_PathSetup(&hKeyCurrVersion);
  327. if (retCode) {
  328. return;
  329. }
  330. retCode = RegCreateKeyEx(hKeyCurrVersion, szImeRegName, 0,
  331. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKeyGB, NULL);
  332. if (retCode) {
  333. RegCloseKey(hKeyCurrVersion);
  334. return;
  335. }
  336. retCode = RegSetValueEx (hKeyGB,
  337. szRegImeIndex,
  338. (DWORD)0,
  339. REG_DWORD,
  340. (LPBYTE)&sImeL.dwRegImeIndex,
  341. sizeof(DWORD));
  342. if (retCode) {
  343. RegCloseKey(hKeyGB);
  344. RegCloseKey(hKeyCurrVersion);
  345. return;
  346. }
  347. RegCloseKey(hKeyGB);
  348. RegCloseKey(hKeyCurrVersion);
  349. #endif //COMBO_IME
  350. } else if (PtInRect(&sImeG.rcShapeText, *lpptCursor)) {
  351. DWORD dwConvMode;
  352. if (lpIMC->fdwConversion & IME_CMODE_CHARCODE) {
  353. MessageBeep((UINT)-1);
  354. } else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  355. MessageBeep((UINT)-1);
  356. } else {
  357. dwConvMode = lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE;
  358. ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
  359. }
  360. } else if (PtInRect(&sImeG.rcSymbol, *lpptCursor)) {
  361. DWORD fdwConversion;
  362. if (lpIMC->fdwConversion & IME_CMODE_CHARCODE) {
  363. MessageBeep((UINT)-1);
  364. } else {
  365. fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SYMBOL;
  366. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  367. }
  368. } else if (PtInRect(&sImeG.rcSKText, *lpptCursor)) {
  369. DWORD fdwConversion;
  370. LPPRIVCONTEXT lpImcP;
  371. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  372. if(lpImcP) {
  373. if(!(lpImeL->hSKMenu)) {
  374. lpImeL->hSKMenu = LoadMenu (hInst, TEXT("SKMENU"));
  375. }
  376. lpImeL->dwSKState[lpImeL->dwSKWant] =
  377. lpImeL->dwSKState[lpImeL->dwSKWant]^1;
  378. fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SOFTKBD;
  379. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  380. ImmUnlockIMCC(lpIMC->hPrivate);
  381. } else {
  382. MessageBeep((UINT)-1);
  383. }
  384. } else {
  385. MessageBeep((UINT)-1);
  386. }
  387. ImmUnlockIMC(hIMC);
  388. return;
  389. }
  390. /**********************************************************************/
  391. /* StatusSetCursor() */
  392. /**********************************************************************/
  393. void PASCAL StatusSetCursor(
  394. HWND hStatusWnd,
  395. LPARAM lParam)
  396. {
  397. POINT ptCursor, ptSavCursor;
  398. RECT rcWnd;
  399. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  400. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  401. return;
  402. }
  403. GetCursorPos(&ptCursor);
  404. ptSavCursor = ptCursor;
  405. ScreenToClient(hStatusWnd, &ptCursor);
  406. if (PtInRect(&sImeG.rcStatusText, ptCursor)) {
  407. SetCursor(LoadCursor(hInst, szHandCursor));
  408. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  409. SetStatus(hStatusWnd, &ptCursor);
  410. } else if (HIWORD(lParam) == WM_RBUTTONUP) {
  411. if (PtInRect(&sImeG.rcSKText, ptCursor)) {
  412. static BOOL fSoftkey= FALSE;
  413. // prevent recursive
  414. if (fSoftkey) {
  415. // configuration already bring up
  416. return;
  417. }
  418. fSoftkey = TRUE;
  419. SoftkeyMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  420. fSoftkey = FALSE;
  421. }else{
  422. static BOOL fCmenu=FALSE;
  423. // prevent recursive
  424. if (fCmenu) {
  425. // configuration already bring up
  426. return;
  427. }
  428. fCmenu = TRUE;
  429. ContextMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  430. fCmenu = FALSE;
  431. }
  432. }
  433. return;
  434. } else {
  435. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  436. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  437. // start drag
  438. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  439. } else {
  440. return;
  441. }
  442. }
  443. SetCapture(hStatusWnd);
  444. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  445. MAKELONG(ptSavCursor.x, ptSavCursor.y));
  446. GetWindowRect(hStatusWnd, &rcWnd);
  447. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
  448. MAKELONG(ptSavCursor.x - rcWnd.left, ptSavCursor.y - rcWnd.top));
  449. DrawDragBorder(hStatusWnd, MAKELONG(ptSavCursor.x, ptSavCursor.y),
  450. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  451. return;
  452. }
  453. /**********************************************************************/
  454. /* PaintStatusWindow() */
  455. /**********************************************************************/
  456. void PASCAL PaintStatusWindow(
  457. HDC hDC,
  458. HWND hStatusWnd)
  459. {
  460. HWND hUIWnd;
  461. HIMC hIMC;
  462. LPINPUTCONTEXT lpIMC;
  463. LPPRIVCONTEXT lpImcP;
  464. HGDIOBJ hOldFont;
  465. HBITMAP hImeIconBmp, hShapeBmp, hSymbolBmp, hSKBmp;
  466. HBITMAP hOldBmp;
  467. HDC hMemDC;
  468. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  469. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  470. if (!hIMC) {
  471. MessageBeep((UINT)-1);
  472. return;
  473. }
  474. if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  475. MessageBeep((UINT)-1);
  476. return;
  477. }
  478. // get lpImcP
  479. if(!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
  480. MessageBeep((UINT)-1);
  481. return;
  482. }
  483. #if defined(COMBO_IME)
  484. //in case the IME index has been changed and the ImeName size is different
  485. {
  486. POINTS ptPos;
  487. ptPos.x = (short)lpIMC->ptStatusWndPos.x;
  488. ptPos.y = (short)lpIMC->ptStatusWndPos.y;
  489. SetWindowPos(hStatusWnd, NULL,
  490. ptPos.x, ptPos.y,
  491. sImeG.xStatusWi, sImeG.yStatusHi,
  492. SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOZORDER);
  493. }
  494. #endif //COMBO_IME
  495. // set font
  496. if (sImeG.fDiffSysCharSet) {
  497. LOGFONT lfFont;
  498. ZeroMemory(&lfFont, sizeof(lfFont));
  499. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  500. lfFont.lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  501. lfFont.lfCharSet = NATIVE_CHARSET;
  502. lstrcpy(lfFont.lfFaceName, TEXT("Simsun"));
  503. SelectObject(hDC, CreateFontIndirect(&lfFont));
  504. }
  505. // draw Ime Name
  506. if (lpIMC->fOpen) {
  507. SetTextColor(hDC, RGB(0x00, 0x00, 0x00));
  508. } else {
  509. SetTextColor(hDC, RGB(0x80, 0x80, 0x80));
  510. }
  511. SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
  512. DrawText(hDC, szImeName, lstrlen(szImeName),
  513. &sImeG.rcImeName, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  514. DrawConvexRect(hDC,
  515. sImeG.rcImeName.left,
  516. sImeG.rcImeName.top,
  517. sImeG.rcImeName.right - 1,
  518. sImeG.rcImeName.bottom - 1);
  519. DrawConvexRectP(hDC,
  520. sImeG.rcImeName.left,
  521. sImeG.rcImeName.top,
  522. sImeG.rcImeName.right,
  523. sImeG.rcImeName.bottom);
  524. // load all bitmap
  525. hSymbolBmp = (HBITMAP)NULL;
  526. hShapeBmp = (HBITMAP)NULL;
  527. hSKBmp = (HBITMAP)NULL;
  528. if (!lpIMC->fOpen) {
  529. hSymbolBmp = LoadBitmap(hInst, szNone);
  530. hShapeBmp = LoadBitmap(hInst, szNone);
  531. hSKBmp = LoadBitmap(hInst, szNone);
  532. hImeIconBmp = LoadBitmap(hInst, szChinese);
  533. } else if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  534. hImeIconBmp = LoadBitmap(hInst, szChinese);
  535. } else {
  536. hImeIconBmp = LoadBitmap(hInst, szEnglish);
  537. }
  538. if (!hShapeBmp) {
  539. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
  540. hShapeBmp = LoadBitmap(hInst, szFullShape);
  541. } else {
  542. hShapeBmp = LoadBitmap(hInst, szHalfShape);
  543. }
  544. }
  545. if (!hSymbolBmp) {
  546. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  547. hSymbolBmp = LoadBitmap(hInst, szSymbol);
  548. } else {
  549. hSymbolBmp = LoadBitmap(hInst, szNoSymbol);
  550. }
  551. }
  552. if (!hSKBmp) {
  553. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  554. hSKBmp = LoadBitmap(hInst, szSoftKBD);
  555. } else {
  556. hSKBmp = LoadBitmap(hInst, szNoSoftKBD);
  557. }
  558. }
  559. ImmUnlockIMC(hIMC);
  560. ImmUnlockIMCC(lpIMC->hPrivate);
  561. hMemDC = CreateCompatibleDC(hDC);
  562. hOldBmp = SelectObject(hMemDC, hImeIconBmp);
  563. BitBlt(hDC, sImeG.rcImeIcon.left, sImeG.rcImeIcon.top,
  564. sImeG.rcImeIcon.right - sImeG.rcImeIcon.left,
  565. STATUS_DIM_Y,
  566. hMemDC, 0, 0, SRCCOPY);
  567. SelectObject(hMemDC, hShapeBmp);
  568. BitBlt(hDC, sImeG.rcShapeText.left, sImeG.rcShapeText.top,
  569. sImeG.rcShapeText.right - sImeG.rcShapeText.left,
  570. STATUS_DIM_Y,
  571. hMemDC, 0, 0, SRCCOPY);
  572. SelectObject(hMemDC, hSymbolBmp);
  573. BitBlt(hDC, sImeG.rcSymbol.left, sImeG.rcSymbol.top,
  574. sImeG.rcSymbol.right - sImeG.rcSymbol.left,
  575. STATUS_DIM_Y,
  576. hMemDC, 0, 0, SRCCOPY);
  577. SelectObject(hMemDC, hSKBmp);
  578. BitBlt(hDC, sImeG.rcSKText.left, sImeG.rcSKText.top,
  579. sImeG.xStatusWi - sImeG.rcSKText.left,
  580. STATUS_DIM_Y,
  581. hMemDC, 0, 0, SRCCOPY);
  582. SelectObject(hMemDC, hOldBmp);
  583. DeleteDC(hMemDC);
  584. DeleteObject(hImeIconBmp);
  585. DeleteObject(hSymbolBmp);
  586. DeleteObject(hShapeBmp);
  587. DeleteObject(hSKBmp);
  588. if (sImeG.fDiffSysCharSet) {
  589. DeleteObject(SelectObject(hDC, hOldFont));
  590. }
  591. return;
  592. }
  593. /**********************************************************************/
  594. /* StatusWndProc() */
  595. /**********************************************************************/
  596. LRESULT CALLBACK StatusWndProc(
  597. HWND hStatusWnd,
  598. UINT uMsg,
  599. WPARAM wParam,
  600. LPARAM lParam)
  601. {
  602. switch (uMsg) {
  603. case WM_DESTROY:
  604. DestroyStatusWindow(hStatusWnd);
  605. break;
  606. case WM_SETCURSOR:
  607. StatusSetCursor(hStatusWnd, lParam);
  608. break;
  609. case WM_MOUSEMOVE:
  610. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  611. POINT ptCursor;
  612. DrawDragBorder(hStatusWnd,
  613. GetWindowLong(hStatusWnd, UI_MOVE_XY),
  614. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  615. GetCursorPos(&ptCursor);
  616. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  617. MAKELONG(ptCursor.x, ptCursor.y));
  618. DrawDragBorder(hStatusWnd, MAKELONG(ptCursor.x, ptCursor.y),
  619. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  620. } else {
  621. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  622. }
  623. break;
  624. case WM_LBUTTONUP:
  625. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  626. LONG lTmpCursor, lTmpOffset;
  627. lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
  628. // calculate the org by the offset
  629. lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  630. DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
  631. (*(LPPOINTS)&lTmpCursor).x -= (*(LPPOINTS)&lTmpOffset).x;
  632. (*(LPPOINTS)&lTmpCursor).y -= (*(LPPOINTS)&lTmpOffset).y;
  633. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  634. ReleaseCapture();
  635. AdjustStatusBoundary((LPPOINTS)&lTmpCursor,
  636. GetWindow(hStatusWnd, GW_OWNER));
  637. SendMessage(GetWindow(hStatusWnd, GW_OWNER), WM_IME_CONTROL,
  638. IMC_SETSTATUSWINDOWPOS, lTmpCursor);
  639. } else {
  640. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  641. }
  642. break;
  643. case WM_IME_NOTIFY:
  644. // get work area for changing
  645. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  646. if (wParam == IMN_SETSTATUSWINDOWPOS) {
  647. SetStatusWindowPos(hStatusWnd);
  648. }
  649. break;
  650. case WM_PAINT:
  651. {
  652. HDC hDC;
  653. PAINTSTRUCT ps;
  654. hDC = BeginPaint(hStatusWnd, &ps);
  655. PaintStatusWindow(hDC, hStatusWnd);
  656. EndPaint(hStatusWnd, &ps);
  657. }
  658. break;
  659. case WM_MOUSEACTIVATE:
  660. return (MA_NOACTIVATE);
  661. default:
  662. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  663. }
  664. return (0L);
  665. }
  666. /**********************************************************************/
  667. /* ImeVerDlgProc() */
  668. /* Return Value: */
  669. /* TRUE - successful, FALSE - failure */
  670. /**********************************************************************/
  671. BOOL FAR PASCAL ImeVerDlgProc( // dialog procedure of configuration
  672. HWND hDlg,
  673. UINT uMessage,
  674. WORD wParam,
  675. LONG lParam)
  676. {
  677. RECT rc;
  678. LONG DlgWidth, DlgHeight;
  679. switch (uMessage) {
  680. case WM_INITDIALOG:
  681. hCrtDlg = hDlg;
  682. // reset position
  683. GetWindowRect(hDlg, &rc);
  684. DlgWidth = rc.right - rc.left;
  685. DlgHeight = rc.bottom - rc.top;
  686. SetWindowPos(hDlg, HWND_TOP,
  687. (int)(sImeG.rcWorkArea.right - DlgWidth)/2,
  688. (int)(sImeG.rcWorkArea.bottom - DlgHeight)/2,
  689. (int)0, (int)0, SWP_NOSIZE);
  690. return (TRUE); // don't want to set focus to special control
  691. case WM_COMMAND:
  692. switch (wParam) {
  693. case IDOK:
  694. EndDialog(hDlg, FALSE);
  695. break;
  696. case IDCANCEL:
  697. EndDialog(hDlg, FALSE);
  698. break;
  699. default:
  700. return (FALSE);
  701. break;
  702. }
  703. return (TRUE);
  704. case WM_CLOSE:
  705. EndDialog(hDlg, FALSE);
  706. return FALSE;
  707. case WM_PAINT:
  708. {
  709. RECT rc;
  710. GetClientRect(hDlg, &rc);
  711. DrawConvexRect(GetDC(hDlg),
  712. rc.left + 10,
  713. rc.top + 10,
  714. rc.right - 10 - 1,
  715. rc.bottom - 43 - 1);
  716. DrawConvexRectP(GetDC(hDlg),
  717. rc.left + 10,
  718. rc.top + 10,
  719. rc.right - 10,
  720. rc.bottom - 43);
  721. }
  722. return (FALSE);
  723. default:
  724. return (FALSE);
  725. }
  726. return (TRUE);
  727. }