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.

890 lines
27 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. if ( !GetKeyboardState(lpbKeyState) )
  289. {
  290. ImmUnlockIMC(hIMC);
  291. return;
  292. }
  293. if (lpbKeyState[VK_CAPITAL] & 1)
  294. {
  295. // Simulate a key press
  296. keybd_event( VK_CAPITAL,
  297. 0x3A,
  298. KEYEVENTF_EXTENDEDKEY | 0,
  299. 0 );
  300. // Simulate a key release
  301. keybd_event( VK_CAPITAL,
  302. 0x3A,
  303. KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
  304. 0);
  305. }
  306. fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
  307. ~(IME_CMODE_CHARCODE | IME_CMODE_EUDC);
  308. // 10.11 add
  309. uCaps = 0;
  310. }
  311. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  312. } else if (PtInRect(&sImeG.rcImeName, *lpptCursor)) {
  313. #if defined(COMBO_IME)
  314. DWORD dwConvMode;
  315. int cxBorder, cyBorder;
  316. HKEY hKeyCurrVersion;
  317. HKEY hKeyGB;
  318. DWORD retCode;
  319. //change current IME index
  320. dwConvMode = lpIMC->fdwConversion ^ (IME_CMODE_INDEX_FIRST << sImeL.dwRegImeIndex);
  321. sImeL.dwRegImeIndex = (sImeL.dwRegImeIndex+1) % IMEINDEXNUM;
  322. szImeName = pszImeName[sImeL.dwRegImeIndex];
  323. dwConvMode |= (IME_CMODE_INDEX_FIRST << sImeL.dwRegImeIndex);
  324. // re-caculate statusuidata
  325. cxBorder = GetSystemMetrics(SM_CXBORDER);
  326. cyBorder = GetSystemMetrics(SM_CYBORDER);
  327. InitStatusUIData(cxBorder, cyBorder);
  328. ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
  329. //set IME index in registry
  330. retCode = OpenReg_PathSetup(&hKeyCurrVersion);
  331. if (retCode) {
  332. return;
  333. }
  334. retCode = RegCreateKeyEx(hKeyCurrVersion, szImeRegName, 0,
  335. NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKeyGB, NULL);
  336. if (retCode) {
  337. RegCloseKey(hKeyCurrVersion);
  338. return;
  339. }
  340. retCode = RegSetValueEx (hKeyGB,
  341. szRegImeIndex,
  342. (DWORD)0,
  343. REG_DWORD,
  344. (LPBYTE)&sImeL.dwRegImeIndex,
  345. sizeof(DWORD));
  346. if (retCode) {
  347. RegCloseKey(hKeyGB);
  348. RegCloseKey(hKeyCurrVersion);
  349. return;
  350. }
  351. RegCloseKey(hKeyGB);
  352. RegCloseKey(hKeyCurrVersion);
  353. #endif //COMBO_IME
  354. } else if (PtInRect(&sImeG.rcShapeText, *lpptCursor)) {
  355. DWORD dwConvMode;
  356. if (lpIMC->fdwConversion & IME_CMODE_CHARCODE) {
  357. MessageBeep((UINT)-1);
  358. } else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
  359. MessageBeep((UINT)-1);
  360. } else {
  361. dwConvMode = lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE;
  362. ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
  363. }
  364. } else if (PtInRect(&sImeG.rcSymbol, *lpptCursor)) {
  365. DWORD fdwConversion;
  366. if (lpIMC->fdwConversion & IME_CMODE_CHARCODE) {
  367. MessageBeep((UINT)-1);
  368. } else {
  369. fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SYMBOL;
  370. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  371. }
  372. } else if (PtInRect(&sImeG.rcSKText, *lpptCursor)) {
  373. DWORD fdwConversion;
  374. LPPRIVCONTEXT lpImcP;
  375. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  376. if(lpImcP) {
  377. if(!(lpImeL->hSKMenu)) {
  378. lpImeL->hSKMenu = LoadMenu (hInst, TEXT("SKMENU"));
  379. }
  380. lpImeL->dwSKState[lpImeL->dwSKWant] =
  381. lpImeL->dwSKState[lpImeL->dwSKWant]^1;
  382. fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SOFTKBD;
  383. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  384. ImmUnlockIMCC(lpIMC->hPrivate);
  385. } else {
  386. MessageBeep((UINT)-1);
  387. }
  388. } else {
  389. MessageBeep((UINT)-1);
  390. }
  391. ImmUnlockIMC(hIMC);
  392. return;
  393. }
  394. /**********************************************************************/
  395. /* StatusSetCursor() */
  396. /**********************************************************************/
  397. void PASCAL StatusSetCursor(
  398. HWND hStatusWnd,
  399. LPARAM lParam)
  400. {
  401. POINT ptCursor, ptSavCursor;
  402. RECT rcWnd;
  403. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  404. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  405. return;
  406. }
  407. GetCursorPos(&ptCursor);
  408. ptSavCursor = ptCursor;
  409. ScreenToClient(hStatusWnd, &ptCursor);
  410. if (PtInRect(&sImeG.rcStatusText, ptCursor)) {
  411. SetCursor(LoadCursor(hInst, szHandCursor));
  412. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  413. SetStatus(hStatusWnd, &ptCursor);
  414. } else if (HIWORD(lParam) == WM_RBUTTONUP) {
  415. if (PtInRect(&sImeG.rcSKText, ptCursor)) {
  416. static BOOL fSoftkey= FALSE;
  417. // prevent recursive
  418. if (fSoftkey) {
  419. // configuration already bring up
  420. return;
  421. }
  422. fSoftkey = TRUE;
  423. SoftkeyMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  424. fSoftkey = FALSE;
  425. }else{
  426. static BOOL fCmenu=FALSE;
  427. // prevent recursive
  428. if (fCmenu) {
  429. // configuration already bring up
  430. return;
  431. }
  432. fCmenu = TRUE;
  433. ContextMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  434. fCmenu = FALSE;
  435. }
  436. }
  437. return;
  438. } else {
  439. SetCursor(LoadCursor(NULL, IDC_SIZEALL));
  440. if (HIWORD(lParam) == WM_LBUTTONDOWN) {
  441. // start drag
  442. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  443. } else {
  444. return;
  445. }
  446. }
  447. SetCapture(hStatusWnd);
  448. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  449. MAKELONG(ptSavCursor.x, ptSavCursor.y));
  450. GetWindowRect(hStatusWnd, &rcWnd);
  451. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
  452. MAKELONG(ptSavCursor.x - rcWnd.left, ptSavCursor.y - rcWnd.top));
  453. DrawDragBorder(hStatusWnd, MAKELONG(ptSavCursor.x, ptSavCursor.y),
  454. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  455. return;
  456. }
  457. /**********************************************************************/
  458. /* PaintStatusWindow() */
  459. /**********************************************************************/
  460. void PASCAL PaintStatusWindow(
  461. HDC hDC,
  462. HWND hStatusWnd)
  463. {
  464. HWND hUIWnd;
  465. HIMC hIMC;
  466. LPINPUTCONTEXT lpIMC;
  467. LPPRIVCONTEXT lpImcP;
  468. HGDIOBJ hOldFont;
  469. HBITMAP hImeIconBmp, hShapeBmp, hSymbolBmp, hSKBmp;
  470. HBITMAP hOldBmp;
  471. HDC hMemDC;
  472. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  473. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  474. if (!hIMC) {
  475. MessageBeep((UINT)-1);
  476. return;
  477. }
  478. if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
  479. MessageBeep((UINT)-1);
  480. return;
  481. }
  482. // get lpImcP
  483. if(!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
  484. MessageBeep((UINT)-1);
  485. return;
  486. }
  487. #if defined(COMBO_IME)
  488. //in case the IME index has been changed and the ImeName size is different
  489. {
  490. POINTS ptPos;
  491. ptPos.x = (short)lpIMC->ptStatusWndPos.x;
  492. ptPos.y = (short)lpIMC->ptStatusWndPos.y;
  493. SetWindowPos(hStatusWnd, NULL,
  494. ptPos.x, ptPos.y,
  495. sImeG.xStatusWi, sImeG.yStatusHi,
  496. SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOZORDER);
  497. }
  498. #endif //COMBO_IME
  499. // set font
  500. if (sImeG.fDiffSysCharSet) {
  501. LOGFONT lfFont;
  502. ZeroMemory(&lfFont, sizeof(lfFont));
  503. hOldFont = GetCurrentObject(hDC, OBJ_FONT);
  504. lfFont.lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
  505. lfFont.lfCharSet = NATIVE_CHARSET;
  506. lstrcpy(lfFont.lfFaceName, TEXT("Simsun"));
  507. SelectObject(hDC, CreateFontIndirect(&lfFont));
  508. }
  509. // draw Ime Name
  510. if (lpIMC->fOpen) {
  511. SetTextColor(hDC, RGB(0x00, 0x00, 0x00));
  512. } else {
  513. SetTextColor(hDC, RGB(0x80, 0x80, 0x80));
  514. }
  515. SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
  516. DrawText(hDC, szImeName, lstrlen(szImeName),
  517. &sImeG.rcImeName, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  518. DrawConvexRect(hDC,
  519. sImeG.rcImeName.left,
  520. sImeG.rcImeName.top,
  521. sImeG.rcImeName.right - 1,
  522. sImeG.rcImeName.bottom - 1);
  523. DrawConvexRectP(hDC,
  524. sImeG.rcImeName.left,
  525. sImeG.rcImeName.top,
  526. sImeG.rcImeName.right,
  527. sImeG.rcImeName.bottom);
  528. // load all bitmap
  529. hSymbolBmp = (HBITMAP)NULL;
  530. hShapeBmp = (HBITMAP)NULL;
  531. hSKBmp = (HBITMAP)NULL;
  532. if (!lpIMC->fOpen) {
  533. hSymbolBmp = LoadBitmap(hInst, szNone);
  534. hShapeBmp = LoadBitmap(hInst, szNone);
  535. hSKBmp = LoadBitmap(hInst, szNone);
  536. hImeIconBmp = LoadBitmap(hInst, szChinese);
  537. } else if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
  538. hImeIconBmp = LoadBitmap(hInst, szChinese);
  539. } else {
  540. hImeIconBmp = LoadBitmap(hInst, szEnglish);
  541. }
  542. if (!hShapeBmp) {
  543. if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
  544. hShapeBmp = LoadBitmap(hInst, szFullShape);
  545. } else {
  546. hShapeBmp = LoadBitmap(hInst, szHalfShape);
  547. }
  548. }
  549. if (!hSymbolBmp) {
  550. if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
  551. hSymbolBmp = LoadBitmap(hInst, szSymbol);
  552. } else {
  553. hSymbolBmp = LoadBitmap(hInst, szNoSymbol);
  554. }
  555. }
  556. if (!hSKBmp) {
  557. if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
  558. hSKBmp = LoadBitmap(hInst, szSoftKBD);
  559. } else {
  560. hSKBmp = LoadBitmap(hInst, szNoSoftKBD);
  561. }
  562. }
  563. ImmUnlockIMC(hIMC);
  564. ImmUnlockIMCC(lpIMC->hPrivate);
  565. hMemDC = CreateCompatibleDC(hDC);
  566. hOldBmp = SelectObject(hMemDC, hImeIconBmp);
  567. BitBlt(hDC, sImeG.rcImeIcon.left, sImeG.rcImeIcon.top,
  568. sImeG.rcImeIcon.right - sImeG.rcImeIcon.left,
  569. STATUS_DIM_Y,
  570. hMemDC, 0, 0, SRCCOPY);
  571. SelectObject(hMemDC, hShapeBmp);
  572. BitBlt(hDC, sImeG.rcShapeText.left, sImeG.rcShapeText.top,
  573. sImeG.rcShapeText.right - sImeG.rcShapeText.left,
  574. STATUS_DIM_Y,
  575. hMemDC, 0, 0, SRCCOPY);
  576. SelectObject(hMemDC, hSymbolBmp);
  577. BitBlt(hDC, sImeG.rcSymbol.left, sImeG.rcSymbol.top,
  578. sImeG.rcSymbol.right - sImeG.rcSymbol.left,
  579. STATUS_DIM_Y,
  580. hMemDC, 0, 0, SRCCOPY);
  581. SelectObject(hMemDC, hSKBmp);
  582. BitBlt(hDC, sImeG.rcSKText.left, sImeG.rcSKText.top,
  583. sImeG.xStatusWi - sImeG.rcSKText.left,
  584. STATUS_DIM_Y,
  585. hMemDC, 0, 0, SRCCOPY);
  586. SelectObject(hMemDC, hOldBmp);
  587. DeleteDC(hMemDC);
  588. DeleteObject(hImeIconBmp);
  589. DeleteObject(hSymbolBmp);
  590. DeleteObject(hShapeBmp);
  591. DeleteObject(hSKBmp);
  592. if (sImeG.fDiffSysCharSet) {
  593. DeleteObject(SelectObject(hDC, hOldFont));
  594. }
  595. return;
  596. }
  597. /**********************************************************************/
  598. /* StatusWndProc() */
  599. /**********************************************************************/
  600. LRESULT CALLBACK StatusWndProc(
  601. HWND hStatusWnd,
  602. UINT uMsg,
  603. WPARAM wParam,
  604. LPARAM lParam)
  605. {
  606. switch (uMsg) {
  607. case WM_DESTROY:
  608. DestroyStatusWindow(hStatusWnd);
  609. break;
  610. case WM_SETCURSOR:
  611. StatusSetCursor(hStatusWnd, lParam);
  612. break;
  613. case WM_MOUSEMOVE:
  614. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  615. POINT ptCursor;
  616. DrawDragBorder(hStatusWnd,
  617. GetWindowLong(hStatusWnd, UI_MOVE_XY),
  618. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  619. GetCursorPos(&ptCursor);
  620. SetWindowLong(hStatusWnd, UI_MOVE_XY,
  621. MAKELONG(ptCursor.x, ptCursor.y));
  622. DrawDragBorder(hStatusWnd, MAKELONG(ptCursor.x, ptCursor.y),
  623. GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  624. } else {
  625. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  626. }
  627. break;
  628. case WM_LBUTTONUP:
  629. if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
  630. LONG lTmpCursor, lTmpOffset;
  631. lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
  632. // calculate the org by the offset
  633. lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  634. DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
  635. (*(LPPOINTS)&lTmpCursor).x -= (*(LPPOINTS)&lTmpOffset).x;
  636. (*(LPPOINTS)&lTmpCursor).y -= (*(LPPOINTS)&lTmpOffset).y;
  637. SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  638. ReleaseCapture();
  639. AdjustStatusBoundary((LPPOINTS)&lTmpCursor,
  640. GetWindow(hStatusWnd, GW_OWNER));
  641. SendMessage(GetWindow(hStatusWnd, GW_OWNER), WM_IME_CONTROL,
  642. IMC_SETSTATUSWINDOWPOS, lTmpCursor);
  643. } else {
  644. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  645. }
  646. break;
  647. case WM_IME_NOTIFY:
  648. // get work area for changing
  649. SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
  650. if (wParam == IMN_SETSTATUSWINDOWPOS) {
  651. SetStatusWindowPos(hStatusWnd);
  652. }
  653. break;
  654. case WM_PAINT:
  655. {
  656. HDC hDC;
  657. PAINTSTRUCT ps;
  658. hDC = BeginPaint(hStatusWnd, &ps);
  659. PaintStatusWindow(hDC, hStatusWnd);
  660. EndPaint(hStatusWnd, &ps);
  661. }
  662. break;
  663. case WM_MOUSEACTIVATE:
  664. return (MA_NOACTIVATE);
  665. default:
  666. return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  667. }
  668. return (0L);
  669. }
  670. /**********************************************************************/
  671. /* ImeVerDlgProc() */
  672. /* Return Value: */
  673. /* TRUE - successful, FALSE - failure */
  674. /**********************************************************************/
  675. INT_PTR CALLBACK ImeVerDlgProc( // dialog procedure of configuration
  676. HWND hDlg,
  677. UINT uMessage,
  678. WPARAM wParam,
  679. LPARAM lParam)
  680. {
  681. RECT rc;
  682. LONG DlgWidth, DlgHeight;
  683. switch (uMessage) {
  684. case WM_INITDIALOG:
  685. hCrtDlg = hDlg;
  686. // reset position
  687. GetWindowRect(hDlg, &rc);
  688. DlgWidth = rc.right - rc.left;
  689. DlgHeight = rc.bottom - rc.top;
  690. SetWindowPos(hDlg, HWND_TOP,
  691. (int)(sImeG.rcWorkArea.right - DlgWidth)/2,
  692. (int)(sImeG.rcWorkArea.bottom - DlgHeight)/2,
  693. (int)0, (int)0, SWP_NOSIZE);
  694. return (TRUE); // don't want to set focus to special control
  695. case WM_COMMAND:
  696. switch (wParam) {
  697. case IDOK:
  698. EndDialog(hDlg, FALSE);
  699. break;
  700. case IDCANCEL:
  701. EndDialog(hDlg, FALSE);
  702. break;
  703. default:
  704. return (FALSE);
  705. break;
  706. }
  707. return (TRUE);
  708. case WM_CLOSE:
  709. EndDialog(hDlg, FALSE);
  710. return FALSE;
  711. case WM_PAINT:
  712. {
  713. GetClientRect(hDlg, &rc);
  714. DrawConvexRect(GetDC(hDlg),
  715. rc.left + 10,
  716. rc.top + 10,
  717. rc.right - 10 - 1,
  718. rc.bottom - 43 - 1);
  719. DrawConvexRectP(GetDC(hDlg),
  720. rc.left + 10,
  721. rc.top + 10,
  722. rc.right - 10,
  723. rc.bottom - 43);
  724. }
  725. return (FALSE);
  726. default:
  727. return (FALSE);
  728. }
  729. return (TRUE);
  730. }