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.

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