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.

715 lines
20 KiB

  1. /*++
  2. Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
  3. Module Name:
  4. uisubs.c
  5. ++*/
  6. #include <windows.h>
  7. #include <immdev.h>
  8. #include <htmlhelp.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. #ifndef MUL_MONITOR
  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. #ifndef MUL_MONITOR
  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. if ( hDC )
  52. {
  53. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  54. // ->
  55. PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
  56. PATINVERT);
  57. // v
  58. PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
  59. cyBorder, PATINVERT);
  60. // _>
  61. PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
  62. rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
  63. // v
  64. PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
  65. - cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
  66. DeleteDC(hDC);
  67. }
  68. return;
  69. }
  70. /**********************************************************************/
  71. /* DrawFrameBorder() */
  72. /**********************************************************************/
  73. void PASCAL DrawFrameBorder( // border of IME
  74. HDC hDC,
  75. HWND hWnd) // window of IME
  76. {
  77. RECT rcWnd;
  78. int xWi, yHi;
  79. GetWindowRect(hWnd, &rcWnd);
  80. xWi = rcWnd.right - rcWnd.left;
  81. yHi = rcWnd.bottom - rcWnd.top;
  82. // 1, ->
  83. PatBlt(hDC, 0, 0, xWi, 1, WHITENESS);
  84. // 1, v
  85. PatBlt(hDC, 0, 0, 1, yHi, WHITENESS);
  86. // 1, _>
  87. PatBlt(hDC, 0, yHi, xWi, -1, BLACKNESS);
  88. // 1, v
  89. PatBlt(hDC, xWi, 0, -1, yHi, BLACKNESS);
  90. xWi -= 2;
  91. yHi -= 2;
  92. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  93. // 2, ->
  94. PatBlt(hDC, 1, 1, xWi, 1, PATCOPY);
  95. // 2, v
  96. PatBlt(hDC, 1, 1, 1, yHi, PATCOPY);
  97. // 2, v
  98. PatBlt(hDC, xWi + 1, 1, -1, yHi, PATCOPY);
  99. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  100. // 2, _>
  101. PatBlt(hDC, 1, yHi + 1, xWi, -1, PATCOPY);
  102. xWi -= 2;
  103. yHi -= 2;
  104. // 3, ->
  105. PatBlt(hDC, 2, 2, xWi, 1, PATCOPY);
  106. // 3, v
  107. PatBlt(hDC, 2, 2, 1, yHi, PATCOPY);
  108. // 3, v
  109. PatBlt(hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
  110. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  111. // 3, _>
  112. PatBlt(hDC, 2, yHi + 2, xWi, -1, PATCOPY);
  113. SelectObject(hDC, GetStockObject(GRAY_BRUSH));
  114. xWi -= 2;
  115. yHi -= 2;
  116. // 4, ->
  117. PatBlt(hDC, 3, 3, xWi, 1, PATCOPY);
  118. // 4, v
  119. PatBlt(hDC, 3, 3, 1, yHi, PATCOPY);
  120. SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
  121. // 4, v
  122. PatBlt(hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
  123. // 4, _>
  124. PatBlt(hDC, 3, yHi + 3, xWi, -1, WHITENESS);
  125. return;
  126. }
  127. /**********************************************************************/
  128. /* ContextMenuWndProc() */
  129. /**********************************************************************/
  130. LRESULT CALLBACK ContextMenuWndProc(
  131. HWND hCMenuWnd,
  132. UINT uMsg,
  133. WPARAM wParam,
  134. LPARAM lParam)
  135. {
  136. HRESULT hr;
  137. switch (uMsg) {
  138. case WM_DESTROY:
  139. {
  140. HWND hUIWnd;
  141. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  142. if (hUIWnd) {
  143. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
  144. IMN_PRIVATE_CMENUDESTROYED);
  145. }
  146. }
  147. break;
  148. case WM_USER_DESTROY:
  149. {
  150. SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
  151. DestroyWindow(hCMenuWnd);
  152. }
  153. break;
  154. case WM_COMMAND:
  155. switch(LOWORD(wParam)) {
  156. case IDM_PROP:
  157. {
  158. HIMC hIMC;
  159. LPINPUTCONTEXT lpIMC;
  160. LPPRIVCONTEXT lpImcP;
  161. int UI_MODE;
  162. HWND hUIWnd;
  163. RECT rcWorkArea;
  164. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  165. if (!hUIWnd) {
  166. return (0L);
  167. }
  168. #ifdef MUL_MONITOR
  169. rcWorkArea = ImeMonitorWorkAreaFromWindow(hCMenuWnd);
  170. #else
  171. rcWorkArea = sImeG.rcWorkArea;
  172. #endif
  173. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  174. if (!hIMC) {
  175. return (0L);
  176. }
  177. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  178. if (!lpIMC) {
  179. return (0L);
  180. }
  181. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  182. if (!lpImcP) {
  183. return (0L);
  184. }
  185. ImeConfigure(GetKeyboardLayout(0), lpIMC->hWnd, IME_CONFIG_GENERAL, NULL);
  186. #ifdef CROSSREF
  187. {
  188. HWND hCompWnd;
  189. hCompWnd = GetCompWnd(hUIWnd);
  190. DestroyWindow(hCompWnd);
  191. }
  192. #endif
  193. lpImcP->iImeState = CST_INIT;
  194. CompCancel(hIMC, lpIMC);
  195. // change compwnd size
  196. // init fields of hIMC
  197. lpIMC->fOpen = TRUE;
  198. if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
  199. lpIMC->fdwConversion = IME_CMODE_NATIVE;
  200. lpIMC->fdwInit |= INIT_CONVERSION;
  201. }
  202. lpImcP->fdwImeMsg = lpImcP->fdwImeMsg | MSG_IMN_DESTROYCAND;
  203. GenerateMessage(hIMC, lpIMC, lpImcP);
  204. // set cand window data
  205. if(sImeG.IC_Trace) {
  206. UI_MODE = BOX_UI;
  207. } else {
  208. POINT ptSTFixPos;
  209. UI_MODE = LIN_UI;
  210. ptSTFixPos.x = 0;
  211. ptSTFixPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
  212. ImmSetStatusWindowPos(hIMC, (LPPOINT)&ptSTFixPos);
  213. }
  214. InitCandUIData(
  215. GetSystemMetrics(SM_CXBORDER),
  216. GetSystemMetrics(SM_CYBORDER), UI_MODE);
  217. ImmUnlockIMCC(lpIMC->hPrivate);
  218. ImmUnlockIMC(hIMC);
  219. break;
  220. }
  221. //case IDM_HLP:
  222. case IDM_OPTGUD:
  223. {
  224. TCHAR szOPTGUDHlpName[MAX_PATH];
  225. szOPTGUDHlpName[0] = 0;
  226. if (GetWindowsDirectory((LPTSTR)szOPTGUDHlpName, MAX_PATH))
  227. {
  228. hr = StringCchCat((LPTSTR)szOPTGUDHlpName, ARRAYSIZE(szOPTGUDHlpName), TEXT("\\HELP\\WINIME.CHM"));
  229. if (FAILED(hr))
  230. break;
  231. HtmlHelp(hCMenuWnd,szOPTGUDHlpName,HH_DISPLAY_TOPIC,0L);
  232. }
  233. }
  234. break;
  235. case IDM_IMEGUD:
  236. {
  237. TCHAR szIMEGUDHlpName[MAX_PATH];
  238. szIMEGUDHlpName[0] = TEXT('\0');
  239. if (GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAX_PATH))
  240. {
  241. hr = StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT("\\HELP\\") );
  242. if (FAILED(hr))
  243. break;
  244. #if defined(COMBO_IME)
  245. //COMBO_IME has only one IME help file
  246. hr = StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT("WINGB.CHM"));
  247. if (FAILED(hr))
  248. break;
  249. #else //COMBO_IME
  250. #ifdef GB
  251. hr = StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT("WINGB.CHM"));
  252. if (FAILED(hr))
  253. break;
  254. #else
  255. hr = StringCchCat((LPTSTR)szIMEGUDHlpName, ARRAYSIZE(szIMEGUDHlpName), TEXT("WINNM.HLP"));
  256. if (FAILED(hr))
  257. break;
  258. #endif
  259. #endif //COMBO_IME
  260. HtmlHelp(hCMenuWnd,szIMEGUDHlpName,HH_DISPLAY_TOPIC,0L);
  261. }
  262. }
  263. break;
  264. case IDM_VER:
  265. {
  266. HIMC hIMC;
  267. LPINPUTCONTEXT lpIMC;
  268. HWND hUIWnd;
  269. hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
  270. if (!hUIWnd) {
  271. return (0L);
  272. }
  273. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  274. if (!hIMC) {
  275. return (0L);
  276. }
  277. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  278. if (!lpIMC) {
  279. return (0L);
  280. }
  281. DialogBox(hInst, TEXT("IMEVER"), (HWND)lpIMC->hWnd, ImeVerDlgProc);
  282. ImmUnlockIMC(hIMC);
  283. break;
  284. }
  285. }
  286. break;
  287. case WM_CLOSE:
  288. {
  289. HMENU hMenu;
  290. GetMenu(hCMenuWnd);
  291. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  292. if (hMenu) {
  293. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  294. DestroyMenu(hMenu);
  295. }
  296. }
  297. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  298. default:
  299. return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  300. }
  301. return (0L);
  302. }
  303. /**********************************************************************/
  304. /* SoftkeyMenuWndProc() */
  305. /**********************************************************************/
  306. LRESULT CALLBACK SoftkeyMenuWndProc(
  307. HWND hKeyMenuWnd,
  308. UINT uMsg,
  309. WPARAM wParam,
  310. LPARAM lParam)
  311. {
  312. switch (uMsg) {
  313. case WM_DESTROY:
  314. {
  315. HWND hUIWnd;
  316. hUIWnd = (HWND)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
  317. if (hUIWnd) {
  318. SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
  319. IMN_PRIVATE_SOFTKEYMENUDESTROYED);
  320. }
  321. }
  322. break;
  323. case WM_USER_DESTROY:
  324. {
  325. SendMessage(hKeyMenuWnd, WM_CLOSE, 0, 0);
  326. DestroyWindow(hKeyMenuWnd);
  327. }
  328. break;
  329. case WM_COMMAND:
  330. switch(LOWORD(wParam)) {
  331. case IDM_SKL1:
  332. case IDM_SKL2:
  333. case IDM_SKL3:
  334. case IDM_SKL4:
  335. case IDM_SKL5:
  336. case IDM_SKL6:
  337. case IDM_SKL7:
  338. case IDM_SKL8:
  339. case IDM_SKL9:
  340. case IDM_SKL10:
  341. case IDM_SKL11:
  342. case IDM_SKL12:
  343. case IDM_SKL13:
  344. {
  345. HIMC hIMC;
  346. LPINPUTCONTEXT lpIMC;
  347. LPPRIVCONTEXT lpImcP;
  348. DWORD fdwConversion;
  349. HWND hUIWnd;
  350. hUIWnd = (HWND)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
  351. if (!hUIWnd) {
  352. return (0L);
  353. }
  354. hIMC = (HIMC)GetWindowLongPtr(hUIWnd,IMMGWLP_IMC);
  355. if (!hIMC) {
  356. return (0L);
  357. }
  358. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  359. if (!lpIMC) {
  360. return (0L);
  361. }
  362. lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
  363. if (!lpImcP) {
  364. return (0L);
  365. }
  366. {
  367. UINT i;
  368. lpImeL->dwSKWant = LOWORD(wParam) - IDM_SKL1;
  369. lpImeL->dwSKState[lpImeL->dwSKWant] =
  370. lpImeL->dwSKState[lpImeL->dwSKWant]^1;
  371. // clear other SK State
  372. for(i=0; i<NumsSK; i++) {
  373. if(i == lpImeL->dwSKWant) continue;
  374. lpImeL->dwSKState[i] = 0;
  375. }
  376. if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
  377. if(LOWORD(wParam) == IDM_SKL1)
  378. lpImcP->iImeState = CST_INIT;
  379. else
  380. lpImcP->iImeState = CST_SOFTKB;
  381. fdwConversion = lpIMC->fdwConversion | IME_CMODE_SOFTKBD;
  382. } else {
  383. lpImcP->iImeState = CST_INIT;
  384. fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_SOFTKBD);
  385. }
  386. }
  387. ImmSetConversionStatus(hIMC, (fdwConversion & ~(IME_CMODE_SOFTKBD)),
  388. lpIMC->fdwSentence);
  389. ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
  390. ImmUnlockIMCC(lpIMC->hPrivate);
  391. ImmUnlockIMC(hIMC);
  392. break;
  393. }
  394. }
  395. break;
  396. case WM_CLOSE:
  397. {
  398. HMENU hMenu;
  399. GetMenu(hKeyMenuWnd);
  400. hMenu = (HMENU)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_MENU);
  401. if (hMenu) {
  402. SetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)NULL);
  403. DestroyMenu(hMenu);
  404. }
  405. }
  406. return DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
  407. case WM_SETCURSOR:
  408. if (HIWORD(lParam) == WM_RBUTTONUP)
  409. MessageBeep(-1);
  410. default:
  411. return DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
  412. }
  413. return (0L);
  414. }
  415. /**********************************************************************/
  416. /* ContextMenu() */
  417. /**********************************************************************/
  418. void PASCAL ContextMenu(
  419. HWND hStatusWnd,
  420. int x,
  421. int y)
  422. {
  423. HWND hUIWnd;
  424. HWND hCMenuWnd;
  425. HGLOBAL hUIPrivate;
  426. LPUIPRIV lpUIPrivate;
  427. HIMC hIMC;
  428. LPINPUTCONTEXT lpIMC;
  429. HMENU hMenu, hCMenu;
  430. RECT rcStatusWnd;
  431. RECT rcWorkArea;
  432. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  433. if(!hUIWnd){
  434. return;
  435. }
  436. GetWindowRect(hStatusWnd, &rcStatusWnd);
  437. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  438. if (!hIMC) {
  439. return;
  440. }
  441. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  442. if (!lpIMC) {
  443. return;
  444. }
  445. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  446. if (!hUIPrivate) {
  447. goto ContextMenuUnlockIMC;
  448. }
  449. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  450. if (!lpUIPrivate) {
  451. goto ContextMenuUnlockIMC;
  452. }
  453. if (!lpUIPrivate->hCMenuWnd) {
  454. // this is important to assign owner window, otherwise the focus
  455. // will be gone
  456. // When UI terminate, it need to destroy this window
  457. lpUIPrivate->hCMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
  458. szCMenuClassName, TEXT("Context Menu"),
  459. WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
  460. lpIMC->hWnd, (HMENU)NULL, hInst, NULL);
  461. }
  462. hCMenuWnd = lpUIPrivate->hCMenuWnd;
  463. // Unlock before we call into TrackPopupMenu().
  464. GlobalUnlock(hUIPrivate);
  465. if (!hCMenuWnd) {
  466. goto ContextMenuUnlockIMC;
  467. }
  468. hMenu = LoadMenu(hInst, TEXT("PROPMENU"));
  469. hCMenu = GetSubMenu(hMenu, 0);
  470. // Disable some of menu items.
  471. if ( lpImeL->fWinLogon == TRUE )
  472. {
  473. // In Logon Mode, we don't want to show help and configuration dialog
  474. EnableMenuItem(hCMenu, 0, MF_BYPOSITION | MF_GRAYED );
  475. EnableMenuItem(hCMenu, IDM_PROP, MF_BYCOMMAND | MF_GRAYED);
  476. }
  477. SetWindowLongPtr(hCMenuWnd, CMENU_HUIWND, (LONG_PTR)hUIWnd);
  478. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)hMenu);
  479. TrackPopupMenu (hCMenu, TPM_LEFTBUTTON,
  480. rcStatusWnd.left, rcStatusWnd.top, 0, hCMenuWnd, NULL);
  481. hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
  482. if (hMenu) {
  483. SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
  484. DestroyMenu(hMenu);
  485. }
  486. ContextMenuUnlockIMC:
  487. ImmUnlockIMC(hIMC);
  488. return;
  489. }
  490. /**********************************************************************/
  491. /* SoftkeyMenu() */
  492. /**********************************************************************/
  493. void PASCAL SoftkeyMenu(
  494. HWND hStatusWnd,
  495. int x,
  496. int y)
  497. {
  498. HWND hUIWnd;
  499. HWND hSoftkeyMenuWnd;
  500. HGLOBAL hUIPrivate;
  501. LPUIPRIV lpUIPrivate;
  502. HIMC hIMC;
  503. LPINPUTCONTEXT lpIMC;
  504. HMENU hMenu, hKeyMenu;
  505. RECT rcStatusWnd;
  506. hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
  507. if(!hUIWnd){
  508. return;
  509. }
  510. GetWindowRect(hStatusWnd, &rcStatusWnd);
  511. hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
  512. if (!hIMC) {
  513. return;
  514. }
  515. lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
  516. if (!lpIMC) {
  517. return;
  518. }
  519. hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
  520. if (!hUIPrivate) {
  521. goto KeyMenuUnlockIMC;
  522. }
  523. lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
  524. if (!lpUIPrivate) {
  525. goto KeyMenuUnlockIMC;
  526. }
  527. if (!lpUIPrivate->hSoftkeyMenuWnd) {
  528. // this is important to assign owner window, otherwise the focus
  529. // will be gone
  530. // When UI terminate, it need to destroy this window
  531. lpUIPrivate->hSoftkeyMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
  532. szSoftkeyMenuClassName, TEXT("Softkey Menu"),
  533. WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
  534. lpIMC->hWnd, (HMENU)NULL, hInst, NULL);
  535. }
  536. hSoftkeyMenuWnd = lpUIPrivate->hSoftkeyMenuWnd;
  537. // Unlock before we call into TrackPopupMenu().
  538. GlobalUnlock(hUIPrivate);
  539. if (!hSoftkeyMenuWnd) {
  540. goto KeyMenuUnlockIMC;
  541. }
  542. hMenu = LoadMenu(hInst, TEXT("SKMENU"));
  543. hKeyMenu = GetSubMenu(hMenu, 0);
  544. SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_HUIWND, (LONG_PTR)hUIWnd);
  545. SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)hMenu);
  546. if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
  547. CheckMenuItem(hMenu,lpImeL->dwSKWant + IDM_SKL1, MF_CHECKED);
  548. }
  549. TrackPopupMenu (hKeyMenu, TPM_LEFTBUTTON,
  550. rcStatusWnd.left, rcStatusWnd.top, 0, hSoftkeyMenuWnd, NULL);
  551. hMenu = (HMENU)GetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU);
  552. if (hMenu) {
  553. SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)NULL);
  554. DestroyMenu(hMenu);
  555. }
  556. KeyMenuUnlockIMC:
  557. ImmUnlockIMC(hIMC);
  558. return;
  559. }