|
|
/*************************************************
* ui.c * * * * Copyright (C) 1999 Microsoft Inc. * * * *************************************************/
#include <windows.h>
#include <immdev.h>
#include "imeattr.h"
#include "imedefs.h"
/**********************************************************************/ /* CreateUIWindow() */ /**********************************************************************/ void PASCAL CreateUIWindow( // create composition window
HWND hUIWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate;
// create storage for UI setting
hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV)); if (!hUIPrivate) { // Oh! Oh!
return; }
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);
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw candidate window
return; }
GlobalUnlock(hUIPrivate);
return; }
/**********************************************************************/ /* DestroyUIWindow() */ /**********************************************************************/ void PASCAL DestroyUIWindow( // destroy composition window
HWND hUIWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { // Oh! Oh!
return; }
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // Oh! Oh!
return; }
// composition window need to be destroyed
if (lpUIPrivate->hCompWnd) { DestroyWindow(lpUIPrivate->hCompWnd); }
GlobalUnlock(hUIPrivate);
// free storage for UI settings
GlobalFree(hUIPrivate);
return; }
/**********************************************************************/ /* ShowUI() */ /**********************************************************************/ void PASCAL ShowUI( // show the sub windows
HWND hUIWnd, int nShowCmd) { HIMC hIMC; LPINPUTCONTEXT lpIMC; LPPRIVCONTEXT lpImcP; HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate;
if (nShowCmd == SW_HIDE) { } else if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))) { nShowCmd = SW_HIDE; } else if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) { nShowCmd = SW_HIDE; } else if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) { ImmUnlockIMC(hIMC); nShowCmd = SW_HIDE; } else { }
if (nShowCmd == SW_HIDE) {
ShowComp(hUIWnd, nShowCmd); return; }
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { // can not darw status window
goto ShowUIUnlockIMCC; }
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw status window
goto ShowUIUnlockIMCC; }
if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW) #if 0
&& (lpImcP->fdwImeMsg & MSG_ALREADY_START) #endif
) { if (lpUIPrivate->hCompWnd) { if ((UINT)GetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_XY) != lpImeL->nRevMaxKey) { ChangeCompositionSize(hUIWnd); }
if (lpUIPrivate->nShowCompCmd != SW_HIDE) { // some time the WM_ERASEBKGND is eaten by the app
RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_ERASE); }
SendMessage(lpUIPrivate->hCompWnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONWINDOW, 0);
if (lpUIPrivate->nShowCompCmd == SW_HIDE) { ShowComp(hUIWnd, nShowCmd); } } else { CreateCompWindow(hUIWnd); } } else if (lpUIPrivate->nShowCompCmd == SW_HIDE) { } else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) { // delay the hide with status window
lpUIPrivate->fdwSetContext |= ISC_HIDE_COMP_WINDOW; } else { ShowComp(hUIWnd, SW_HIDE); }
if (lpIMC->fdwInit & INIT_SENTENCE) { // app set the sentence mode so we should not change it
// with the configure option set by end user
} else if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) { if (!(lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT)) { DWORD fdwSentence;
fdwSentence = lpIMC->fdwSentence; *(LPWORD)&fdwSentence |= IME_SMODE_PHRASEPREDICT;
ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence); } } else { if (lpIMC->fdwSentence & IME_SMODE_PHRASEPREDICT) { DWORD fdwSentence;
fdwSentence = lpIMC->fdwSentence; *(LPWORD)&fdwSentence &= ~(IME_SMODE_PHRASEPREDICT);
ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence); } }
// we switch to this hIMC
lpUIPrivate->hCacheIMC = hIMC;
GlobalUnlock(hUIPrivate);
ShowUIUnlockIMCC: ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMC(hIMC);
return; }
/**********************************************************************/ /* NotifyUI() */ /**********************************************************************/ void PASCAL NotifyUI( HWND hUIWnd, WPARAM wParam, LPARAM lParam) { HWND hStatusWnd;
switch (wParam) { case IMN_SETSENTENCEMODE: break; case IMN_SETCOMPOSITIONFONT: // we are not going to change font, but an IME can do this if it want
break; case IMN_SETCOMPOSITIONWINDOW:
// if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI))
{ HWND hCompWnd;
hCompWnd = GetCompWnd(hUIWnd); if (!hCompWnd) { return; }
PostMessage(hCompWnd, WM_IME_NOTIFY, wParam, lParam); } break; case IMN_PRIVATE: switch (lParam) { case IMN_PRIVATE_COMPOSITION_SIZE: ChangeCompositionSize( hUIWnd); break; default: break; } break; default: break; }
return; }
/**********************************************************************/ /* UIChange() */ /**********************************************************************/ LRESULT PASCAL UIChange( HWND hUIWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { return (0L); }
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { return (0L); }
if (lpUIPrivate->fdwSetContext & ISC_SHOW_UI_ALL) { ShowUI(hUIWnd, SW_SHOWNOACTIVATE); } else { ShowUI(hUIWnd, SW_HIDE); }
GlobalUnlock(hUIPrivate);
return (0L); }
/**********************************************************************/ /* SetContext() */ /**********************************************************************/ void PASCAL SetContext( // the context activated/deactivated
HWND hUIWnd, BOOL fOn, LPARAM lShowUI) { HGLOBAL hUIPrivate;
register LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { return; }
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { return; }
if (fOn) { HIMC hIMC; LPINPUTCONTEXT lpIMC;
register DWORD fdwSetContext;
lpUIPrivate->fdwSetContext = lpUIPrivate->fdwSetContext & ~(ISC_SHOWUIALL|ISC_HIDE_SOFTKBD);
lpUIPrivate->fdwSetContext |= (lShowUI & ISC_SHOWUIALL) | ISC_SHOW_SOFTKBD;
fdwSetContext = lpUIPrivate->fdwSetContext & (ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);
if (fdwSetContext == ISC_HIDE_COMP_WINDOW) { ShowComp( hUIWnd, SW_HIDE); } else if (fdwSetContext & ISC_HIDE_COMP_WINDOW) { lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_COMP_WINDOW); } else { }
fdwSetContext = lpUIPrivate->fdwSetContext & (ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) { goto SetCxtUnlockUIPriv; }
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) { goto SetCxtUnlockUIPriv; }
if (lpIMC->cfCandForm[0].dwIndex != 0) { lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT; }
ImmUnlockIMC(hIMC); } else { lpUIPrivate->fdwSetContext &= ~ISC_SETCONTEXT_UI; }
SetCxtUnlockUIPriv: GlobalUnlock(hUIPrivate);
UIChange( hUIWnd);
return; }
/**********************************************************************/ /* GetCompWindow() */ /**********************************************************************/ LRESULT PASCAL GetCompWindow( HWND hUIWnd, LPCOMPOSITIONFORM lpCompForm) { HWND hCompWnd; RECT rcCompWnd; HIMC hIMC; LPINPUTCONTEXT lpIMC;
hCompWnd = GetCompWnd(hUIWnd);
if (!hCompWnd) { return (1L); }
if (!GetWindowRect(hCompWnd, &rcCompWnd)) { return (1L); }
lpCompForm->dwStyle = CFS_RECT; lpCompForm->ptCurrentPos = *(LPPOINT)&rcCompWnd; lpCompForm->rcArea = rcCompWnd;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) { return (1L); }
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) { return (1L); }
ScreenToClient(lpIMC->hWnd, &lpCompForm->ptCurrentPos);
lpCompForm->rcArea.right += lpCompForm->ptCurrentPos.x - lpCompForm->rcArea.left;
lpCompForm->rcArea.bottom += lpCompForm->ptCurrentPos.y - lpCompForm->rcArea.top;
*(LPPOINT)&lpCompForm->rcArea = lpCompForm->ptCurrentPos;
ImmUnlockIMC(hIMC);
return (0L); }
/**********************************************************************/ /* UIWndProc() / UniUIWndProc() */ /**********************************************************************/ LRESULT CALLBACK UIWndProc( HWND hUIWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: CreateUIWindow(hUIWnd); break; case WM_DESTROY: DestroyUIWindow(hUIWnd); break; case WM_IME_STARTCOMPOSITION: //
// Create a window as the composition window.
//
CreateCompWindow(hUIWnd); break; case WM_IME_COMPOSITION: { HWND hCompWnd; if (lParam & GCS_RESULTSTR) { MoveDefaultCompPosition(hUIWnd); }
hCompWnd = GetCompWnd(hUIWnd);
if (hCompWnd) { RECT rcRect;
rcRect = lpImeL->rcCompText; // off by 1
rcRect.right += 1; rcRect.bottom += 1;
RedrawWindow(hCompWnd, &rcRect, NULL, RDW_INVALIDATE); } break; } case WM_IME_ENDCOMPOSITION: //
// We can destroy the composition window here. But we don't have a
// status window. So we keep the composition window displayed
// to show our presence.
//
return (0L); case WM_IME_NOTIFY: NotifyUI(hUIWnd, wParam, lParam); break; case WM_IME_SETCONTEXT: SetContext(hUIWnd, (BOOL)wParam, lParam); break; case WM_IME_CONTROL: switch (wParam) { case IMC_GETCOMPOSITIONWINDOW: return GetCompWindow(hUIWnd, (LPCOMPOSITIONFORM)lParam); } case WM_IME_COMPOSITIONFULL: return (0L); case WM_IME_SELECT: //
// try to use SetContext
// SelectIME(hUIWnd, (BOOL)wParam);
//
SetContext( hUIWnd, (BOOL)wParam, 0); //
// We want a comp window immediately after IME starts.
//
CreateCompWindow(hUIWnd); return (0L); case WM_MOUSEACTIVATE: return (MA_NOACTIVATE); case WM_USER_UICHANGE: return UIChange( hUIWnd); default: return DefWindowProc(hUIWnd, uMsg, wParam, lParam); } return (0L); }
|