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.
 
 
 
 
 
 

366 lines
12 KiB

/****************************************************************************
COMPUI.CPP
Owner: cslim
Copyright (c) 1997-1999 Microsoft Corporation
Composition window UI functions
History:
14-JUL-1999 cslim Copied from IME98 source tree
*****************************************************************************/
#include "precomp.h"
#include "ui.h"
#include "imedefs.h"
#include "names.h"
#include "escape.h"
#include "winex.h"
#include "cicero.h"
#include "debug.h"
#include "resource.h"
PRIVATE VOID PASCAL PaintCompWindow(HWND hCompWnd, HDC hDC);
///////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK CompWndProc(HWND hCompWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
Dbg(DBGID_UI, TEXT("CompWndProc():uMessage = 0x%08lX, wParam = 0x%04X, lParam = 0x%08lX"), uMessage, wParam, lParam);
switch (uMessage)
{
case WM_IME_CHAR:
case WM_IME_COMPOSITIONFULL:
case WM_IME_COMPOSITION:
case WM_IME_CONTROL:
case WM_IME_SELECT:
case WM_IME_SETCONTEXT:
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
return (0L);
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hCompWnd, &ps);
PaintCompWindow(hCompWnd, hDC);
EndPaint(hCompWnd, &ps);
}
break;
default :
return DefWindowProc(hCompWnd, uMessage, wParam, lParam);
}
return (0L);
}
VOID PASCAL PaintCompWindow(HWND hCompWnd, HDC hDC)
{
HWND hWndUI;
HIMC hIMC;
PCIMECtx pImeCtx;
HFONT hFontFix, hOldFont;
HBITMAP hBMComp;
INT iSaveBkMode;
hWndUI = GetWindow(hCompWnd, GW_OWNER);
hIMC = GethImcFromHwnd(hWndUI);
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
return;
Dbg(DBGID_UI, TEXT("PaintCompWindow():CompCh = 0x%X"), pImeCtx->GetCompBufStr());
if (pImeCtx->GetCompBufLen())
{
// Create font
if (IsWinNT())
hFontFix = CreateFontW(
-16,0,0,0,
0,0,0,0,
HANGUL_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
FIXED_PITCH,
wzIMECompFont);
else
hFontFix = CreateFontA(
-16,0,0,0,
0,0,0,0,
HANGUL_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
FIXED_PITCH,
szIMECompFont);
hOldFont = (HFONT)SelectObject(hDC, hFontFix);
// Draw comp window Bitmap
hBMComp = (HBITMAP)OurLoadImage(MAKEINTRESOURCE(IDB_COMP_WIN), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_LOADMAP3DCOLORS );
DrawBitmap(hDC, 0, 0, hBMComp);
iSaveBkMode = SetBkMode(hDC, TRANSPARENT);
// Set text color
SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
OurTextOutW(hDC, 3, 3, pImeCtx->GetCompBufStr());
// restore and delete created objects
SelectObject(hDC, hOldFont);
SetBkMode(hDC, iSaveBkMode);
DeleteObject(hBMComp);
DeleteObject(hFontFix);
}
}
// open comp window
VOID PASCAL OpenComp(HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HIMC hIMC;
PCIMECtx pImeCtx;
INT nShowCompCmd;
POINT ptClientComp;
CIMEData ImeData;
Dbg(DBGID_UI, TEXT("OpenComp()"));
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
// can not draw comp window
if (!hUIPrivate)
{
DbgAssert(0);
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate)
return;
// Check WM_IME_SETCONTEXT lParam
if ((lpUIPrivate->uiShowParam & ISC_SHOWUICOMPOSITIONWINDOW) == 0)
goto OpenCompUnlockUIPriv;
hIMC = GethImcFromHwnd(hUIWnd);
pImeCtx = GetIMECtx(hIMC);
if (pImeCtx == NULL)
{
Dbg(DBGID_UI, TEXT("OpenComp - Invalid hImc"));
ImeData->ptCompPos.x = ImeData->rcWorkArea.right - COMP_SIZEX;
ImeData->ptCompPos.y = ImeData->rcWorkArea.bottom - COMP_SIZEY;
nShowCompCmd = SW_HIDE;
}
else
{
#if 1 // MultiMonitor
RECT rcWorkArea;
ImeMonitorWorkAreaFromWindow(pImeCtx->GetAppWnd(), &rcWorkArea);
// if client window exist in same monitor as status window
if (!IsCicero() && PtInRect(&rcWorkArea, ImeData->ptStatusPos))
{
ImeData->ptCompPos.x =
(ImeData->ptStatusPos.x+ImeData->xStatusWi+UI_GAPX + COMP_SIZEX > ImeData->rcWorkArea.right) ?
ImeData->ptStatusPos.x - UI_GAPX - COMP_SIZEX : ImeData->ptStatusPos.x + ImeData->xStatusWi + UI_GAPX;
ImeData->ptCompPos.y = ImeData->ptStatusPos.y;
Dbg(DBGID_UI, TEXT("OpenComp - PtInRect x = %d, y = %d"), ImeData->ptCompPos.x, ImeData->ptCompPos.y);
}
else
{
// if client window appeared in different monitor from status window resides,
// then display left top of workarea of client window montitor
ImeData->ptCompPos.x = 0;
ImeData->ptCompPos.y = 0;
}
#else
ImeData->ptCompPos.x =
(ImeData->ptStatusPos.x+ImeData->xStatusWi+UI_GAPX + COMP_SIZEX > ImeData->rcWorkArea.right) ?
ImeData->ptStatusPos.x - UI_GAPX - COMP_SIZEX : ImeData->ptStatusPos.x + ImeData->xStatusWi + UI_GAPX;
ImeData->ptCompPos.y = ImeData->ptStatusPos.y;
#endif
// Set Comp wnd position of HIMC in client coordinate
ptClientComp = ImeData->ptCompPos;
ScreenToClient(pImeCtx->GetAppWnd(), &ptClientComp);
pImeCtx->SetCompositionFormPos(ptClientComp);
nShowCompCmd = SW_SHOWNOACTIVATE;
}
if (lpUIPrivate->hCompWnd)
{
SetWindowPos(lpUIPrivate->hCompWnd, NULL,
ImeData->ptCompPos.x, ImeData->ptCompPos.y,
0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
}
else
{
Dbg(DBGID_UI, TEXT("OpenComp - CreateWindow x = %d, y = %d"), ImeData->ptCompPos.x, ImeData->ptCompPos.y);
// create comp window
lpUIPrivate->hCompWnd = CreateWindow(
szCompClassName, TEXT("\0"),
WS_DISABLED | WS_POPUP,
ImeData->ptCompPos.x, ImeData->ptCompPos.y,
COMP_SIZEX, COMP_SIZEX,
hUIWnd, (HMENU)NULL, vpInstData->hInst, NULL);
DbgAssert(lpUIPrivate->hCompWnd != 0);
//if (!lpUIPrivate->hCompWnd)
// goto OpenCompUnlockUIPriv;
}
//if (pImeCtx)
// ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
OpenCompUnlockUIPriv:
GlobalUnlock(hUIPrivate);
return;
}
// Show the composition window
VOID ShowComp(HWND hUIWnd, INT nShowCompCmd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HIMC hIMC;
PCIMECtx pImeCtx;
Dbg(DBGID_UI, TEXT("ShowComp(): nShowCompCmd = %d"), nShowCompCmd);
hUIPrivate = GethUIPrivateFromHwnd(hUIWnd);
// can not draw comp window
if (!hUIPrivate)
{
DbgAssert(0);
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate)
{
DbgAssert(0);
return;
}
hIMC = GethImcFromHwnd(hUIWnd);
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
goto SwCompNoChange;
// b#53794
// Some absurd Apps send WM_IME_START_COMPOSITION and WM_IME_COMPOSITION,
// even though they have no composition string
// In this case wrong composition window appears in screen like white square or something.
if (nShowCompCmd == SW_SHOWNOACTIVATE)
{
if (pImeCtx->GetCompBufLen() == 0 || vfWndOpen[COMP_WINDOW] == fFalse)
nShowCompCmd = SW_HIDE;
}
if (lpUIPrivate->nShowCompCmd == nShowCompCmd)
goto SwCompNoChange;
if (lpUIPrivate->hCompWnd)
{
ShowWindow(lpUIPrivate->hCompWnd, nShowCompCmd);
lpUIPrivate->nShowCompCmd = nShowCompCmd;
}
else
lpUIPrivate->nShowCompCmd = SW_HIDE;
SwCompNoChange:
GlobalUnlock(hUIPrivate);
}
BOOL fSetCompWindowPos(HWND hCompWnd)
{
HIMC hIMC;
PCIMECtx pImeCtx;
RECT rcCur;
POINT ptNew;
CIMEData ImeData;
// No composition window
if (hCompWnd == 0)
return fFalse;
hIMC = GethImcFromHwnd(GetWindow(hCompWnd, GW_OWNER));
//if (!hIMC)
// {
// DbgAssert(0);
// return fFalse;
// }
//lpIMC = (LPINPUTCONTEXT)OurImmLockIMC(hIMC);
//if (!lpIMC)
// {
// DbgAssert(0);
// return fFalse;
// }
if ((pImeCtx = GetIMECtx(hIMC)) == NULL)
return fFalse;
Dbg(DBGID_UI, TEXT("fSetCompWindowPos()"));
if (pImeCtx->GetCompositionFormStyle() & CFS_RECT)
{
Dbg(DBGID_UI, TEXT("fSetCompWindowPos(): CFS_RECT"));
pImeCtx->GetCompositionForm(&rcCur);
ptNew.x = rcCur.left;
ptNew.y = rcCur.top;
ClientToScreen(pImeCtx->GetAppWnd(), &ptNew);
}
else
if (pImeCtx->GetCompositionFormStyle() & CFS_POINT)
{
Dbg(DBGID_UI, TEXT("fSetCompWindowPos(): CFS_POINT"));
pImeCtx->GetCompositionForm(&ptNew);
ClientToScreen(pImeCtx->GetAppWnd(), &ptNew);
}
else
{ // For CFS_DEFAULT
Dbg(DBGID_UI, TEXT("fSetCompWindowPos(): CFS_DEFAULT"));
#if 1 // MultiMonitor
RECT rcWorkArea;
ImeMonitorWorkAreaFromWindow(pImeCtx->GetAppWnd(), &rcWorkArea);
// if client window exist in same monitor as status window
if ( PtInRect(&rcWorkArea, ImeData->ptStatusPos) )
{
ptNew.x =
(ImeData->ptStatusPos.x+ImeData->xStatusWi+UI_GAPX + COMP_SIZEX > ImeData->rcWorkArea.right) ?
ImeData->ptStatusPos.x - UI_GAPX - COMP_SIZEX : ImeData->ptStatusPos.x + ImeData->xStatusWi + UI_GAPX;
ptNew.y = ImeData->ptStatusPos.y;
}
else
{ // if client window appeared in different monitor from status window resides,
// then display right bottom of workarea of client window montitor
ptNew.x = rcWorkArea.right - COMP_SIZEX;
ptNew.y = rcWorkArea.bottom - COMP_SIZEY;
}
#else
ptNew.x =
(ImeData->ptStatusPos.x+ImeData->xStatusWi+UI_GAPX + COMP_SIZEX > ImeData->rcWorkArea.right) ?
ImeData->ptStatusPos.x - UI_GAPX - COMP_SIZEX : ImeData->ptStatusPos.x + ImeData->xStatusWi + UI_GAPX;
ptNew.y = ImeData->ptStatusPos.y;
#endif
ImeData->ptCompPos = ptNew;
ScreenToClient(pImeCtx->GetAppWnd(), &ptNew);
pImeCtx->SetCompositionFormPos(ptNew);
}
SetWindowPos(hCompWnd, NULL,
ptNew.x, ptNew.y,
0, 0, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOSIZE|SWP_NOZORDER);
return (fTrue);
}