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.

791 lines
23 KiB

  1. /*++
  2. Copyright (c) 1995-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. UISUBS.c
  5. ++*/
  6. #include <windows.h>
  7. #include <htmlhelp.h>
  8. #include <immdev.h>
  9. #include <imedefs.h>
  10. /**********************************************************************/
  11. /* DrawDragBorder() */
  12. /**********************************************************************/
  13. void PASCAL DrawDragBorder(
  14. HWND hWnd, // window of IME is dragged
  15. LONG lCursorPos, // the cursor position
  16. LONG lCursorOffset) // the offset form cursor to window org
  17. {
  18. HDC hDC;
  19. int cxBorder, cyBorder;
  20. int x, y;
  21. RECT rcWnd;
  22. cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
  23. cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
  24. // get cursor position
  25. x = (*(LPPOINTS)&lCursorPos).x;
  26. y = (*(LPPOINTS)&lCursorPos).y;
  27. // calculate the org by the offset
  28. x -= (*(LPPOINTS)&lCursorOffset).x;
  29. y -= (*(LPPOINTS)&lCursorOffset).y;
  30. #if 0 // MultiMonitor support
  31. // check for the min boundary of the display
  32. if (x < sImeG.rcWorkArea.left) {
  33. x = sImeG.rcWorkArea.left;
  34. }
  35. if (y < sImeG.rcWorkArea.top) {
  36. y = sImeG.rcWorkArea.top;
  37. }
  38. #endif
  39. // check for the max boundary of the display
  40. GetWindowRect(hWnd, &rcWnd);
  41. #if 0 // MultiMonitor support
  42. if (x + rcWnd.right - rcWnd.left > sImeG.rcWorkArea.right) {
  43. x = sImeG.rcWorkArea.right - (rcWnd.right - rcWnd.left);
  44. }
  45. if (y + rcWnd.bottom - rcWnd.top > sImeG.rcWorkArea.bottom) {
  46. y = sImeG.rcWorkArea.bottom - (rcWnd.bottom - rcWnd.top);
  47. }
  48. #endif
  49. // draw the moving track
  50. hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  51. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  52. // ->
  53. PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
  54. PATINVERT);
  55. // v
  56. PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
  57. cyBorder, PATINVERT);
  58. // _>
  59. PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
  60. rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
  61. // v
  62. PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
  63. - cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
  64. DeleteDC(hDC);
  65. return;
  66. }
  67. /**********************************************************************/
  68. /* DrawFrameBorder() */
  69. /**********************************************************************/
  70. void PASCAL DrawFrameBorder( // border of IME
  71. HDC hDC,
  72. HWND hWnd) // window of IME
  73. {
  74. RECT rcWnd;
  75. int xWi, yHi;
  76. GetWindowRect(hWnd, &rcWnd);
  77. xWi = rcWnd.right - rcWnd.left;
  78. yHi = rcWnd.bottom - rcWnd.top;
  79. // 1, ->
  80. PatBlt(hDC, 0, 0, xWi, 1, WHITENESS);
  81. // 1, v
  82. PatBlt(hDC, 0, 0, 1, yHi, WHITENESS);
  83. // 1, _>
  84. PatBlt(hDC, 0, yHi, xWi, -1, BLACKNESS);
  85. // 1, v
  86. PatBlt(hDC, xWi, 0, -1, yHi, BLACKNESS);
  87. xWi -= 2;
  88. yHi -= 2;
  89. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  90. // 2, ->
  91. PatBlt(hDC, 1, 1, xWi, 1, PATCOPY);
  92. // 2, v
  93. PatBlt(hDC, 1, 1, 1, yHi, PATCOPY);
  94. // 2, v
  95. PatBlt(hDC, xWi + 1, 1, -1, yHi, PATCOPY);
  96. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  97. // 2, _>
  98. PatBlt(hDC, 1, yHi + 1, xWi, -1, PATCOPY);
  99. xWi -= 2;
  100. yHi -= 2;
  101. // 3, ->
  102. PatBlt(hDC, 2, 2, xWi, 1, PATCOPY);
  103. // 3, v
  104. PatBlt(hDC, 2, 2, 1, yHi, PATCOPY);
  105. // 3, v
  106. PatBlt(hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
  107. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  108. // 3, _>
  109. PatBlt(hDC, 2, yHi + 2, xWi, -1, PATCOPY);
  110. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  111. xWi -= 2;
  112. yHi -= 2;
  113. // 4, ->
  114. PatBlt(hDC, 3, 3, xWi, 1, PATCOPY);
  115. // 4, v
  116. PatBlt(hDC, 3, 3, 1, yHi, PATCOPY);
  117. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  118. // 4, v
  119. PatBlt(hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
  120. // 4, _>
  121. PatBlt(hDC, 3, yHi + 3, xWi, -1, WHITENESS);
  122. return;
  123. }
  124. /**********************************************************************/
  125. /* ContextMenuWndProc() */
  126. /**********************************************************************/
  127. LRESULT CALLBACK ContextMenuWndProc(
  128. HWND hCMenuWnd,
  129. UINT uMsg,
  130. WPARAM wParam,
  131. LPARAM lParam)
  132. {
  133. switch (uMsg) {
  134. case WM_DESTROY:
  135. {
  136. HWND hUIWnd;
  137. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  138. if (hUIWnd) {
  139. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
  140. IMN_PRIVATE_CMENUDESTROYED);
  141. }
  142. }
  143. break;
  144. case WM_USER_DESTROY:
  145. {
  146. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  147. DestroyWindow(hCMenuWnd);
  148. }
  149. break;
  150. case WM_COMMAND:
  151. switch(LOWORD(wParam)) {
  152. case IDM_SET:
  153. {
  154. HIMC hIMC;
  155. LPINPUTCONTEXT lpIMC;
  156. LPPRIVCONTEXT lpImcP;
  157. int UI_MODE;
  158. HWND hUIWnd;
  159. RECT rcWorkArea;
  160. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  161. #if 1 // MultiMonitor support
  162. rcWorkArea = ImeMonitorWorkAreaFromWindow(hCMenuWnd);
  163. #endif
  164. if (!hUIWnd) {
  165. return (0L);
  166. }
  167. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  168. if (!hIMC) {
  169. return (0L);
  170. }
  171. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  172. if (!lpIMC) {
  173. return (0L);
  174. }
  175. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  176. if (!lpImcP) {
  177. return (0L);
  178. }
  179. ImeConfigure(GetKeyboardLayout(0), lpIMC->hWnd, IME_CONFIG_GENERAL, NULL);
  180. #ifdef CROSSREF
  181. {
  182. HWND hCompWnd;
  183. hCompWnd = GetCompWnd(hUIWnd);
  184. DestroyWindow(hCompWnd);
  185. }
  186. #endif
  187. lpImcP->iImeState = CST_INIT;
  188. CompCancel(hIMC, lpIMC);
  189. // change compwnd size
  190. // init fields of hIMC
  191. lpIMC->fOpen = TRUE;
  192. if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
  193. lpIMC->fdwConversion = IME_CMODE_NATIVE;
  194. lpIMC->fdwInit |= INIT_CONVERSION;
  195. }
  196. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg | MSG_IMN_DESTROYCAND;
  197. GenerateMessage(hIMC, lpIMC, lpImcP);
  198. // set cand window data
  199. if(MBIndex.IMEChara[0].IC_Trace) {
  200. UI_MODE = BOX_UI;
  201. } else {
  202. POINT ptSTFixPos;
  203. UI_MODE = LIN_UI;
  204. ptSTFixPos.x = 0;
  205. ptSTFixPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
  206. ImmSetStatusWindowPos(hIMC, (LPPOINT)&ptSTFixPos);
  207. }
  208. InitCandUIData(
  209. GetSystemMetrics(SM_CXBORDER),
  210. GetSystemMetrics(SM_CYBORDER), UI_MODE);
  211. ImmUnlockIMCC(lpIMC->hPrivate);
  212. ImmUnlockIMC(hIMC);
  213. break;
  214. }
  215. case IDM_CRTWORD:
  216. {
  217. HIMC hIMC;
  218. LPINPUTCONTEXT lpIMC;
  219. HWND hUIWnd;
  220. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  221. if (!hUIWnd) {
  222. return (0L);
  223. }
  224. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  225. if(!hIMC){
  226. break;
  227. }
  228. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  229. if (!lpIMC) {
  230. break;
  231. }
  232. DialogBox(hInst, TEXT("CREATEWORD"), (HWND)lpIMC->hWnd, CrtWordDlgProc);
  233. ImmUnlockIMC(hIMC);
  234. break;
  235. }
  236. case IDM_OPTGUD:
  237. {
  238. TCHAR szOPTGUDHlpName[MAX_PATH];
  239. szOPTGUDHlpName[0] = 0;
  240. if (GetWindowsDirectory((LPTSTR)szOPTGUDHlpName, MAX_PATH))
  241. {
  242. StringCchCat((LPTSTR)szOPTGUDHlpName, ARRAYSIZE(szOPTGUDHlpName), TEXT("\\HELP\\WINIME.CHM"));
  243. HtmlHelp(hCMenuWnd,szOPTGUDHlpName,HH_DISPLAY_TOPIC,0L);
  244. }
  245. }
  246. break;
  247. case IDM_IMEGUD:
  248. {
  249. TCHAR szIMEGUDHlpName[MAX_PATH];
  250. int iLen;
  251. szIMEGUDHlpName[0] = 0;
  252. if(GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAX_PATH))
  253. {
  254. StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT("\\HELP\\"));
  255. StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), (LPTSTR)szImeMBFileName);
  256. iLen = lstrlen(szIMEGUDHlpName);
  257. szIMEGUDHlpName[iLen-3] = 0;
  258. StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT(".CHM"));
  259. HtmlHelp(hCMenuWnd,szIMEGUDHlpName,HH_DISPLAY_TOPIC,0L);
  260. }
  261. }
  262. break;
  263. case IDM_VER:
  264. {
  265. HIMC hIMC;
  266. LPINPUTCONTEXT lpIMC;
  267. HWND hUIWnd;
  268. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  269. if (!hUIWnd) {
  270. return (0L);
  271. }
  272. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  273. if (!hIMC) { // Oh! Oh!
  274. return (0L);
  275. }
  276. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  277. if (!lpIMC) { // Oh! Oh!
  278. return (0L);
  279. }
  280. DialogBox(hInst, TEXT("IMEVER"), (HWND)lpIMC->hWnd, ImeVerDlgProc);
  281. ImmUnlockIMC(hIMC);
  282. break;
  283. }
  284. }
  285. break;
  286. case WM_CLOSE:
  287. {
  288. HMENU hMenu;
  289. GetMenu(hCMenuWnd);
  290. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  291. if (hMenu) {
  292. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  293. DestroyMenu(hMenu);
  294. }
  295. }
  296. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  297. default:
  298. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  299. }
  300. return (0L);
  301. }
  302. /**********************************************************************/
  303. /* SoftkeyMenuWndProc() */
  304. /**********************************************************************/
  305. LRESULT CALLBACK SoftkeyMenuWndProc(
  306. HWND hKeyMenuWnd,
  307. UINT uMsg,
  308. WPARAM wParam,
  309. LPARAM lParam)
  310. {
  311. switch (uMsg) {
  312. case WM_DESTROY:
  313. {
  314. HWND hUIWnd;
  315. hUIWnd = (HWND)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
  316. if (hUIWnd) {
  317. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
  318. IMN_PRIVATE_SOFTKEYMENUDESTROYED);
  319. }
  320. }
  321. break;
  322. case WM_USER_DESTROY:
  323. {
  324. SendMessage(hKeyMenuWnd, WM_CLOSE, 0, 0);
  325. DestroyWindow(hKeyMenuWnd);
  326. }
  327. break;
  328. case WM_COMMAND:
  329. switch(LOWORD(wParam)) {
  330. case IDM_SKL1:
  331. case IDM_SKL2:
  332. case IDM_SKL3:
  333. case IDM_SKL4:
  334. case IDM_SKL5:
  335. case IDM_SKL6:
  336. case IDM_SKL7:
  337. case IDM_SKL8:
  338. case IDM_SKL9:
  339. case IDM_SKL10:
  340. case IDM_SKL11:
  341. case IDM_SKL12:
  342. case IDM_SKL13:
  343. {
  344. HIMC hIMC;
  345. LPINPUTCONTEXT lpIMC;
  346. LPPRIVCONTEXT lpImcP;
  347. DWORD fdwConversion;
  348. HWND hUIWnd;
  349. hUIWnd = (HWND)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
  350. if (!hUIWnd) {
  351. return (0L);
  352. }
  353. hIMC = (HIMC)GetWindowLongPtr(hUIWnd,IMMGWLP_IMC);
  354. if (!hIMC) { // Oh! Oh!
  355. return (0L);
  356. }
  357. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  358. if (!lpIMC) { // Oh! Oh!
  359. return (0L);
  360. }
  361. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  362. if (!lpImcP) {
  363. return (0L);
  364. }
  365. {
  366. UINT i;
  367. lpImeL->dwSKWant = LOWORD(wParam) - IDM_SKL1;
  368. lpImeL->dwSKState[lpImeL->dwSKWant] =
  369. lpImeL->dwSKState[lpImeL->dwSKWant]^1;
  370. // clear other SK State
  371. for(i=0; i<NumsSK; i++) {
  372. if(i == lpImeL->dwSKWant) continue;
  373. lpImeL->dwSKState[i] = 0;
  374. }
  375. if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
  376. if(LOWORD(wParam) == IDM_SKL1)
  377. lpImcP->iImeState = CST_INIT;
  378. else
  379. lpImcP->iImeState = CST_SOFTKB;
  380. fdwConversion = lpIMC->fdwConversion | IME_CMODE_SOFTKBD;
  381. } else {
  382. lpImcP->iImeState = CST_INIT;
  383. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_SOFTKBD);
  384. }
  385. }
  386. ImmSetConversionStatus(hIMC, (fdwConversion & ~(IME_CMODE_SOFTKBD)),
  387. lpIMC->fdwSentence);
  388. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  389. ImmUnlockIMCC(lpIMC->hPrivate);
  390. ImmUnlockIMC(hIMC);
  391. break;
  392. }
  393. }
  394. break;
  395. case WM_CLOSE:
  396. {
  397. HMENU hMenu;
  398. GetMenu(hKeyMenuWnd);
  399. hMenu = (HMENU)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_MENU);
  400. if (hMenu) {
  401. SetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)NULL);
  402. DestroyMenu(hMenu);
  403. }
  404. }
  405. return DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
  406. default:
  407. return DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
  408. }
  409. return (0L);
  410. }
  411. /**********************************************************************/
  412. /* ContextMenu() */
  413. /**********************************************************************/
  414. void PASCAL ContextMenu(
  415. HWND hStatusWnd,
  416. int x,
  417. int y)
  418. {
  419. HWND hUIWnd;
  420. HWND hCMenuWnd;
  421. HGLOBAL hUIPrivate;
  422. LPUIPRIV lpUIPrivate;
  423. HIMC hIMC;
  424. LPINPUTCONTEXT lpIMC;
  425. HMENU hMenu, hCMenu;
  426. RECT rcStatusWnd;
  427. RECT rcWorkArea;
  428. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  429. if(!hUIWnd){
  430. return;
  431. }
  432. GetWindowRect(hStatusWnd, &rcStatusWnd);
  433. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  434. if (!hIMC) {
  435. return;
  436. }
  437. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  438. if (!lpIMC) {
  439. return;
  440. }
  441. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  442. if (!hUIPrivate) {
  443. goto ContextMenuUnlockIMC;
  444. }
  445. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  446. if (!lpUIPrivate) {
  447. goto ContextMenuUnlockIMC;
  448. }
  449. #if 1 // MultiMonitor support
  450. rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
  451. #endif
  452. if (lpUIPrivate->hCMenuWnd) {
  453. SetWindowPos(lpUIPrivate->hCMenuWnd, NULL,
  454. rcWorkArea.left, rcWorkArea.top, 0, 0,
  455. SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
  456. } else {
  457. // this is important to assign owner window, otherwise the focus
  458. // will be gone
  459. // When UI terminate, it need to destroy this window
  460. lpUIPrivate->hCMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
  461. szCMenuClassName, TEXT("Context Menu"),
  462. WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
  463. lpIMC->hWnd, (HMENU)NULL, hInst, NULL);
  464. }
  465. hCMenuWnd = lpUIPrivate->hCMenuWnd;
  466. // Unlock before we call into TrackPopupMenu().
  467. GlobalUnlock(hUIPrivate);
  468. if (!hCMenuWnd) {
  469. goto ContextMenuUnlockIMC;
  470. }
  471. hMenu = LoadMenu(hInst, TEXT("PROPMENU"));
  472. hCMenu = GetSubMenu(hMenu, 0);
  473. if ( lpImeL->fWinLogon == TRUE )
  474. {
  475. // In Logon Mode, we don't want to show help and configuration dialog
  476. EnableMenuItem(hCMenu, 0, MF_BYPOSITION | MF_GRAYED );
  477. EnableMenuItem(hCMenu, IDM_CRTWORD, MF_BYCOMMAND | MF_GRAYED);
  478. EnableMenuItem(hCMenu, IDM_SET, MF_BYCOMMAND | MF_GRAYED);
  479. }
  480. SetWindowLongPtr(hCMenuWnd, CMENU_HUIWND, (LONG_PTR)hUIWnd);
  481. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)hMenu);
  482. TrackPopupMenu (hCMenu, TPM_LEFTBUTTON,
  483. rcStatusWnd.left, rcStatusWnd.top, 0, hCMenuWnd, NULL);
  484. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  485. if (hMenu) {
  486. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  487. DestroyMenu(hMenu);
  488. }
  489. ContextMenuUnlockIMC:
  490. ImmUnlockIMC(hIMC);
  491. return;
  492. }
  493. /**********************************************************************/
  494. /* SoftkeyMenu() */
  495. /**********************************************************************/
  496. void PASCAL SoftkeyMenu(
  497. HWND hStatusWnd,
  498. int x,
  499. int y)
  500. {
  501. HWND hUIWnd;
  502. HWND hSoftkeyMenuWnd;
  503. HGLOBAL hUIPrivate;
  504. LPUIPRIV lpUIPrivate;
  505. HIMC hIMC;
  506. LPINPUTCONTEXT lpIMC;
  507. HMENU hMenu, hKeyMenu;
  508. RECT rcStatusWnd;
  509. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  510. if(!hUIWnd){
  511. return;
  512. }
  513. GetWindowRect(hStatusWnd, &rcStatusWnd);
  514. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  515. if (!hIMC) {
  516. return;
  517. }
  518. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  519. if (!lpIMC) {
  520. return;
  521. }
  522. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  523. if (!hUIPrivate) {
  524. goto KeyMenuUnlockIMC;
  525. }
  526. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  527. if (!lpUIPrivate) {
  528. goto KeyMenuUnlockIMC;
  529. }
  530. if (!lpUIPrivate->hSoftkeyMenuWnd) {
  531. // this is important to assign owner window, otherwise the focus
  532. // will be gone
  533. // When UI terminate, it need to destroy this window
  534. lpUIPrivate->hSoftkeyMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
  535. szSoftkeyMenuClassName, TEXT("Softkey Menu"),
  536. WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
  537. lpIMC->hWnd, (HMENU)NULL, hInst, NULL);
  538. }
  539. hSoftkeyMenuWnd = lpUIPrivate->hSoftkeyMenuWnd;
  540. // Unlock before we call into TrackPopupMenu().
  541. GlobalUnlock(hUIPrivate);
  542. if (!hSoftkeyMenuWnd) {
  543. goto KeyMenuUnlockIMC;
  544. }
  545. hMenu = LoadMenu(hInst, TEXT("SKMENU"));
  546. hKeyMenu = GetSubMenu(hMenu, 0);
  547. SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_HUIWND, (LONG_PTR)hUIWnd);
  548. SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)hMenu);
  549. if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
  550. CheckMenuItem(hMenu,lpImeL->dwSKWant + IDM_SKL1, MF_CHECKED);
  551. }
  552. TrackPopupMenu (hKeyMenu, TPM_LEFTBUTTON,
  553. rcStatusWnd.left, rcStatusWnd.top, 0, hSoftkeyMenuWnd, NULL);
  554. hMenu = (HMENU)GetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU);
  555. if (hMenu) {
  556. SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)NULL);
  557. DestroyMenu(hMenu);
  558. }
  559. KeyMenuUnlockIMC:
  560. ImmUnlockIMC(hIMC);
  561. return;
  562. }
  563. #if 1 // MultiMonitor support
  564. /**********************************************************************/
  565. /* ImeMonitorWorkAreaFromWindow() */
  566. /**********************************************************************/
  567. RECT PASCAL ImeMonitorWorkAreaFromWindow(
  568. HWND hAppWnd)
  569. {
  570. HMONITOR hMonitor;
  571. hMonitor = MonitorFromWindow(hAppWnd, MONITOR_DEFAULTTONEAREST);
  572. if (hMonitor) {
  573. MONITORINFO sMonitorInfo;
  574. sMonitorInfo.cbSize = sizeof(sMonitorInfo);
  575. // init a default value to avoid GetMonitorInfo fails
  576. sMonitorInfo.rcWork = sImeG.rcWorkArea;
  577. #ifdef UNICODE
  578. GetMonitorInfoW(hMonitor, &sMonitorInfo);
  579. #else
  580. GetMonitorInfoA(hMonitor, &sMonitorInfo);
  581. #endif
  582. return sMonitorInfo.rcWork;
  583. } else {
  584. return sImeG.rcWorkArea;
  585. }
  586. }
  587. /**********************************************************************/
  588. /* ImeMonitorWorkAreaFromPoint() */
  589. /**********************************************************************/
  590. RECT PASCAL ImeMonitorWorkAreaFromPoint(
  591. POINT ptPoint)
  592. {
  593. HMONITOR hMonitor;
  594. hMonitor = MonitorFromPoint(ptPoint, MONITOR_DEFAULTTONEAREST);
  595. if (hMonitor) {
  596. MONITORINFO sMonitorInfo;
  597. sMonitorInfo.cbSize = sizeof(sMonitorInfo);
  598. // init a default value to avoid GetMonitorInfo fails
  599. sMonitorInfo.rcWork = sImeG.rcWorkArea;
  600. #ifdef UNICODE
  601. GetMonitorInfoW(hMonitor, &sMonitorInfo);
  602. #else
  603. GetMonitorInfoA(hMonitor, &sMonitorInfo);
  604. #endif
  605. return sMonitorInfo.rcWork;
  606. } else {
  607. return sImeG.rcWorkArea;
  608. }
  609. }
  610. /**********************************************************************/
  611. /* ImeMonitorWorkAreaFromRect() */
  612. /**********************************************************************/
  613. RECT PASCAL ImeMonitorWorkAreaFromRect(
  614. LPRECT lprcRect)
  615. {
  616. HMONITOR hMonitor;
  617. hMonitor = MonitorFromRect(lprcRect, MONITOR_DEFAULTTONEAREST);
  618. if (hMonitor) {
  619. MONITORINFO sMonitorInfo;
  620. sMonitorInfo.cbSize = sizeof(sMonitorInfo);
  621. // init a default value to avoid GetMonitorInfo fails
  622. sMonitorInfo.rcWork = sImeG.rcWorkArea;
  623. #ifdef UNICODE
  624. GetMonitorInfoW(hMonitor, &sMonitorInfo);
  625. #else
  626. GetMonitorInfoA(hMonitor, &sMonitorInfo);
  627. #endif
  628. return sMonitorInfo.rcWork;
  629. } else {
  630. return sImeG.rcWorkArea;
  631. }
  632. }
  633. #endif