699 lines
19 KiB
C
699 lines
19 KiB
C
|
|
/*++
|
|
|
|
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
uisubs.c
|
|
|
|
|
|
++*/
|
|
|
|
|
|
#include <windows.h>
|
|
#include <immdev.h>
|
|
#include <htmlhelp.h>
|
|
#include <imedefs.h>
|
|
|
|
/**********************************************************************/
|
|
/* DrawDragBorder() */
|
|
/**********************************************************************/
|
|
void PASCAL DrawDragBorder(
|
|
HWND hWnd, // window of IME is dragged
|
|
LONG lCursorPos, // the cursor position
|
|
LONG lCursorOffset) // the offset form cursor to window org
|
|
{
|
|
HDC hDC;
|
|
int cxBorder, cyBorder;
|
|
int x, y;
|
|
RECT rcWnd;
|
|
|
|
cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
|
|
cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
|
|
|
|
// get cursor position
|
|
x = (*(LPPOINTS)&lCursorPos).x;
|
|
y = (*(LPPOINTS)&lCursorPos).y;
|
|
|
|
// calculate the org by the offset
|
|
x -= (*(LPPOINTS)&lCursorOffset).x;
|
|
y -= (*(LPPOINTS)&lCursorOffset).y;
|
|
|
|
#ifndef MUL_MONITOR
|
|
// check for the min boundary of the display
|
|
if (x < sImeG.rcWorkArea.left) {
|
|
x = sImeG.rcWorkArea.left;
|
|
}
|
|
|
|
if (y < sImeG.rcWorkArea.top) {
|
|
y = sImeG.rcWorkArea.top;
|
|
}
|
|
#endif
|
|
|
|
// check for the max boundary of the display
|
|
GetWindowRect(hWnd, &rcWnd);
|
|
|
|
#ifndef MUL_MONITOR
|
|
|
|
if (x + rcWnd.right - rcWnd.left > sImeG.rcWorkArea.right) {
|
|
x = sImeG.rcWorkArea.right - (rcWnd.right - rcWnd.left);
|
|
}
|
|
|
|
if (y + rcWnd.bottom - rcWnd.top > sImeG.rcWorkArea.bottom) {
|
|
y = sImeG.rcWorkArea.bottom - (rcWnd.bottom - rcWnd.top);
|
|
}
|
|
|
|
#endif
|
|
|
|
// draw the moving track
|
|
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
|
|
|
|
if ( hDC )
|
|
{
|
|
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
|
|
|
|
// ->
|
|
PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
|
|
PATINVERT);
|
|
// v
|
|
PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
|
|
cyBorder, PATINVERT);
|
|
// _>
|
|
PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
|
|
rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
|
|
// v
|
|
PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
|
|
- cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
|
|
|
|
DeleteDC(hDC);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* DrawFrameBorder() */
|
|
/**********************************************************************/
|
|
void PASCAL DrawFrameBorder( // border of IME
|
|
HDC hDC,
|
|
HWND hWnd) // window of IME
|
|
{
|
|
RECT rcWnd;
|
|
int xWi, yHi;
|
|
|
|
GetWindowRect(hWnd, &rcWnd);
|
|
|
|
xWi = rcWnd.right - rcWnd.left;
|
|
yHi = rcWnd.bottom - rcWnd.top;
|
|
|
|
// 1, ->
|
|
PatBlt(hDC, 0, 0, xWi, 1, WHITENESS);
|
|
|
|
// 1, v
|
|
PatBlt(hDC, 0, 0, 1, yHi, WHITENESS);
|
|
|
|
// 1, _>
|
|
PatBlt(hDC, 0, yHi, xWi, -1, BLACKNESS);
|
|
|
|
// 1, v
|
|
PatBlt(hDC, xWi, 0, -1, yHi, BLACKNESS);
|
|
|
|
xWi -= 2;
|
|
yHi -= 2;
|
|
|
|
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
|
|
|
|
// 2, ->
|
|
PatBlt(hDC, 1, 1, xWi, 1, PATCOPY);
|
|
|
|
// 2, v
|
|
PatBlt(hDC, 1, 1, 1, yHi, PATCOPY);
|
|
|
|
// 2, v
|
|
PatBlt(hDC, xWi + 1, 1, -1, yHi, PATCOPY);
|
|
|
|
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
|
|
|
|
// 2, _>
|
|
PatBlt(hDC, 1, yHi + 1, xWi, -1, PATCOPY);
|
|
|
|
xWi -= 2;
|
|
yHi -= 2;
|
|
|
|
// 3, ->
|
|
PatBlt(hDC, 2, 2, xWi, 1, PATCOPY);
|
|
|
|
// 3, v
|
|
PatBlt(hDC, 2, 2, 1, yHi, PATCOPY);
|
|
|
|
// 3, v
|
|
PatBlt(hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
|
|
|
|
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
|
|
|
|
// 3, _>
|
|
PatBlt(hDC, 2, yHi + 2, xWi, -1, PATCOPY);
|
|
|
|
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
|
|
|
|
xWi -= 2;
|
|
yHi -= 2;
|
|
|
|
// 4, ->
|
|
PatBlt(hDC, 3, 3, xWi, 1, PATCOPY);
|
|
|
|
// 4, v
|
|
PatBlt(hDC, 3, 3, 1, yHi, PATCOPY);
|
|
|
|
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
|
|
|
|
// 4, v
|
|
PatBlt(hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
|
|
|
|
// 4, _>
|
|
PatBlt(hDC, 3, yHi + 3, xWi, -1, WHITENESS);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/**********************************************************************/
|
|
/* ContextMenuWndProc() */
|
|
/**********************************************************************/
|
|
LRESULT CALLBACK ContextMenuWndProc(
|
|
HWND hCMenuWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
switch (uMsg) {
|
|
case WM_DESTROY:
|
|
{
|
|
HWND hUIWnd;
|
|
|
|
hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
|
|
|
|
if (hUIWnd) {
|
|
SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
|
|
IMN_PRIVATE_CMENUDESTROYED);
|
|
}
|
|
}
|
|
break;
|
|
case WM_USER_DESTROY:
|
|
{
|
|
SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
|
|
DestroyWindow(hCMenuWnd);
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam)) {
|
|
case IDM_PROP:
|
|
{
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
LPPRIVCONTEXT lpImcP;
|
|
int UI_MODE;
|
|
HWND hUIWnd;
|
|
RECT rcWorkArea;
|
|
|
|
hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
|
|
|
|
if (!hUIWnd) {
|
|
return (0L);
|
|
}
|
|
|
|
#ifdef MUL_MONITOR
|
|
rcWorkArea = ImeMonitorWorkAreaFromWindow(hCMenuWnd);
|
|
#else
|
|
rcWorkArea = sImeG.rcWorkArea;
|
|
#endif
|
|
|
|
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
|
|
if (!hIMC) {
|
|
return (0L);
|
|
}
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
if (!lpIMC) {
|
|
return (0L);
|
|
}
|
|
|
|
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
|
|
if (!lpImcP) {
|
|
return (0L);
|
|
}
|
|
|
|
ImeConfigure(GetKeyboardLayout(0), lpIMC->hWnd, IME_CONFIG_GENERAL, NULL);
|
|
|
|
#ifdef CROSSREF
|
|
{
|
|
HWND hCompWnd;
|
|
hCompWnd = GetCompWnd(hUIWnd);
|
|
DestroyWindow(hCompWnd);
|
|
}
|
|
#endif
|
|
|
|
lpImcP->iImeState = CST_INIT;
|
|
CompCancel(hIMC, lpIMC);
|
|
|
|
// change compwnd size
|
|
|
|
// init fields of hIMC
|
|
lpIMC->fOpen = TRUE;
|
|
|
|
if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
|
|
lpIMC->fdwConversion = IME_CMODE_NATIVE;
|
|
lpIMC->fdwInit |= INIT_CONVERSION;
|
|
}
|
|
|
|
lpImcP->fdwImeMsg = lpImcP->fdwImeMsg | MSG_IMN_DESTROYCAND;
|
|
GenerateMessage(hIMC, lpIMC, lpImcP);
|
|
|
|
// set cand window data
|
|
if(sImeG.IC_Trace) {
|
|
UI_MODE = BOX_UI;
|
|
} else {
|
|
POINT ptSTFixPos;
|
|
|
|
UI_MODE = LIN_UI;
|
|
ptSTFixPos.x = 0;
|
|
ptSTFixPos.y = rcWorkArea.bottom - sImeG.yStatusHi;
|
|
ImmSetStatusWindowPos(hIMC, (LPPOINT)&ptSTFixPos);
|
|
}
|
|
InitCandUIData(
|
|
GetSystemMetrics(SM_CXBORDER),
|
|
GetSystemMetrics(SM_CYBORDER), UI_MODE);
|
|
|
|
ImmUnlockIMCC(lpIMC->hPrivate);
|
|
ImmUnlockIMC(hIMC);
|
|
break;
|
|
}
|
|
//case IDM_HLP:
|
|
case IDM_OPTGUD:
|
|
{
|
|
TCHAR szOPTGUDHlpName[MAX_PATH];
|
|
|
|
szOPTGUDHlpName[0] = 0;
|
|
GetWindowsDirectory((LPTSTR)szOPTGUDHlpName, MAX_PATH);
|
|
lstrcat((LPTSTR)szOPTGUDHlpName, TEXT("\\HELP\\WINIME.CHM"));
|
|
HtmlHelp(hCMenuWnd,szOPTGUDHlpName,HH_DISPLAY_TOPIC,0L);
|
|
}
|
|
break;
|
|
case IDM_IMEGUD:
|
|
{
|
|
TCHAR szIMEGUDHlpName[MAX_PATH];
|
|
|
|
szIMEGUDHlpName[0] = TEXT('\0');
|
|
GetWindowsDirectory((LPTSTR)szIMEGUDHlpName, MAX_PATH);
|
|
lstrcat((LPTSTR)szIMEGUDHlpName, TEXT("\\HELP\\") );
|
|
#if defined(COMBO_IME)
|
|
//COMBO_IME has only one IME help file
|
|
lstrcat((LPTSTR)szIMEGUDHlpName, TEXT("WINGB.CHM"));
|
|
#else //COMBO_IME
|
|
#ifdef GB
|
|
lstrcpy((LPTSTR)szIMEGUDHlpName, TEXT("WINGB.CHM"));
|
|
#else
|
|
lstrcpy((LPTSTR)szIMEGUDHlpName, TEXT("WINNM.HLP"));
|
|
#endif
|
|
#endif //COMBO_IME
|
|
HtmlHelp(hCMenuWnd,szIMEGUDHlpName,HH_DISPLAY_TOPIC,0L);
|
|
}
|
|
break;
|
|
case IDM_VER:
|
|
{
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
HWND hUIWnd;
|
|
|
|
hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
|
|
|
|
if (!hUIWnd) {
|
|
return (0L);
|
|
}
|
|
|
|
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
|
|
|
|
if (!hIMC) {
|
|
return (0L);
|
|
}
|
|
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
if (!lpIMC) {
|
|
return (0L);
|
|
}
|
|
|
|
DialogBox(hInst, TEXT("IMEVER"), (HWND)lpIMC->hWnd, (DLGPROC)ImeVerDlgProc);
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
{
|
|
HMENU hMenu;
|
|
|
|
GetMenu(hCMenuWnd);
|
|
|
|
hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
|
|
if (hMenu) {
|
|
SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
|
|
DestroyMenu(hMenu);
|
|
}
|
|
}
|
|
return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
|
|
default:
|
|
return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
return (0L);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* SoftkeyMenuWndProc() */
|
|
/**********************************************************************/
|
|
LRESULT CALLBACK SoftkeyMenuWndProc(
|
|
HWND hKeyMenuWnd,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
switch (uMsg) {
|
|
case WM_DESTROY:
|
|
{
|
|
HWND hUIWnd;
|
|
|
|
hUIWnd = (HWND)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
|
|
|
|
if (hUIWnd) {
|
|
SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
|
|
IMN_PRIVATE_SOFTKEYMENUDESTROYED);
|
|
}
|
|
}
|
|
break;
|
|
case WM_USER_DESTROY:
|
|
{
|
|
SendMessage(hKeyMenuWnd, WM_CLOSE, 0, 0);
|
|
DestroyWindow(hKeyMenuWnd);
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam)) {
|
|
case IDM_SKL1:
|
|
case IDM_SKL2:
|
|
case IDM_SKL3:
|
|
case IDM_SKL4:
|
|
case IDM_SKL5:
|
|
case IDM_SKL6:
|
|
case IDM_SKL7:
|
|
case IDM_SKL8:
|
|
case IDM_SKL9:
|
|
case IDM_SKL10:
|
|
case IDM_SKL11:
|
|
case IDM_SKL12:
|
|
case IDM_SKL13:
|
|
{
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
LPPRIVCONTEXT lpImcP;
|
|
DWORD fdwConversion;
|
|
HWND hUIWnd;
|
|
|
|
hUIWnd = (HWND)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
|
|
|
|
if (!hUIWnd) {
|
|
return (0L);
|
|
}
|
|
|
|
hIMC = (HIMC)GetWindowLongPtr(hUIWnd,IMMGWLP_IMC);
|
|
|
|
if (!hIMC) {
|
|
return (0L);
|
|
}
|
|
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
if (!lpIMC) {
|
|
return (0L);
|
|
}
|
|
|
|
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
|
|
|
|
if (!lpImcP) {
|
|
return (0L);
|
|
}
|
|
|
|
{
|
|
UINT i;
|
|
|
|
lpImeL->dwSKWant = LOWORD(wParam) - IDM_SKL1;
|
|
lpImeL->dwSKState[lpImeL->dwSKWant] =
|
|
lpImeL->dwSKState[lpImeL->dwSKWant]^1;
|
|
|
|
// clear other SK State
|
|
for(i=0; i<NumsSK; i++) {
|
|
if(i == lpImeL->dwSKWant) continue;
|
|
lpImeL->dwSKState[i] = 0;
|
|
}
|
|
|
|
if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
|
|
if(LOWORD(wParam) == IDM_SKL1)
|
|
lpImcP->iImeState = CST_INIT;
|
|
else
|
|
lpImcP->iImeState = CST_SOFTKB;
|
|
fdwConversion = lpIMC->fdwConversion | IME_CMODE_SOFTKBD;
|
|
} else {
|
|
lpImcP->iImeState = CST_INIT;
|
|
fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_SOFTKBD);
|
|
}
|
|
}
|
|
|
|
ImmSetConversionStatus(hIMC, (fdwConversion & ~(IME_CMODE_SOFTKBD)),
|
|
lpIMC->fdwSentence);
|
|
ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
|
|
|
|
ImmUnlockIMCC(lpIMC->hPrivate);
|
|
ImmUnlockIMC(hIMC);
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
{
|
|
HMENU hMenu;
|
|
|
|
GetMenu(hKeyMenuWnd);
|
|
|
|
hMenu = (HMENU)GetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_MENU);
|
|
if (hMenu) {
|
|
SetWindowLongPtr(hKeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)NULL);
|
|
DestroyMenu(hMenu);
|
|
}
|
|
}
|
|
return DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
|
|
|
|
case WM_SETCURSOR:
|
|
if (HIWORD(lParam) == WM_RBUTTONUP)
|
|
MessageBeep(-1);
|
|
default:
|
|
return DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
return (0L);
|
|
}
|
|
|
|
|
|
/**********************************************************************/
|
|
/* ContextMenu() */
|
|
/**********************************************************************/
|
|
void PASCAL ContextMenu(
|
|
HWND hStatusWnd,
|
|
int x,
|
|
int y)
|
|
{
|
|
HWND hUIWnd;
|
|
HWND hCMenuWnd;
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
HMENU hMenu, hCMenu;
|
|
RECT rcStatusWnd;
|
|
RECT rcWorkArea;
|
|
|
|
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
|
|
if(!hUIWnd){
|
|
return;
|
|
}
|
|
GetWindowRect(hStatusWnd, &rcStatusWnd);
|
|
|
|
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
|
|
if (!hIMC) {
|
|
return;
|
|
}
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
if (!lpIMC) {
|
|
return;
|
|
}
|
|
|
|
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
|
|
if (!hUIPrivate) {
|
|
goto ContextMenuUnlockIMC;
|
|
}
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
if (!lpUIPrivate) {
|
|
goto ContextMenuUnlockIMC;
|
|
}
|
|
|
|
if (!lpUIPrivate->hCMenuWnd) {
|
|
// this is important to assign owner window, otherwise the focus
|
|
// will be gone
|
|
|
|
// When UI terminate, it need to destroy this window
|
|
lpUIPrivate->hCMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
|
|
szCMenuClassName, TEXT("Context Menu"),
|
|
WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
|
|
lpIMC->hWnd, (HMENU)NULL, hInst, NULL);
|
|
|
|
}
|
|
|
|
hCMenuWnd = lpUIPrivate->hCMenuWnd;
|
|
|
|
// Unlock before we call into TrackPopupMenu().
|
|
GlobalUnlock(hUIPrivate);
|
|
|
|
if (!hCMenuWnd) {
|
|
goto ContextMenuUnlockIMC;
|
|
}
|
|
|
|
hMenu = LoadMenu(hInst, TEXT("PROPMENU"));
|
|
hCMenu = GetSubMenu(hMenu, 0);
|
|
|
|
// Disable some of menu items.
|
|
|
|
if ( lpImeL->fWinLogon == TRUE )
|
|
{
|
|
// In Logon Mode, we don't want to show help and configuration dialog
|
|
|
|
EnableMenuItem(hCMenu, 0, MF_BYPOSITION | MF_GRAYED );
|
|
EnableMenuItem(hCMenu, IDM_PROP, MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
|
|
SetWindowLongPtr(hCMenuWnd, CMENU_HUIWND, (LONG_PTR)hUIWnd);
|
|
SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)hMenu);
|
|
|
|
TrackPopupMenu (hCMenu, TPM_LEFTBUTTON,
|
|
rcStatusWnd.left, rcStatusWnd.top, 0, hCMenuWnd, NULL);
|
|
|
|
hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
|
|
if (hMenu) {
|
|
SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
|
|
DestroyMenu(hMenu);
|
|
}
|
|
|
|
ContextMenuUnlockIMC:
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return;
|
|
}
|
|
/**********************************************************************/
|
|
/* SoftkeyMenu() */
|
|
/**********************************************************************/
|
|
void PASCAL SoftkeyMenu(
|
|
HWND hStatusWnd,
|
|
int x,
|
|
int y)
|
|
{
|
|
HWND hUIWnd;
|
|
HWND hSoftkeyMenuWnd;
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
HMENU hMenu, hKeyMenu;
|
|
RECT rcStatusWnd;
|
|
|
|
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
|
|
if(!hUIWnd){
|
|
return;
|
|
}
|
|
GetWindowRect(hStatusWnd, &rcStatusWnd);
|
|
|
|
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
|
|
if (!hIMC) {
|
|
return;
|
|
}
|
|
|
|
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
|
|
if (!lpIMC) {
|
|
return;
|
|
}
|
|
|
|
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
|
|
if (!hUIPrivate) {
|
|
goto KeyMenuUnlockIMC;
|
|
}
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
if (!lpUIPrivate) {
|
|
goto KeyMenuUnlockIMC;
|
|
}
|
|
|
|
if (!lpUIPrivate->hSoftkeyMenuWnd) {
|
|
// this is important to assign owner window, otherwise the focus
|
|
// will be gone
|
|
|
|
// When UI terminate, it need to destroy this window
|
|
lpUIPrivate->hSoftkeyMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
|
|
szSoftkeyMenuClassName, TEXT("Softkey Menu"),
|
|
WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
|
|
lpIMC->hWnd, (HMENU)NULL, hInst, NULL);
|
|
|
|
}
|
|
|
|
hSoftkeyMenuWnd = lpUIPrivate->hSoftkeyMenuWnd;
|
|
|
|
// Unlock before we call into TrackPopupMenu().
|
|
GlobalUnlock(hUIPrivate);
|
|
|
|
if (!hSoftkeyMenuWnd) {
|
|
goto KeyMenuUnlockIMC;
|
|
}
|
|
|
|
hMenu = LoadMenu(hInst, TEXT("SKMENU"));
|
|
hKeyMenu = GetSubMenu(hMenu, 0);
|
|
|
|
SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_HUIWND, (LONG_PTR)hUIWnd);
|
|
SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)hMenu);
|
|
|
|
|
|
if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
|
|
CheckMenuItem(hMenu,lpImeL->dwSKWant + IDM_SKL1, MF_CHECKED);
|
|
}
|
|
|
|
|
|
TrackPopupMenu (hKeyMenu, TPM_LEFTBUTTON,
|
|
rcStatusWnd.left, rcStatusWnd.top, 0, hSoftkeyMenuWnd, NULL);
|
|
|
|
hMenu = (HMENU)GetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU);
|
|
if (hMenu) {
|
|
SetWindowLongPtr(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, (LONG_PTR)NULL);
|
|
DestroyMenu(hMenu);
|
|
}
|
|
|
|
KeyMenuUnlockIMC:
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
return;
|
|
}
|
|
|