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.
1451 lines
46 KiB
1451 lines
46 KiB
/****************************************************************************
|
|
UI.CPP
|
|
|
|
Owner: cslim
|
|
Copyright (c) 1997-1999 Microsoft Corporation
|
|
|
|
UI functions
|
|
|
|
History:
|
|
14-JUL-1999 cslim Copied from IME98 source tree
|
|
*****************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#include "apientry.h"
|
|
#include "ui.h"
|
|
#include "imedefs.h"
|
|
#include "names.h"
|
|
#include "config.h"
|
|
#include "debug.h"
|
|
#include "shellapi.h"
|
|
#include "winex.h"
|
|
#include "imcsub.h"
|
|
#include "cpadsvr.h"
|
|
#include "pad.h"
|
|
#include "cicero.h"
|
|
#include "toolbar.h"
|
|
#include "resource.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
PRIVATE LRESULT CALLBACK UIWndProc(HWND hUIWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
|
|
PRIVATE BOOL HandlePrivateMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plRet);
|
|
|
|
PRIVATE LRESULT PASCAL NotifyUI(HWND hUIWnd, WPARAM wParam, LPARAM lParam);
|
|
PRIVATE VOID PASCAL StatusWndMsg(HWND hUIWnd, BOOL fOn);
|
|
PRIVATE HWND PASCAL GetStatusWnd(HWND hUIWnd);
|
|
PRIVATE VOID PASCAL ShowUI(HWND hUIWnd, int nShowCmd);
|
|
PRIVATE VOID PASCAL OnImeSetContext(HWND hUIWnd, BOOL fOn, LPARAM lShowUI);
|
|
PRIVATE VOID PASCAL OnImeSelect(HWND hUIWnd, BOOL fOn);
|
|
PRIVATE HWND PASCAL GetCandWnd(HWND hUIWnd);
|
|
PRIVATE HWND PASCAL GetCompWnd(HWND hUIWnd);
|
|
PRIVATE LRESULT PASCAL GetCandPos(HWND hUIWnd, LPCANDIDATEFORM lpCandForm);
|
|
PRIVATE LRESULT PASCAL GetCompPos(HWND hUIWnd, LPCOMPOSITIONFORM lpCompForm);
|
|
PRIVATE VOID PASCAL UIWndOnCommand(HWND hUIWnd, int id, HWND hWndCtl, UINT codeNotify);
|
|
|
|
// Commented out SetIndicator because #199
|
|
PRIVATE BOOL PASCAL SetIndicator(PCIMECtx pImeCtx);
|
|
|
|
__inline
|
|
BOOL PASCAL SetIndicator(HIMC hIMC)
|
|
{
|
|
PCIMECtx pImeCtx;
|
|
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
return fFalse;
|
|
else
|
|
return SetIndicator(pImeCtx);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// TLS
|
|
#define UNDEF_TLSINDEX -1
|
|
DWORD vdwTLSIndex = UNDEF_TLSINDEX; // Thread Local Strage initial value.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Private UI messages
|
|
UINT WM_MSIME_PROPERTY = 0; // Invoke property DLG
|
|
UINT WM_MSIME_UPDATETOOLBAR = 0; // Redraw status window(Toolbar)
|
|
UINT WM_MSIME_OPENMENU = 0; // Pop up status window context menu
|
|
UINT WM_MSIME_IMEPAD = 0; // Boot up IME Pad
|
|
|
|
// Message string
|
|
#define RWM_PROPERTY "MSIMEProperty"
|
|
#define RWM_UPDATETOOLBAR "MSIMEUpdateToolbar"
|
|
#define RWM_OPENMENU "MSIMEOpenMenu"
|
|
#define RWM_IMEPAD "MSIMEIMEPAD"
|
|
|
|
/*----------------------------------------------------------------------------
|
|
InitPrivateUIMsg
|
|
|
|
Register all IME private UI messages
|
|
----------------------------------------------------------------------------*/
|
|
BOOL InitPrivateUIMsg()
|
|
{
|
|
WM_MSIME_PROPERTY = RegisterWindowMessageA(RWM_PROPERTY);
|
|
WM_MSIME_UPDATETOOLBAR = RegisterWindowMessageA(RWM_UPDATETOOLBAR);
|
|
WM_MSIME_OPENMENU = RegisterWindowMessageA(RWM_OPENMENU);
|
|
WM_MSIME_IMEPAD = RegisterWindowMessageA(RWM_IMEPAD);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
RegisterImeUIClass
|
|
|
|
Register all IME UI calsses
|
|
----------------------------------------------------------------------------*/
|
|
BOOL RegisterImeUIClass(HANDLE hInstance)
|
|
{
|
|
WNDCLASSEXA wc;
|
|
HANDLE hMod;
|
|
BOOL fRet = fTrue;
|
|
|
|
// Init wc zero
|
|
ZeroMemory(&wc, sizeof(WNDCLASSEXA));
|
|
|
|
wc.cbSize = sizeof(WNDCLASSEXW);
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = sizeof(LONG_PTR) * 2; // for IMMGWLP_IMC and IMMGWLP_PRIVATE
|
|
// and for move offset of Status window
|
|
wc.hIcon = NULL;
|
|
wc.hInstance = (HINSTANCE)hInstance;
|
|
wc.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
|
|
wc.lpszMenuName = NULL;
|
|
wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
|
|
wc.hIconSm = NULL;
|
|
|
|
// Assumption
|
|
DbgAssert(sizeof(WNDCLASSEXA) == sizeof(WNDCLASSEXW));
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// IME UI server class
|
|
|
|
wc.style = CS_VREDRAW | CS_HREDRAW | CS_IME;
|
|
wc.lpfnWndProc = UIWndProc;
|
|
|
|
// Create Unicode window when NT
|
|
if (IsWinNT())
|
|
{
|
|
LPWNDCLASSEXW pwcW = (LPWNDCLASSEXW)&wc;
|
|
|
|
// IME UI class UNICODE name
|
|
pwcW->lpszClassName = wszUIClassName;
|
|
|
|
if ((fRet = RegisterClassExW(pwcW)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
|
|
}
|
|
else
|
|
{
|
|
// IME UI class ANSI name
|
|
wc.lpszClassName = szUIClassName;
|
|
|
|
if ((fRet = RegisterClassEx(&wc)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// IME status class
|
|
wc.style = CS_VREDRAW | CS_HREDRAW | CS_IME;
|
|
wc.lpfnWndProc = StatusWndProc;
|
|
wc.lpszClassName = szStatusClassName;
|
|
if ((fRet = RegisterClassEx(&wc)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
|
|
// Cand and composition wnd do not need extra wnd bytes
|
|
wc.cbWndExtra = 0;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// IME candidate class
|
|
wc.lpfnWndProc = CandWndProc;
|
|
wc.lpszClassName = szCandClassName;
|
|
if ((fRet = RegisterClassEx(&wc)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// IME composition class
|
|
wc.lpfnWndProc = CompWndProc;
|
|
wc.lpszClassName = szCompClassName;
|
|
if ((fRet = RegisterClassEx(&wc)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Register Our Tooltip class
|
|
hMod = GetModuleHandle("comctl32.dll");
|
|
DbgAssert(hMod != 0);
|
|
// If NT, register W class for Unicode text display on tooltip
|
|
if (IsWinNT())
|
|
{
|
|
WNDCLASSEXW wcw;
|
|
// Init wcw
|
|
ZeroMemory(&wcw, sizeof(WNDCLASSEXW));
|
|
|
|
wcw.cbSize = sizeof(WNDCLASSEXW);
|
|
|
|
if (!GetClassInfoExW(NULL, wszTooltipClassName, &wcw))
|
|
{
|
|
GetClassInfoExW(NULL, TOOLTIPS_CLASSW, &wcw);
|
|
wcw.cbSize = sizeof(WNDCLASSEXW);
|
|
wcw.style |= CS_IME;
|
|
wcw.hInstance = (HINSTANCE)hMod;
|
|
wcw.lpszClassName = wszTooltipClassName;
|
|
if ((fRet = RegisterClassExW(&wcw)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
|
|
if (!GetClassInfoEx(NULL, szTooltipClassName, &wc))
|
|
{
|
|
GetClassInfoEx(NULL, TOOLTIPS_CLASS, &wc);
|
|
wc.cbSize = sizeof(WNDCLASSEX);
|
|
wc.style |= CS_IME;
|
|
wc.hInstance = (HINSTANCE)hMod;
|
|
wc.lpszClassName = szTooltipClassName;
|
|
if ((fRet = RegisterClassEx(&wc)) == fFalse)
|
|
goto RegisterImeUIClassExit;
|
|
}
|
|
}
|
|
|
|
RegisterImeUIClassExit:
|
|
#ifdef DEBUG
|
|
OutputDebugString("RegisterImeUIClass() : return\r\n");
|
|
#endif
|
|
DbgAssert(fRet);
|
|
return fRet;
|
|
}
|
|
|
|
|
|
BOOL UnregisterImeUIClass(HANDLE hInstance)
|
|
{
|
|
BOOL fRet = fTrue;
|
|
|
|
// Unregister Status window class
|
|
UnregisterClass(szStatusClassName, (HINSTANCE)hInstance);
|
|
|
|
// Unregister Candidate window class
|
|
UnregisterClass(szCandClassName, (HINSTANCE)hInstance);
|
|
|
|
// Unregister Composition window class
|
|
UnregisterClass(szCompClassName, (HINSTANCE)hInstance);
|
|
|
|
// Unregister Tooltip window class
|
|
UnregisterClass(szTooltipClassName, (HINSTANCE)hInstance);
|
|
|
|
// Unregister UI class window class
|
|
UnregisterClass(szUIClassName, (HINSTANCE)hInstance);
|
|
|
|
return fRet;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
UIWndProc
|
|
|
|
IME UI wnd messgae proc
|
|
----------------------------------------------------------------------------*/
|
|
LRESULT CALLBACK UIWndProc(HWND hUIWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
LRESULT lRet;
|
|
LRESULT lResult = 0;
|
|
|
|
Dbg(DBGID_UI, TEXT("UIWndProc():uMessage = 0x%08lX, wParam = 0x%04X, lParam = 0x%08lX"), uMessage, wParam, lParam);
|
|
|
|
switch (uMessage)
|
|
{
|
|
HANDLE_MSG(hUIWnd, WM_COMMAND, UIWndOnCommand);
|
|
case WM_CREATE:
|
|
Dbg(DBGID_UI, TEXT("UIWndProc(): WM_CREATE- UI window Created"));
|
|
// create storage for UI setting
|
|
hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV));
|
|
if (!hUIPrivate)
|
|
{
|
|
DbgAssert(0);
|
|
return 1L;
|
|
}
|
|
|
|
if ((lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate))==0)
|
|
return 1L;
|
|
|
|
// Set UI show default value.
|
|
lpUIPrivate->uiShowParam = ISC_SHOWUIALL;
|
|
|
|
SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)hUIPrivate);
|
|
// set the default position for UI window, it is hide now
|
|
//SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER);
|
|
//ShowWindow(hUIWnd, SW_SHOWNOACTIVATE);
|
|
|
|
// Chcek if this is Winlogon process in Win9x
|
|
if (!IsWinNT())
|
|
{
|
|
if (IsExplorerProcess() == fFalse && IsExplorer() == fFalse)
|
|
vpInstData->dwSystemInfoFlags |= IME_SYSINFO_WINLOGON;
|
|
}
|
|
|
|
// Init Cicero service
|
|
CiceroInitialize();
|
|
DbgAssert(lpUIPrivate->m_pCicToolbar == NULL);
|
|
|
|
if (IsCicero())
|
|
lpUIPrivate->m_pCicToolbar = new CToolBar();
|
|
|
|
GlobalUnlock(hUIPrivate);
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
Dbg(DBGID_UI, TEXT("UIWndProc(): WM_DESTROY- UI window destroyed"));
|
|
|
|
// Destroy IME Pad if exist
|
|
CImePadSvr::DestroyCImePadSvr();
|
|
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate))
|
|
{
|
|
Dbg(DBGID_UI, TEXT(" - WM_DESTROY Destroy all UI windows"));
|
|
|
|
if (lpUIPrivate->hStatusTTWnd)
|
|
DestroyWindow(lpUIPrivate->hCandTTWnd);
|
|
|
|
if (lpUIPrivate->hStatusWnd)
|
|
DestroyWindow(lpUIPrivate->hStatusWnd);
|
|
|
|
if (lpUIPrivate->hCandTTWnd)
|
|
DestroyWindow(lpUIPrivate->hCandTTWnd);
|
|
|
|
if (lpUIPrivate->hCandWnd)
|
|
DestroyWindow(lpUIPrivate->hCandWnd);
|
|
|
|
if (lpUIPrivate->hCompWnd)
|
|
DestroyWindow(lpUIPrivate->hCompWnd);
|
|
|
|
// Terminate Cicero service
|
|
if (IsCicero())
|
|
{
|
|
if (lpUIPrivate->m_pCicToolbar)
|
|
{
|
|
lpUIPrivate->m_pCicToolbar->Terminate();
|
|
delete lpUIPrivate->m_pCicToolbar;
|
|
lpUIPrivate->m_pCicToolbar = NULL;
|
|
}
|
|
// Issue: This call causes AV on Win9x
|
|
// CiceroTerminate();
|
|
}
|
|
|
|
GlobalUnlock(hUIPrivate);
|
|
GlobalFree(hUIPrivate);
|
|
SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)0L);
|
|
}
|
|
|
|
return 0;
|
|
|
|
case WM_IME_NOTIFY:
|
|
return NotifyUI(hUIWnd, wParam, lParam);
|
|
|
|
case WM_IME_SETCONTEXT:
|
|
Dbg(DBGID_UI, TEXT(" - WM_IME_SETCONTEXT"));
|
|
OnImeSetContext(hUIWnd, (BOOL)wParam, lParam);
|
|
return 0;
|
|
|
|
// WM_IME_CONTROL: Return Non-zero means failure otherwise 0
|
|
case WM_IME_CONTROL:
|
|
Dbg(DBGID_UI, TEXT(" - WM_IME_CONTROL"));
|
|
switch (wParam)
|
|
{
|
|
case IMC_GETCANDIDATEPOS:
|
|
return GetCandPos(hUIWnd, (LPCANDIDATEFORM)lParam);
|
|
|
|
case IMC_GETCOMPOSITIONWINDOW:
|
|
return GetCompPos(hUIWnd, (LPCOMPOSITIONFORM)lParam);
|
|
|
|
case IMC_GETSTATUSWINDOWPOS:
|
|
{
|
|
HWND hStatusWnd;
|
|
RECT rcStatusWnd;
|
|
|
|
Dbg(DBGID_UI, TEXT("UIWndProc() - WM_IME_CONTROL - IMC_GETSTATUSWINDOWPOS"));
|
|
hStatusWnd = GetStatusWnd(hUIWnd);
|
|
if (!hStatusWnd)
|
|
return (1L);
|
|
|
|
if (!GetWindowRect(hStatusWnd, &rcStatusWnd))
|
|
return (1L);
|
|
|
|
return (MAKELRESULT(rcStatusWnd.left, rcStatusWnd.top));
|
|
}
|
|
break;
|
|
|
|
case IMC_GETCOMPOSITIONFONT:
|
|
{
|
|
HFONT hFontFix;
|
|
LPLOGFONT lpLogFont;
|
|
LOGFONT lfFont;
|
|
|
|
hFontFix = CreateFont(-16,0,0,0,0,0,0,0,129,OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH, szIMECompFont);
|
|
lpLogFont = (LPLOGFONT)lParam;
|
|
if (GetObject(hFontFix, sizeof(lfFont), (LPVOID)&lfFont))
|
|
*lpLogFont = lfFont;
|
|
DeleteObject(hFontFix);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return (1L);
|
|
}
|
|
return 0;
|
|
|
|
//
|
|
case WM_IME_STARTCOMPOSITION:
|
|
OpenComp(hUIWnd);
|
|
return 0;
|
|
|
|
case WM_IME_COMPOSITION:
|
|
HWND hCompWnd;
|
|
hCompWnd = GetCompWnd(hUIWnd);
|
|
if (hCompWnd) // Do not use Update() !
|
|
{
|
|
ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
|
|
InvalidateRect(hCompWnd, NULL, fTrue);
|
|
}
|
|
return 0;
|
|
|
|
case WM_IME_ENDCOMPOSITION:
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (hUIPrivate && (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)))
|
|
{
|
|
// if comp wnd exist, destroy it.
|
|
if (lpUIPrivate->hCompWnd)
|
|
{
|
|
ShowComp(hUIWnd, SW_HIDE);
|
|
DestroyWindow(lpUIPrivate->hCompWnd);
|
|
lpUIPrivate->hCompWnd = 0;
|
|
}
|
|
GlobalUnlock(hUIPrivate);
|
|
}
|
|
return 0;
|
|
|
|
case WM_IME_SELECT:
|
|
Dbg(DBGID_UI, TEXT(" - WM_IME_SELECT"));
|
|
OnImeSelect(hUIWnd, (BOOL)wParam);
|
|
return 0;
|
|
|
|
case WM_DISPLAYCHANGE:
|
|
{
|
|
CIMEData ImeData(CIMEData::SMReadWrite);
|
|
|
|
Dbg(DBGID_UI, TEXT(" - WM_DISPLAYCHANGE"));
|
|
SystemParametersInfo(SPI_GETWORKAREA, 0, &ImeData->rcWorkArea, 0);
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if ( lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate) )
|
|
{
|
|
StatusDisplayChange(hUIWnd);
|
|
GlobalUnlock(hUIPrivate);
|
|
}
|
|
return 0;
|
|
}
|
|
default:
|
|
if (vfUnicode == fTrue && IsWinNT() == fTrue)
|
|
lResult = DefWindowProcW(hUIWnd, uMessage, wParam, lParam);
|
|
else
|
|
lResult = DefWindowProc(hUIWnd, uMessage, wParam, lParam);
|
|
}
|
|
|
|
// if Private msg
|
|
if (uMessage >= 0xC000)
|
|
{
|
|
// if private msg proccessed return value
|
|
if (HandlePrivateMessage(hUIWnd, uMessage, wParam, lParam, &lRet))
|
|
return lRet;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
HandlePrivateMessage
|
|
|
|
IME UI private messgae handler
|
|
----------------------------------------------------------------------------*/
|
|
PRIVATE BOOL HandlePrivateMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plRet)
|
|
{
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
LRESULT lRet = 0;
|
|
BOOL fProcessed = fFalse;
|
|
|
|
if (msg == WM_MSIME_PROPERTY)
|
|
{
|
|
fProcessed = fTrue;
|
|
hIMC = GethImcFromHwnd(hWnd);
|
|
if (pImeCtx = GetIMECtx(hIMC))
|
|
ImeConfigure(NULL, pImeCtx->GetAppWnd(), (DWORD)lParam, NULL);
|
|
DbgAssert(pImeCtx != NULL);
|
|
}
|
|
else
|
|
if (msg == WM_MSIME_UPDATETOOLBAR)
|
|
{
|
|
HWND hStatusWnd;
|
|
|
|
fProcessed = fTrue;
|
|
hStatusWnd = GetStatusWnd(hWnd);
|
|
if (hStatusWnd)
|
|
{
|
|
CIMEData ImeData;
|
|
InvalidateRect(hStatusWnd, &ImeData->rcButtonArea, fFalse);
|
|
}
|
|
}
|
|
else
|
|
if (msg == WM_MSIME_OPENMENU)
|
|
{
|
|
fProcessed = fTrue;
|
|
UIPopupMenu(hWnd);
|
|
}
|
|
else
|
|
if (msg == WM_MSIME_IMEPAD)
|
|
{
|
|
if ((vpInstData->dwSystemInfoFlags & IME_SYSINFO_WINLOGON) == 0)
|
|
{
|
|
hIMC = GethImcFromHwnd(hWnd);
|
|
if (pImeCtx = GetIMECtx(hIMC))
|
|
SetForegroundWindow(pImeCtx->GetAppWnd()); // trick
|
|
DbgAssert(pImeCtx != NULL);
|
|
|
|
// Boot Pad
|
|
BootPad(hWnd, (UINT)wParam, lParam);
|
|
}
|
|
}
|
|
|
|
*plRet = lRet;
|
|
return fProcessed;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
LRESULT PASCAL NotifyUI(HWND hUIWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hWnd;
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
LONG lRet = 0;
|
|
|
|
Dbg(DBGID_UI, TEXT("NotifyUI(): hUIWnd = 0x%X wParam = 0x%04X, lParam = 0x%08lX"), hUIWnd, wParam, lParam);
|
|
|
|
switch (wParam)
|
|
{
|
|
case IMN_OPENSTATUSWINDOW:
|
|
Dbg(DBGID_UI, TEXT("NotifyUI(): IMN_OPENSTATUSWINDOW"));
|
|
StatusWndMsg(hUIWnd, fTrue);
|
|
break;
|
|
|
|
case IMN_CLOSESTATUSWINDOW:
|
|
Dbg(DBGID_UI, TEXT("NotifyUI(): IMN_CLOSESTATUSWINDOW"));
|
|
StatusWndMsg(hUIWnd, fFalse);
|
|
break;
|
|
|
|
case IMN_SETSTATUSWINDOWPOS:
|
|
Dbg(DBGID_UI, TEXT("NotifyUI(): IMN_SETSTATUSWINDOWPOS"));
|
|
if (!IsCicero())
|
|
{
|
|
fSetStatusWindowPos(GetStatusWnd(hUIWnd), NULL);
|
|
fSetCompWindowPos(GetCompWnd(hUIWnd));
|
|
}
|
|
break;
|
|
|
|
// IMN_SETCOMPOSITIONWINDOW called for all user key press
|
|
case IMN_SETCOMPOSITIONWINDOW:
|
|
hWnd = GetCompWnd(hUIWnd);
|
|
if (hWnd)
|
|
fSetCompWindowPos(hWnd);
|
|
break;
|
|
|
|
case IMN_OPENCANDIDATE:
|
|
Dbg(DBGID_UI, TEXT(" - IMN_OPENCANDIDATE"));
|
|
OpenCand(hUIWnd);
|
|
break;
|
|
|
|
case IMN_CLOSECANDIDATE:
|
|
Dbg(DBGID_UI, TEXT(" - IMN_CLOSECANDIDATE"));
|
|
if (lParam & 0x00000001)
|
|
{
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (hUIPrivate && (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)))
|
|
{
|
|
if (lpUIPrivate->hCandWnd)
|
|
{
|
|
ShowCand(hUIWnd, SW_HIDE);
|
|
DestroyWindow(lpUIPrivate->hCandWnd);
|
|
lpUIPrivate->hCandWnd = 0;
|
|
}
|
|
|
|
if (lpUIPrivate->hCandTTWnd)
|
|
{
|
|
DestroyWindow(lpUIPrivate->hCandTTWnd);
|
|
lpUIPrivate->hCandTTWnd = 0;
|
|
}
|
|
GlobalUnlock(hUIPrivate);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IMN_SETCANDIDATEPOS:
|
|
hWnd = GetCandWnd(hUIWnd);
|
|
if (hWnd)
|
|
fSetCandWindowPos(hWnd);
|
|
break;
|
|
|
|
case IMN_CHANGECANDIDATE:
|
|
Dbg(DBGID_UI, TEXT(" - Redraw cand window"));
|
|
hWnd = GetCandWnd(hUIWnd);
|
|
//RedrawWindow(hStatusWnd, &ImeData->rcButtonArea, NULL, RDW_INVALIDATE);
|
|
InvalidateRect(hWnd, NULL, fFalse);
|
|
break;
|
|
|
|
case IMN_SETOPENSTATUS:
|
|
SetIndicator(GethImcFromHwnd(hUIWnd));
|
|
break;
|
|
|
|
case IMN_SETCONVERSIONMODE:
|
|
hWnd = GetStatusWnd(hUIWnd);
|
|
if (hWnd)
|
|
{
|
|
CIMEData ImeData(CIMEData::SMReadWrite);
|
|
Dbg(DBGID_UI, TEXT(" - Redraw status window"));
|
|
//RedrawWindow(hWnd, &ImeData->rcButtonArea, NULL, RDW_INVALIDATE);
|
|
InvalidateRect(hWnd, &ImeData->rcButtonArea, fFalse);
|
|
}
|
|
SetIndicator(GethImcFromHwnd(hUIWnd));
|
|
|
|
// Update Cicero buttons
|
|
if (IsCicero() && (hUIPrivate = GethUIPrivateFromHwnd(hUIWnd)) &&
|
|
(lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)) != NULL)
|
|
{
|
|
lpUIPrivate->m_pCicToolbar->Update(UPDTTB_CMODE|UPDTTB_FHMODE);
|
|
GlobalUnlock(hUIPrivate);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Dbg(DBGID_UI, TEXT("NotifyUI(): Unhandled IMN = 0x%04X"), wParam);
|
|
lRet = fTrue;
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Called when IMN_OPENSTATUSWINDOW/IMN_CLOSESTATUSWINDOW occurs
|
|
// set the show hide state and
|
|
// show/hide the status window
|
|
void PASCAL StatusWndMsg(HWND hUIWnd, BOOL fOn)
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
HIMC hIMC;
|
|
register LPUIPRIV lpUIPrivate;
|
|
|
|
Dbg(DBGID_UI, TEXT("StatusWndMsg(): hUIWnd = 0x%X, fOn = %d"), hUIWnd, fOn);
|
|
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
|
|
if (!hUIPrivate)
|
|
{
|
|
DbgAssert(0);
|
|
return;
|
|
}
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
if (!lpUIPrivate)
|
|
{
|
|
DbgAssert(0);
|
|
return;
|
|
}
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
|
|
// if Cicero enabled, Init/Terminate Cicero toolbar.
|
|
// Office 10 #249973: I moved init position to here from OnImeSetContext.
|
|
// But make sure all user's "HKEY_CURRENT_USER\Control Panel\Input Method\Show Status" shuold be "1"
|
|
// Setup will do this by enumerating HKEY_USERS
|
|
if (IsCicero())
|
|
{
|
|
if (fOn)
|
|
{
|
|
if (lpUIPrivate->m_pCicToolbar)
|
|
lpUIPrivate->m_pCicToolbar->Initialize();
|
|
}
|
|
else
|
|
{
|
|
if (lpUIPrivate->m_pCicToolbar)
|
|
lpUIPrivate->m_pCicToolbar->Terminate();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (fOn)
|
|
{
|
|
InitButtonState(); // b#159
|
|
OpenStatus(hUIWnd);
|
|
}
|
|
|
|
if (lpUIPrivate->hStatusWnd == 0)
|
|
{
|
|
Dbg(DBGID_UI, TEXT("StatusWndMsg(): Null Status window handle"));
|
|
GlobalUnlock(hUIPrivate);
|
|
return;
|
|
}
|
|
|
|
if (fOn)
|
|
{
|
|
if (hIMC)
|
|
ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
|
|
else
|
|
{
|
|
ShowStatus(hUIWnd, SW_HIDE);
|
|
Dbg(DBGID_UI, TEXT("StatusWndMsg(): hIMC == 0, Call ShowStatus(HIDE)"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DestroyWindow(lpUIPrivate->hStatusWnd);
|
|
Dbg(DBGID_UI, TEXT("StatusWndMsg(): Call ShowStatus(HIDE)"));
|
|
}
|
|
}
|
|
// Unlock UI private handle
|
|
GlobalUnlock(hUIPrivate);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
OnUIProcessAttach
|
|
----------------------------------------------------------------------------*/
|
|
BOOL OnUIProcessAttach()
|
|
{
|
|
DbgAssert(vdwTLSIndex == UNDEF_TLSINDEX);
|
|
if (vdwTLSIndex == UNDEF_TLSINDEX)
|
|
{
|
|
vdwTLSIndex = ::TlsAlloc(); //Get new TLS index.
|
|
if (vdwTLSIndex == UNDEF_TLSINDEX)
|
|
{
|
|
Dbg(DBGID_UI, "-->SetActiveUIWnd ::TlsAlloc Error ret [%d]\n", GetLastError());
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
OnUIProcessDetach
|
|
----------------------------------------------------------------------------*/
|
|
BOOL OnUIProcessDetach()
|
|
{
|
|
if (TlsFree(vdwTLSIndex) == 0)
|
|
{
|
|
Dbg(DBGID_UI, "-->::TlsFree Error [%d]\n", GetLastError());
|
|
return fFalse;
|
|
}
|
|
vdwTLSIndex = UNDEF_TLSINDEX;
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
OnUIThreadDetach
|
|
----------------------------------------------------------------------------*/
|
|
BOOL OnUIThreadDetach()
|
|
{
|
|
if (vdwTLSIndex != UNDEF_TLSINDEX)
|
|
TlsSetValue(vdwTLSIndex, NULL);
|
|
|
|
return fTrue;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
SetActiveUIWnd
|
|
|
|
Save current Active UI wnd handle to TLS
|
|
----------------------------------------------------------------------------*/
|
|
VOID SetActiveUIWnd(HWND hWnd)
|
|
{
|
|
Dbg(DBGID_UI, "SetActiveUIWnd(hWnd=%lx) \r\n", hWnd);
|
|
|
|
if (IsWin(hWnd) == fFalse)
|
|
{
|
|
Dbg(DBGID_UI, "SetActiveUIWnd( hWnd=%lx ) - no window\r\n", hWnd );
|
|
return;
|
|
}
|
|
|
|
if (TlsSetValue(vdwTLSIndex, (LPVOID)hWnd) == 0)
|
|
{
|
|
Dbg(DBGID_UI, "-->LoadCImePadSvr() TlsSetValue Failed [%d]\n", GetLastError());
|
|
TlsSetValue(vdwTLSIndex, NULL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
GetActiveUIWnd
|
|
|
|
Retrieve current Active UI wnd handle from TLS
|
|
----------------------------------------------------------------------------*/
|
|
HWND GetActiveUIWnd()
|
|
{
|
|
return (HWND)TlsGetValue(vdwTLSIndex);
|
|
}
|
|
|
|
// Called by OnImeSetContext() and OnImeSelect()
|
|
void PASCAL ShowUI(HWND hUIWnd, int nShowCmd)
|
|
{
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
|
|
Dbg(DBGID_UI, TEXT("ShowUI() : nShowCmd=%d"), nShowCmd);
|
|
|
|
#if 0
|
|
if (nShowCmd != SW_HIDE)
|
|
{
|
|
// Check if hIMC and hPrivate is valid
|
|
// If not valid hide all UI windows.
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
lpIMC = (LPINPUTCONTEXT)OurImmLockIMC(hIMC);
|
|
lpImcP = (LPIMCPRIVATE)GetPrivateBuffer(hIMC);
|
|
|
|
if (!(hIMC && lpIMC && lpImcP))
|
|
nShowCmd = SW_HIDE;
|
|
}
|
|
#else
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
nShowCmd = SW_HIDE;
|
|
#endif
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Lock hUIPrivate
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
|
|
// can not draw status window
|
|
if (!hUIPrivate)
|
|
return;
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
// can not draw status window
|
|
if (!lpUIPrivate)
|
|
return;
|
|
|
|
// Hide all UI window and return immediately
|
|
if (nShowCmd == SW_HIDE)
|
|
{
|
|
Dbg(DBGID_UI, TEXT("ShowUI() : hiding all UI"));
|
|
ShowStatus(hUIWnd, SW_HIDE);
|
|
ShowComp(hUIWnd, SW_HIDE);
|
|
ShowCand(hUIWnd, SW_HIDE);
|
|
|
|
// FIXED : if (nShowCmd == SW_HIDE) hIMC and lpIMC->hPrivate not Locked
|
|
// So you need not Unlock
|
|
goto ShowUIUnlockUIPrivate;
|
|
}
|
|
|
|
//////////////////
|
|
// Status window
|
|
if (lpUIPrivate->hStatusWnd)
|
|
{
|
|
// if currently hide, show it.
|
|
if (lpUIPrivate->nShowStatusCmd == SW_HIDE)
|
|
ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
|
|
else
|
|
{
|
|
// sometime the WM_ERASEBKGND is eaten by the app
|
|
RedrawWindow(lpUIPrivate->hStatusWnd, NULL, NULL,
|
|
RDW_FRAME|RDW_INVALIDATE/*|RDW_ERASE*/);
|
|
}
|
|
}
|
|
/*
|
|
//////////////////////
|
|
// Composition window
|
|
if (lpUIPrivate->hCompWnd)
|
|
{
|
|
if (lpUIPrivate->nShowCompCmd == SW_HIDE)
|
|
ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
|
|
else
|
|
{
|
|
// sometime the WM_ERASEBKGND is eaten by the app
|
|
RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL,
|
|
RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
|
|
}
|
|
}
|
|
|
|
////////////////////
|
|
// Candidate window
|
|
if (lpUIPrivate->hCandWnd)
|
|
{
|
|
if (lpUIPrivate->nShowCandCmd == SW_HIDE)
|
|
ShowCand(hUIWnd, SW_SHOWNOACTIVATE);
|
|
else
|
|
{
|
|
// some time the WM_ERASEBKGND is eaten by the app
|
|
RedrawWindow(lpUIPrivate->hCandWnd, NULL, NULL,
|
|
RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
|
|
}
|
|
|
|
fSetCandWindowPos(lpUIPrivate->hCandWnd);
|
|
}
|
|
*/
|
|
ShowUIUnlockUIPrivate:
|
|
GlobalUnlock(hUIPrivate);
|
|
return;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// WM_IME_SETCONTEXT sent whenever user activated/deactivated a window
|
|
void PASCAL OnImeSetContext(HWND hUIWnd, BOOL fOn, LPARAM lShowUI)
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HWND hwndIndicator = FindWindow(INDICATOR_CLASS, NULL);
|
|
HIMC hIMC = NULL;
|
|
PCIMECtx pImeCtx;
|
|
|
|
Dbg(DBGID_UI, TEXT("OnImeSetContext(): hUIWnd = 0x%X fOn = %d"), hUIWnd, fOn);
|
|
|
|
// Get UI private memory
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (hUIPrivate == 0 || (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)) == 0)
|
|
{
|
|
ShowUI(hUIWnd, SW_HIDE);
|
|
// Set disabled Pen Icon
|
|
if (fOn)
|
|
SetIndicator((PCIMECtx)NULL);
|
|
goto LOnImeSetContextExit;
|
|
}
|
|
|
|
// Init Cicero service
|
|
CiceroInitialize();
|
|
|
|
// If Cicero enabled, init toolbar
|
|
if (IsCicero())
|
|
{
|
|
// Create Toolbar object and store it to private memory
|
|
if (lpUIPrivate->m_pCicToolbar == NULL)
|
|
lpUIPrivate->m_pCicToolbar = new CToolBar();
|
|
|
|
DbgAssert(lpUIPrivate->m_pCicToolbar != NULL);
|
|
}
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
{
|
|
ShowUI(hUIWnd, SW_HIDE);
|
|
// Set disabled Pen Icon
|
|
if (fOn)
|
|
SetIndicator((PCIMECtx)NULL);
|
|
|
|
// Disable cicero buttons
|
|
if (IsCicero() && lpUIPrivate->m_pCicToolbar)
|
|
lpUIPrivate->m_pCicToolbar->SetCurrentIC(NULL);
|
|
|
|
goto LOnImeSetContextExit2;
|
|
}
|
|
|
|
if (fOn)
|
|
{
|
|
// Store UI Window handle to TLS
|
|
SetActiveUIWnd(hUIWnd);
|
|
|
|
// Keep lParam
|
|
lpUIPrivate->uiShowParam = lShowUI;
|
|
|
|
if (pImeCtx->GetCandidateFormIndex(0) != 0)
|
|
pImeCtx->SetCandidateFormIndex(CFS_DEFAULT, 0);
|
|
|
|
// Remove right Help menu item on Pen Icon
|
|
if (hwndIndicator)
|
|
{
|
|
PostMessage(hwndIndicator,
|
|
INDICM_REMOVEDEFAULTMENUITEMS ,
|
|
RDMI_RIGHT,
|
|
(LPARAM)GetKeyboardLayout(NULL));
|
|
// Set Pen Icon
|
|
SetIndicator(pImeCtx);
|
|
}
|
|
|
|
// For display Status window.
|
|
ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
|
|
|
|
if (IsCicero() && lpUIPrivate->m_pCicToolbar)
|
|
lpUIPrivate->m_pCicToolbar->SetCurrentIC(pImeCtx);
|
|
}
|
|
|
|
LOnImeSetContextExit2:
|
|
GlobalUnlock(hUIPrivate);
|
|
|
|
LOnImeSetContextExit:
|
|
LPCImePadSvr lpCImePadSvr = CImePadSvr::GetCImePadSvr();
|
|
if(lpCImePadSvr)
|
|
{
|
|
BOOL fAct = (BOOL)(fOn && hIMC);
|
|
if (fAct)
|
|
{
|
|
IImeIPoint1* pIP = GetImeIPoint(hIMC);
|
|
//HWND hWnd = GetStatusWnd(hUIWnd);
|
|
|
|
//ImePadSetCurrentIPoint(hWnd, pIp);
|
|
lpCImePadSvr->SetIUnkIImeIPoint((IUnknown *)pIP);
|
|
//UpdatePadButton(pUI->GetWnd());
|
|
// Don't need to repaint. StatusOnPaint will do it
|
|
//if (hWnd)
|
|
// InvalidateRect(hWnd, NULL, fFalse);
|
|
}
|
|
lpCImePadSvr->Notify(IMEPADNOTIFY_ACTIVATECONTEXT, fAct, 0);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// WM_IME_SELECT sent when user change IME
|
|
void PASCAL OnImeSelect(HWND hUIWnd, BOOL fOn)
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HWND hwndIndicator = FindWindow(INDICATOR_CLASS, NULL);
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
|
|
Dbg(DBGID_UI, TEXT("OnImeSelect(): hUIWnd = 0x%Xm fOn = %d"), hUIWnd, fOn);
|
|
|
|
// Get UI private memory
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (hUIPrivate == 0 || (lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate)) == 0)
|
|
{
|
|
ShowUI(hUIWnd, SW_HIDE);
|
|
// Set disabled Pen Icon
|
|
SetIndicator((PCIMECtx)NULL);
|
|
return;
|
|
}
|
|
|
|
// Init Cicero service
|
|
CiceroInitialize();
|
|
|
|
// If Cicero enabled, init toolbar
|
|
if (IsCicero())
|
|
{
|
|
// Create Toolbar object and store it to private memory
|
|
if (lpUIPrivate->m_pCicToolbar == NULL)
|
|
lpUIPrivate->m_pCicToolbar = new CToolBar();
|
|
|
|
DbgAssert(lpUIPrivate->m_pCicToolbar != NULL);
|
|
}
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
{
|
|
ShowUI(hUIWnd, SW_HIDE);
|
|
// Set disabled Pen Icon
|
|
SetIndicator((PCIMECtx)NULL);
|
|
|
|
// Disable cicero buttons
|
|
if (IsCicero() && lpUIPrivate->m_pCicToolbar)
|
|
lpUIPrivate->m_pCicToolbar->SetCurrentIC(NULL);
|
|
|
|
return;
|
|
}
|
|
|
|
if (fOn)
|
|
{
|
|
// Store UI Window handle to TLS. Sometimes when user switch IME only WM_IME_SELECT sent. No WM_IME_SETCONTEXT msg.
|
|
SetActiveUIWnd(hUIWnd);
|
|
|
|
if (pImeCtx->GetCandidateFormIndex(0) != 0)
|
|
pImeCtx->SetCandidateFormIndex(CFS_DEFAULT, 0);
|
|
|
|
// Remove right Help menu item on Pen Icon
|
|
if (hwndIndicator)
|
|
{
|
|
Dbg(DBGID_UI, TEXT("OnImeSelect(): Post indicator message"), hUIWnd, fOn);
|
|
|
|
PostMessage(hwndIndicator,
|
|
INDICM_REMOVEDEFAULTMENUITEMS ,
|
|
RDMI_RIGHT,
|
|
(LPARAM)GetKeyboardLayout(NULL));
|
|
// Set Pen Icon
|
|
SetIndicator(pImeCtx);
|
|
}
|
|
|
|
// If Cicero enabled, init toolbar
|
|
if (IsCicero() && lpUIPrivate->m_pCicToolbar)
|
|
lpUIPrivate->m_pCicToolbar->SetCurrentIC(pImeCtx);
|
|
}
|
|
|
|
|
|
// IME PAD
|
|
LPCImePadSvr lpCImePadSvr = CImePadSvr::GetCImePadSvr();
|
|
if(lpCImePadSvr)
|
|
{
|
|
BOOL fAct = (BOOL)(fOn && hIMC);
|
|
if (fAct)
|
|
{
|
|
IImeIPoint1* pIP = GetImeIPoint(hIMC);
|
|
lpCImePadSvr->SetIUnkIImeIPoint((IUnknown *)pIP);
|
|
}
|
|
lpCImePadSvr->Notify(IMEPADNOTIFY_ACTIVATECONTEXT, fAct, 0);
|
|
}
|
|
|
|
// Close input sontext here
|
|
// Because ImeSelect has not called from IMM on WIN95.
|
|
if (fOn == fFalse)
|
|
{
|
|
DWORD dwCMode = 0, dwSent = 0;
|
|
|
|
// If Hanja conversion mode when uninit, cancel it.
|
|
OurImmGetConversionStatus(hIMC, &dwCMode, &dwSent);
|
|
if (dwCMode & IME_CMODE_HANJACONVERT)
|
|
OurImmSetConversionStatus(hIMC, dwCMode & ~IME_CMODE_HANJACONVERT, dwSent);
|
|
|
|
// if interim state, make complete current comp string
|
|
// But IMM sends CPS_CANCEL when user change layout
|
|
if (pImeCtx->GetCompBufLen())
|
|
{
|
|
pImeCtx->FinalizeCurCompositionChar();
|
|
pImeCtx->GenerateMessage();
|
|
}
|
|
|
|
CloseInputContext(hIMC);
|
|
}
|
|
|
|
GlobalUnlock(hUIPrivate);
|
|
}
|
|
|
|
HWND PASCAL GetStatusWnd(HWND hUIWnd)
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HWND hStatusWnd;
|
|
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (!hUIPrivate) // can not darw status window
|
|
return (HWND)NULL;
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
if (!lpUIPrivate) // can not draw status window
|
|
return (HWND)NULL;
|
|
|
|
hStatusWnd = lpUIPrivate->hStatusWnd;
|
|
|
|
GlobalUnlock(hUIPrivate);
|
|
return (hStatusWnd);
|
|
}
|
|
|
|
HWND PASCAL GetCandWnd(HWND hUIWnd) // UI window
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HWND hCandWnd;
|
|
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (!hUIPrivate) // can not darw candidate window
|
|
return (HWND)NULL;
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
if (!lpUIPrivate) // can not draw candidate window
|
|
return (HWND)NULL;
|
|
|
|
hCandWnd = lpUIPrivate->hCandWnd;
|
|
|
|
GlobalUnlock(hUIPrivate);
|
|
return (hCandWnd);
|
|
}
|
|
|
|
HWND PASCAL GetCompWnd(HWND hUIWnd) // UI window
|
|
{
|
|
HGLOBAL hUIPrivate;
|
|
LPUIPRIV lpUIPrivate;
|
|
HWND hCompWnd;
|
|
|
|
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
|
|
if (!hUIPrivate) // can not draw comp window
|
|
return (HWND)NULL;
|
|
|
|
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
|
|
if (!lpUIPrivate) // can not draw comp window
|
|
return (HWND)NULL;
|
|
|
|
hCompWnd = lpUIPrivate->hCompWnd;
|
|
GlobalUnlock(hUIPrivate);
|
|
|
|
return (hCompWnd);
|
|
}
|
|
|
|
LRESULT PASCAL GetCandPos(HWND hUIWnd, LPCANDIDATEFORM lpCandForm)
|
|
{
|
|
HWND hCandWnd;
|
|
RECT rcCandWnd;
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
|
|
if (lpCandForm->dwIndex != 0)
|
|
return (1L);
|
|
|
|
hCandWnd = GetCandWnd(hUIWnd);
|
|
|
|
if (!hCandWnd)
|
|
return (1L);
|
|
|
|
if (!GetWindowRect(hCandWnd, &rcCandWnd))
|
|
return (1L);
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
return (1L);
|
|
|
|
//*lpCandForm = lpIMC->cfCandForm[0];
|
|
lpCandForm->dwIndex = pImeCtx->GetCandidateFormIndex(0);
|
|
lpCandForm->dwStyle = pImeCtx->GetCandidateFormStyle(0);
|
|
pImeCtx->GetCandidateForm(&lpCandForm->rcArea, 0);
|
|
lpCandForm->ptCurrentPos = *(LPPOINT)&rcCandWnd;
|
|
|
|
return (0L);
|
|
}
|
|
|
|
LRESULT PASCAL GetCompPos(HWND hUIWnd, LPCOMPOSITIONFORM lpCompForm)
|
|
{
|
|
HWND hCompWnd;
|
|
RECT rcCompWnd;
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
|
|
hCompWnd = GetCompWnd(hUIWnd);
|
|
|
|
if (!hCompWnd)
|
|
return (1L);
|
|
|
|
if (!GetWindowRect(hCompWnd, &rcCompWnd))
|
|
return (1L);
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
return (1L);
|
|
|
|
lpCompForm->dwStyle = pImeCtx->GetCompositionFormStyle();
|
|
pImeCtx->GetCompositionForm(&lpCompForm->ptCurrentPos);
|
|
pImeCtx->GetCompositionForm(&lpCompForm->rcArea);
|
|
|
|
return (0L);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Popup menu message handler
|
|
void PASCAL UIWndOnCommand(HWND hUIWnd, INT id, HWND hWndCtl, UINT codeNotify)
|
|
{
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
CHAR szBuffer[256];
|
|
CIMEData ImeData(CIMEData::SMReadWrite);
|
|
|
|
szBuffer[0] = '\0';
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
return;
|
|
|
|
switch (id)
|
|
{
|
|
case ID_CONFIG:
|
|
ImeConfigure(0, pImeCtx->GetAppWnd(), IME_CONFIG_GENERAL, NULL);
|
|
break;
|
|
|
|
case ID_ABOUT:
|
|
OurLoadStringA(vpInstData->hInst, IDS_PROGRAM, szBuffer, sizeof(szBuffer));
|
|
ShellAbout(pImeCtx->GetAppWnd(), szBuffer, NULL, (HICON)LoadImage((HINSTANCE)vpInstData->hInst,
|
|
MAKEINTRESOURCE(IDI_UNIKOR), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR));
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// IME internal Keyboard layout change message
|
|
case ID_2BEOLSIK:
|
|
case ID_3BEOLSIK390:
|
|
case ID_3BEOLSIKFINAL :
|
|
if (ImeData.GetCurrentBeolsik() != (UINT)(id - ID_2BEOLSIK))
|
|
{
|
|
if (pImeCtx->GetAutomata())
|
|
pImeCtx->GetAutomata()->InitState();
|
|
|
|
if (pImeCtx->GetGData())
|
|
pImeCtx->GetGData()->SetCurrentBeolsik(id - ID_2BEOLSIK);
|
|
|
|
if (pImeCtx->GetAutomata())
|
|
pImeCtx->GetAutomata()->InitState();
|
|
|
|
SetRegValues(GETSET_REG_IMEKL);
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Han/Eng Toggle
|
|
case ID_HANGUL_MODE :
|
|
if (!(pImeCtx->GetConversionMode() & IME_CMODE_HANGUL))
|
|
{
|
|
OurImmSetConversionStatus(hIMC,
|
|
pImeCtx->GetConversionMode() ^ IME_CMODE_HANGUL,
|
|
pImeCtx->GetSentenceMode());
|
|
}
|
|
break;
|
|
|
|
case ID_ENGLISH_MODE :
|
|
if (pImeCtx->GetConversionMode() & IME_CMODE_HANGUL)
|
|
{
|
|
OurImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
|
|
OurImmSetConversionStatus(hIMC,
|
|
pImeCtx->GetConversionMode() ^ IME_CMODE_HANGUL,
|
|
pImeCtx->GetSentenceMode());
|
|
}
|
|
break;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Hangul deletion per jaso or char.
|
|
case ID_JASO_DELETION:
|
|
ImeData.SetJasoDel(!ImeData.GetJasoDel());
|
|
SetRegValues(GETSET_REG_JASODEL);
|
|
break;
|
|
|
|
default :
|
|
Dbg(DBGID_UI, TEXT("UIWndOnCommand() - Unknown command"));
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void UIPopupMenu(HWND hUIWnd)
|
|
{
|
|
HMENU hMenu, hPopupMenu;
|
|
POINT ptCurrent;
|
|
UINT uiCurSel;
|
|
HIMC hIMC;
|
|
PCIMECtx pImeCtx;
|
|
CIMEData ImeData;
|
|
|
|
hIMC = GethImcFromHwnd(hUIWnd);
|
|
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
|
|
return;
|
|
|
|
GetCursorPos(&ptCurrent);
|
|
hMenu = OurLoadMenu(vpInstData->hInst, MAKEINTRESOURCE(IDR_STATUS_POPUP));
|
|
if (hMenu != NULL)
|
|
{
|
|
hPopupMenu = GetSubMenu(hMenu, 0);
|
|
if (hPopupMenu == NULL)
|
|
{
|
|
DestroyMenu(hMenu);
|
|
return;
|
|
}
|
|
|
|
// Keyboard type selection radio button
|
|
uiCurSel = ID_2BEOLSIK + ImeData.GetCurrentBeolsik();
|
|
CheckMenuRadioItem(hPopupMenu, ID_2BEOLSIK, ID_3BEOLSIKFINAL, uiCurSel, MF_BYCOMMAND);
|
|
|
|
// Han/Eng mode selection radio button
|
|
uiCurSel = ID_HANGUL_MODE + ((pImeCtx->GetConversionMode() & IME_CMODE_HANGUL) ? 0 : 1);
|
|
CheckMenuRadioItem(hPopupMenu, ID_HANGUL_MODE, ID_ENGLISH_MODE, uiCurSel, MF_BYCOMMAND);
|
|
|
|
// Hangul jaso deletion
|
|
if (ImeData.GetJasoDel())
|
|
CheckMenuItem(hPopupMenu, ID_JASO_DELETION, MF_BYCOMMAND | MF_CHECKED);
|
|
else
|
|
CheckMenuItem(hPopupMenu, ID_JASO_DELETION, MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
|
// if Winlogon process, gray all config menu
|
|
if (vpInstData->dwSystemInfoFlags & IME_SYSINFO_WINLOGON)
|
|
{
|
|
EnableMenuItem(hPopupMenu, ID_CONFIG, MF_BYCOMMAND | MF_GRAYED);
|
|
EnableMenuItem(hPopupMenu, ID_2BEOLSIK, MF_BYCOMMAND | MF_GRAYED);
|
|
EnableMenuItem(hPopupMenu, ID_3BEOLSIK390, MF_BYCOMMAND | MF_GRAYED);
|
|
EnableMenuItem(hPopupMenu, ID_3BEOLSIKFINAL, MF_BYCOMMAND | MF_GRAYED);
|
|
EnableMenuItem(hPopupMenu, ID_JASO_DELETION, MF_BYCOMMAND | MF_GRAYED);
|
|
}
|
|
TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
|
|
ptCurrent.x, ptCurrent.y, 0, hUIWnd, NULL);
|
|
DestroyMenu(hMenu);
|
|
}
|
|
}
|
|
|
|
BOOL PASCAL SetIndicator(PCIMECtx pImeCtx)
|
|
{
|
|
ATOM atomIndicator;
|
|
CHAR sztooltip[IMEMENUITEM_STRING_SIZE];
|
|
int nIconIndex;
|
|
HWND hwndIndicator;
|
|
|
|
Dbg(DBGID_Tray, TEXT("SetIndicator Enter"));
|
|
hwndIndicator = FindWindow(INDICATOR_CLASS, NULL);
|
|
|
|
if (!hwndIndicator)
|
|
{
|
|
Dbg(DBGID_Tray, TEXT("!!! WARNING !!!: Indicator window not found"));
|
|
return fFalse;
|
|
}
|
|
|
|
// init sztooltip
|
|
sztooltip[0] = 0;
|
|
|
|
// Default value is disabled.
|
|
OurLoadStringA(vpInstData->hInst, IDS_IME_TT_DISABLE, sztooltip, IMEMENUITEM_STRING_SIZE);
|
|
nIconIndex = 5;
|
|
|
|
if (pImeCtx)
|
|
{
|
|
// If IME closed, English half mode
|
|
if (pImeCtx->IsOpen() == fFalse)
|
|
{
|
|
OurLoadStringA(vpInstData->hInst, IDS_IME_TT_ENG_HALF, sztooltip, IMEMENUITEM_STRING_SIZE);
|
|
nIconIndex= 3;
|
|
}
|
|
else
|
|
{
|
|
// If Hangul mode
|
|
if (pImeCtx->GetConversionMode() & IME_CMODE_HANGUL)
|
|
{
|
|
if (pImeCtx->GetConversionMode() & IME_CMODE_FULLSHAPE)
|
|
{
|
|
OurLoadStringA(vpInstData->hInst, IDS_IME_TT_HANGUL_FULL, sztooltip, IMEMENUITEM_STRING_SIZE);
|
|
nIconIndex = 4;
|
|
}
|
|
else
|
|
{
|
|
OurLoadStringA(vpInstData->hInst, IDS_IME_TT_HANGUL_HALF, sztooltip, IMEMENUITEM_STRING_SIZE);
|
|
nIconIndex = 1;
|
|
}
|
|
}
|
|
else
|
|
// Non-Hangul mode
|
|
if (pImeCtx->GetConversionMode() & IME_CMODE_FULLSHAPE)
|
|
{
|
|
OurLoadStringA(vpInstData->hInst, IDS_IME_TT_ENG_FULL, sztooltip, IMEMENUITEM_STRING_SIZE);
|
|
nIconIndex = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
Dbg(DBGID_Tray, TEXT("SetIndicator: PostMessage: nIconIndex=%d"), nIconIndex);
|
|
PostMessage(hwndIndicator, INDICM_SETIMEICON, nIconIndex, (LPARAM)GetKeyboardLayout(NULL));
|
|
|
|
// Should use GlobalFindAtom b#57121
|
|
atomIndicator = GlobalFindAtom(sztooltip);
|
|
// If no global atom exist, add it
|
|
if (!atomIndicator)
|
|
atomIndicator = GlobalAddAtom(sztooltip);
|
|
|
|
DbgAssert(atomIndicator);
|
|
|
|
if (atomIndicator)
|
|
{
|
|
Dbg(DBGID_Tray, TEXT("SetIndicator: PostMessage: atomIndicator=%s"), sztooltip);
|
|
PostMessage(hwndIndicator, INDICM_SETIMETOOLTIPS, atomIndicator, (LPARAM)GetKeyboardLayout(NULL));
|
|
}
|
|
|
|
return fTrue;;
|
|
}
|