windows-nt/Source/XPSP1/NT/windows/feime/chs/ntgb/candui.c
2020-09-26 16:20:57 +08:00

1722 lines
51 KiB
C

/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
candui.c
++*/
#include <windows.h>
#include <immdev.h>
#include <imedefs.h>
/**********************************************************************/
/* GetCandWnd */
/* Return Value : */
/* window handle of candidatte */
/**********************************************************************/
HWND PASCAL GetCandWnd(
HWND hUIWnd) // UI window
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HWND hCandWnd;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
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);
}
void PASCAL CalcCandPos(
HIMC hIMC,
HWND hUIWnd,
LPPOINT lpptWnd) // the composition window position
{
POINT ptNew, ptSTWPos;
RECT rcWorkArea;
#ifdef MUL_MONITOR
rcWorkArea = ImeMonitorWorkAreaFromPoint(*lpptWnd);
#else
rcWorkArea = sImeG.rcWorkArea;
#endif
ptNew.x = lpptWnd->x + lpImeL->xCompWi + UI_MARGIN;
if (ptNew.x + sImeG.xCandWi > rcWorkArea.right) {
// exceed screen width
ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN;
}
ptNew.y = lpptWnd->y + lpImeL->cyCompBorder - sImeG.cyCandBorder;
if (ptNew.y + sImeG.yCandHi > rcWorkArea.bottom) {
// exceed screen high
ptNew.y = rcWorkArea.bottom - sImeG.yCandHi;
}
if(!sImeG.IC_Trace) {
HWND hCompWnd;
ImmGetStatusWindowPos(hIMC, (LPPOINT)&ptSTWPos);
hCompWnd = GetCompWnd(hUIWnd);
if (hCompWnd) {
ptNew.x = ptSTWPos.x + sImeG.xStatusWi + lpImeL->xCompWi + 2 * UI_MARGIN;
if((ptSTWPos.x + sImeG.xStatusWi + sImeG.xCandWi + lpImeL->xCompWi + 2 * UI_MARGIN)>
rcWorkArea.right) {
if (ptSTWPos.x >= (sImeG.xCandWi + lpImeL->xCompWi + 2 * UI_MARGIN)) {
ptNew.x = ptSTWPos.x - lpImeL->xCompWi - sImeG.xCandWi - 2 * UI_MARGIN;
} else {
ptNew.x = ptSTWPos.x + sImeG.xStatusWi + UI_MARGIN;
}
}
ptNew.y = ptSTWPos.y + lpImeL->cyCompBorder - sImeG.cyCandBorder;
if (ptNew.y + sImeG.yCandHi > rcWorkArea.bottom) {
ptNew.y = rcWorkArea.bottom - sImeG.yCandHi;
}
} else {
ptNew.x = ptSTWPos.x + sImeG.xStatusWi + UI_MARGIN;
if(((ptSTWPos.x + sImeG.xStatusWi + sImeG.xCandWi + UI_MARGIN)>=
rcWorkArea.right)
&& (ptSTWPos.x >= sImeG.xCandWi + UI_MARGIN)) {
ptNew.x = ptSTWPos.x - sImeG.xCandWi - UI_MARGIN;
}
ptNew.y = ptSTWPos.y + lpImeL->cyCompBorder - sImeG.cyCandBorder;
if (ptNew.y + sImeG.yCandHi > rcWorkArea.bottom) {
ptNew.y = rcWorkArea.bottom - sImeG.yCandHi;
}
}
}
lpptWnd->x = ptNew.x;
lpptWnd->y = ptNew.y;
return;
}
/**********************************************************************/
/* AdjustCandPos */
/**********************************************************************/
void AdjustCandPos(
HIMC hIMC,
LPPOINT lpptWnd) // the composition window position
{
LPINPUTCONTEXT lpIMC;
LONG ptFontHi;
UINT uEsc;
RECT rcWorkArea;
#ifdef MUL_MONITOR
rcWorkArea = ImeMonitorWorkAreaFromPoint(*lpptWnd);
#else
rcWorkArea = sImeG.rcWorkArea;
#endif
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (lpIMC->lfFont.A.lfHeight > 0) {
ptFontHi = lpIMC->lfFont.A.lfHeight;
} else if (lpIMC->lfFont.A.lfWidth == 0) {
ptFontHi = lpImeL->yCompHi;
} else {
ptFontHi = -lpIMC->lfFont.A.lfHeight;
}
if (ptFontHi > lpImeL->yCompHi * 8) {
ptFontHi = lpImeL->yCompHi * 8;
}
if (ptFontHi < sImeG.yChiCharHi) {
ptFontHi = sImeG.yChiCharHi;
}
// -450 to 450 index 0
// 450 to 1350 index 1
// 1350 to 2250 index 2
// 2250 to 3150 index 3
uEsc = (UINT)((lpIMC->lfFont.A.lfEscapement + 450) / 900 % 4);
// find the location after IME do an adjustment
ptFontHi = ptFontHi * ptInputEsc[uEsc].y;
if(lpptWnd->y + ptFontHi + sImeG.yCandHi <= rcWorkArea.bottom) {
lpptWnd->y += ptFontHi;
} else {
lpptWnd->y -= (ptFontHi + sImeG.yCandHi);
}
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* AdjustCandRectBoundry */
/**********************************************************************/
void PASCAL AdjustCandRectBoundry(
LPINPUTCONTEXT lpIMC,
LPPOINT lpptCandWnd) // the caret position
{
RECT rcExclude, rcUIRect, rcInterSect;
UINT uEsc;
RECT rcWorkArea;
#ifdef MUL_MONITOR
{
RECT rcCandWnd;
*(LPPOINT)&rcCandWnd = *(LPPOINT)lpptCandWnd;
rcCandWnd.right = rcCandWnd.left + sImeG.xCandWi;
rcCandWnd.bottom = rcCandWnd.top + sImeG.yCandHi;
rcWorkArea = ImeMonitorWorkAreaFromRect(&rcCandWnd);
}
#else
rcWorkArea = sImeG.rcWorkArea;
#endif
// be a normal rectangle, not a negative rectangle
if (lpIMC->cfCandForm[0].rcArea.left > lpIMC->cfCandForm[0].rcArea.right) {
LONG tmp;
tmp = lpIMC->cfCandForm[0].rcArea.left;
lpIMC->cfCandForm[0].rcArea.left = lpIMC->cfCandForm[0].rcArea.right;
lpIMC->cfCandForm[0].rcArea.right = tmp;
}
if (lpIMC->cfCandForm[0].rcArea.top > lpIMC->cfCandForm[0].rcArea.bottom) {
LONG tmp;
tmp = lpIMC->cfCandForm[0].rcArea.top;
lpIMC->cfCandForm[0].rcArea.top = lpIMC->cfCandForm[0].rcArea.bottom;
lpIMC->cfCandForm[0].rcArea.bottom = tmp;
}
// translate from client coordinate to screen coordinate
rcExclude = lpIMC->cfCandForm[0].rcArea;
rcExclude.left += lpptCandWnd->x - lpIMC->cfCandForm[0].ptCurrentPos.x;
rcExclude.right += lpptCandWnd->x - lpIMC->cfCandForm[0].ptCurrentPos.x;
rcExclude.top += lpptCandWnd->y - lpIMC->cfCandForm[0].ptCurrentPos.y;
rcExclude.bottom += lpptCandWnd->y - lpIMC->cfCandForm[0].ptCurrentPos.y;
// if original point is OK, we use it
*(LPPOINT)&rcUIRect = *lpptCandWnd;
if (rcUIRect.left < rcWorkArea.left) {
rcUIRect.left = rcWorkArea.left;
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
rcUIRect.left = rcWorkArea.right - sImeG.xCandWi;
} else {
}
if (rcUIRect.top < rcWorkArea.top) {
rcUIRect.top = rcWorkArea.top;
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi;
} else {
}
rcUIRect.right = rcUIRect.left + sImeG.xCandWi;
rcUIRect.bottom = rcUIRect.top + sImeG.yCandHi;
if (!IntersectRect(&rcInterSect, &rcExclude, &rcUIRect)) {
*lpptCandWnd = *(LPPOINT)&rcUIRect;
return;
}
uEsc = (UINT)((lpIMC->lfFont.A.lfEscapement + 450) / 900 % 4);
if (uEsc & 0x0001) {
// 900 & 2700 we need change x coordinate
if (ptInputEsc[uEsc].x > 0) {
rcUIRect.left = rcExclude.right;
} else {
rcUIRect.left = rcExclude.left - sImeG.xCandWi;
}
} else {
// 0 & 1800 we do not change x coordinate
rcUIRect.left = lpptCandWnd->x;
}
if (rcUIRect.left < rcWorkArea.left) {
rcUIRect.left = rcWorkArea.left;
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
rcUIRect.left = rcWorkArea.right - sImeG.xCandWi;
} else {
}
if (uEsc & 0x0001) {
// 900 & 2700 we do not change y coordinate
rcUIRect.top = lpptCandWnd->y;
} else {
// 0 & 1800 we need change y coordinate
if (ptInputEsc[uEsc].y > 0) {
rcUIRect.top = rcExclude.bottom;
} else {
rcUIRect.top = rcExclude.top - sImeG.yCandHi;
}
}
if (rcUIRect.top < rcWorkArea.top) {
rcUIRect.top = rcWorkArea.top;
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi;
} else {
}
rcUIRect.right = rcUIRect.left + sImeG.xCandWi;
rcUIRect.bottom = rcUIRect.top + sImeG.yCandHi;
// the candidate window not overlapped with exclude rectangle
// so we found a position
if (!IntersectRect(&rcInterSect, &rcExclude, &rcUIRect)) {
*lpptCandWnd = *(LPPOINT)&rcUIRect;
return;
}
// adjust according to
*(LPPOINT)&rcUIRect = *lpptCandWnd;
if (uEsc & 0x0001) {
// 900 & 2700 we prefer adjust x
if (ptInputEsc[uEsc].x > 0) {
rcUIRect.left = rcExclude.right;
} else {
rcUIRect.left = rcExclude.left - sImeG.xCandWi;
}
if (rcUIRect.left < rcWorkArea.left) {
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
} else {
if (rcUIRect.top < rcWorkArea.top) {
rcUIRect.top = rcWorkArea.top;
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi;
}
*lpptCandWnd = *(LPPOINT)&rcUIRect;
return;
}
// negative try
if (ptInputEsc[uEsc].x > 0) {
rcUIRect.left = rcExclude.left - sImeG.xCandWi;
} else {
rcUIRect.left = rcExclude.right;
}
if (rcUIRect.left < rcWorkArea.left) {
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
} else {
if (rcUIRect.top < rcWorkArea.top) {
rcUIRect.top = rcWorkArea.top;
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi;
}
*lpptCandWnd = *(LPPOINT)&rcUIRect;
return;
}
// negative try failure again, we use positive plus display adjust
if (ptInputEsc[uEsc].x > 0) {
rcUIRect.left = rcExclude.right;
} else {
rcUIRect.left = rcExclude.left - sImeG.xCandWi;
}
if (rcUIRect.left < rcWorkArea.left) {
rcUIRect.left = rcWorkArea.left;
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
rcUIRect.left = rcWorkArea.right - sImeG.xCandWi;
}
if (rcUIRect.top < rcWorkArea.top) {
rcUIRect.top = rcWorkArea.top;
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi;
}
*lpptCandWnd = *(LPPOINT)&rcUIRect;
} else {
// 0 & 1800 we prefer adjust y
if (ptInputEsc[uEsc].y > 0) {
rcUIRect.top = rcExclude.bottom;
} else {
rcUIRect.top = rcExclude.top - sImeG.yCandHi;
}
if (rcUIRect.top < rcWorkArea.top) {
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
} else {
if (rcUIRect.left < rcWorkArea.left) {
rcUIRect.left = rcWorkArea.left;
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
rcUIRect.left = rcWorkArea.right - sImeG.xCandWi;
}
*lpptCandWnd = *(LPPOINT)&rcUIRect;
return;
}
// negative try
if (ptInputEsc[uEsc].y > 0) {
rcUIRect.top = rcExclude.top - sImeG.yCandHi;
} else {
rcUIRect.top = rcExclude.bottom;
}
if (rcUIRect.top < rcWorkArea.top) {
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.right) {
} else {
if (rcUIRect.left < rcWorkArea.left) {
rcUIRect.left = rcWorkArea.left;
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
rcUIRect.left = rcWorkArea.right - sImeG.xCandWi;
}
*lpptCandWnd = *(LPPOINT)&rcUIRect;
return;
}
// negative try failure again, we use positive plus display adjust
if (ptInputEsc[uEsc].y > 0) {
rcUIRect.top = rcExclude.bottom;
} else {
rcUIRect.top = rcExclude.top - sImeG.yCandHi;
}
if (rcUIRect.left < rcWorkArea.left) {
rcUIRect.left = rcWorkArea.left;
} else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) {
rcUIRect.left = rcWorkArea.right - sImeG.xCandWi;
}
if (rcUIRect.top < rcWorkArea.top) {
rcUIRect.top = rcWorkArea.top;
} else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) {
rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi;
}
*lpptCandWnd = *(LPPOINT)&rcUIRect;
}
return;
}
/**********************************************************************/
/* AdjustCandBoundry */
/**********************************************************************/
void PASCAL AdjustCandBoundry(
LPPOINT lpptCandWnd) // the position
{
RECT rcWorkArea;
#ifdef MUL_MONITOR
{
RECT rcCandWnd;
*(LPPOINT)&rcCandWnd = *(LPPOINT)lpptCandWnd;
rcCandWnd.right = rcCandWnd.left + sImeG.xCandWi;
rcCandWnd.bottom = rcCandWnd.top + sImeG.yCandHi;
rcWorkArea = ImeMonitorWorkAreaFromRect(&rcCandWnd);
}
#else
rcWorkArea = sImeG.rcWorkArea;
#endif
if (lpptCandWnd->x < rcWorkArea.left) {
lpptCandWnd->x = rcWorkArea.left;
} else if (lpptCandWnd->x + sImeG.xCandWi > rcWorkArea.right) {
lpptCandWnd->x = rcWorkArea.right - sImeG.xCandWi;
}
if (lpptCandWnd->y < rcWorkArea.top) {
lpptCandWnd->y = rcWorkArea.top;
} else if (lpptCandWnd->y + sImeG.yCandHi > rcWorkArea.bottom) {
lpptCandWnd->y = rcWorkArea.bottom - sImeG.yCandHi;
}
return;
}
/**********************************************************************/
/* SetCandPosition() */
/**********************************************************************/
LRESULT PASCAL SetCandPosition(
HWND hCandWnd)
{
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
POINT ptNew;
hUIWnd = GetWindow(hCandWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (1L);
}
ptNew = lpIMC->cfCandForm[0].ptCurrentPos;
ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
if (lpIMC->cfCandForm[0].dwStyle & CFS_FORCE_POSITION) {
} else if (lpIMC->cfCandForm[0].dwStyle == CFS_CANDIDATEPOS) {
AdjustCandBoundry(&ptNew);
} else if (lpIMC->cfCandForm[0].dwStyle == CFS_EXCLUDE) {
if(!sImeG.IC_Trace) {
CalcCandPos(hIMC, hUIWnd, &ptNew);
}
AdjustCandBoundry(&ptNew);
}
SetWindowPos(hCandWnd, NULL, ptNew.x, ptNew.y,
0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
ImmUnlockIMC(hIMC);
return (0L);
}
/**********************************************************************/
/* ShowCand() */
/**********************************************************************/
void PASCAL ShowCand( // Show the candidate window
HWND hUIWnd,
int nShowCandCmd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
if (lpUIPrivate->nShowCandCmd == nShowCandCmd) {
goto SwCandNoChange;
}
if (nShowCandCmd == SW_HIDE) {
lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_CAND_WINDOW);
}
if (!lpUIPrivate->hCandWnd) {
// not in show candidate window mode
} else if (lpUIPrivate->nShowCandCmd == nShowCandCmd) {
} else {
if(nShowCandCmd == SW_HIDE) {
uOpenCand = 0;
} else {
HIMC hIMC;
POINT ptSTWPos;
int Comp_CandWndLen;
RECT rcWorkArea;
uOpenCand = 1;
// reset status window for LINE_UI(FIX_UI)
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
goto ShowCand;
}
ImmGetStatusWindowPos(hIMC, (LPPOINT)&ptSTWPos);
#ifdef MUL_MONITOR
rcWorkArea = ImeMonitorWorkAreaFromPoint(ptSTWPos);
#else
rcWorkArea = sImeG.rcWorkArea;
#endif
Comp_CandWndLen = 0;
if(uOpenCand) {
Comp_CandWndLen += sImeG.xCandWi + UI_MARGIN;
if(uStartComp) {
Comp_CandWndLen += lpImeL->xCompWi + UI_MARGIN;
}
if(ptSTWPos.x + sImeG.xStatusWi + Comp_CandWndLen > rcWorkArea.right) {
PostMessage(GetCompWnd(hUIWnd),
WM_IME_NOTIFY,
IMN_SETCOMPOSITIONWINDOW,
0);
}
}
}
ShowCand:
ShowWindow(lpUIPrivate->hCandWnd, nShowCandCmd);
lpUIPrivate->nShowCandCmd = nShowCandCmd;
}
SwCandNoChange:
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* OpenCand */
/**********************************************************************/
void PASCAL OpenCand(
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
POINT ptWnd;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
lpUIPrivate->fdwSetContext |= ISC_SHOWUICANDIDATEWINDOW;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
goto OpenCandUnlockUIPriv;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
goto OpenCandUnlockUIPriv;
}
if (lpIMC->cfCandForm[0].dwIndex == 0) {
ptWnd = lpIMC->cfCandForm[0].ptCurrentPos;
ClientToScreen(lpIMC->hWnd, &ptWnd);
if (lpIMC->cfCandForm[0].dwStyle & CFS_FORCE_POSITION) {
} else if (lpIMC->cfCandForm[0].dwStyle == CFS_EXCLUDE) {
POINT ptCaret;
AdjustCandBoundry(&ptWnd);
if((!sImeG.IC_Trace) || (!GetCaretPos(&ptCaret))) {
if(GetCompWnd(hUIWnd)) {
ptWnd.x = ptWnd.y = 0;
ClientToScreen(lpIMC->hWnd, &ptWnd);
ptWnd.x -= lpImeL->cxCompBorder + 1;
ptWnd.y -= lpImeL->cyCompBorder + 1;
} else {
ptWnd.x = lpImeL->cxCompBorder + 1;
ptWnd.y = lpImeL->cyCompBorder + 1;
}
CalcCandPos(hIMC, hUIWnd, &ptWnd);
lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS;
lpIMC->cfCandForm[0].ptCurrentPos = ptWnd;
ScreenToClient(lpIMC->hWnd, &lpIMC->cfCandForm[0].ptCurrentPos);
} else {
AdjustCandPos(hIMC, &ptWnd);
}
} else if (lpIMC->cfCandForm[0].dwStyle == CFS_CANDIDATEPOS) {
AdjustCandBoundry(&ptWnd);
} else {
if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
ptWnd.x = ptWnd.y = 0;
ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd);
} else {
ptWnd = lpIMC->cfCompForm.ptCurrentPos;
ClientToScreen(lpIMC->hWnd, &ptWnd);
}
ptWnd.x -= lpImeL->cxCompBorder + 1;
ptWnd.y -= lpImeL->cyCompBorder + 1;
CalcCandPos(hIMC, hUIWnd, &ptWnd);
lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS;
lpIMC->cfCandForm[0].ptCurrentPos = ptWnd;
ScreenToClient(lpIMC->hWnd, &lpIMC->cfCandForm[0].ptCurrentPos);
}
} else {
// make cand windows trace comp window !
if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
ptWnd.x = ptWnd.y = 0;
ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd);
} else {
ptWnd = lpIMC->cfCompForm.ptCurrentPos;
ClientToScreen(lpIMC->hWnd, &ptWnd);
}
ptWnd.x -= lpImeL->cxCompBorder + 1;
ptWnd.y -= lpImeL->cyCompBorder + 1;
CalcCandPos(hIMC, hUIWnd, &ptWnd);
lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS;
lpIMC->cfCandForm[0].ptCurrentPos = ptWnd;
ScreenToClient(lpIMC->hWnd, &lpIMC->cfCandForm[0].ptCurrentPos);
}
ImmUnlockIMC(hIMC);
if (lpUIPrivate->hCandWnd) {
SetWindowPos(lpUIPrivate->hCandWnd,
NULL,
ptWnd.x,
ptWnd.y,
0,
0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
} else {
lpUIPrivate->hCandWnd = CreateWindowEx(
WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,
szCandClassName,
NULL,
WS_POPUP|WS_DISABLED,
ptWnd.x,
ptWnd.y,
sImeG.xCandWi,
sImeG.yCandHi,
hUIWnd,
(HMENU)NULL,
hInst,
NULL);
SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_XY, 0L);
}
ShowCand(hUIWnd, SW_SHOWNOACTIVATE);
OpenCandUnlockUIPriv:
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* CloseCand */
/**********************************************************************/
void PASCAL CloseCand(
HWND hUIWnd)
{
uOpenCand = 0;
ShowCand(hUIWnd, SW_HIDE);
return;
}
/**********************************************************************/
/* DestroyCandWindow */
/**********************************************************************/
void PASCAL DestroyCandWindow(
HWND hCandWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
// undo the drag border
DrawDragBorder(hCandWnd,
GetWindowLong(hCandWnd, UI_MOVE_XY),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
}
hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER),
IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
lpUIPrivate->nShowCandCmd = SW_HIDE;
lpUIPrivate->hCandWnd = (HWND)NULL;
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* MouseSelectCandStr() */
/**********************************************************************/
void PASCAL MouseSelectCandStr(
HWND hCandWnd,
LPPOINT lpCursor)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
DWORD dwValue;
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (!lpIMC->hCandInfo) {
ImmUnlockIMC(hIMC);
return;
}
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
ImmUnlockIMC(hIMC);
return;
}
dwValue = (lpCursor->y - sImeG.rcCandText.top) / sImeG.yChiCharHi;
lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
lpCandInfo->dwOffset[0]);
dwValue = dwValue + lpCandList->dwSelection /
lpCandList->dwPageSize * lpCandList->dwPageSize;
if (dwValue >= lpCandList->dwCount) {
// invalid choice
MessageBeep((UINT)-1);
} else {
NotifyIME(hIMC, NI_SELECTCANDIDATESTR, 0, dwValue);
}
ImmUnlockIMCC(lpIMC->hCandInfo);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* CandPageDownUP() */
/**********************************************************************/
void PASCAL CandPageDownUP(
HWND hCandWnd,
UINT uCandDownUp)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
HDC hDC;
HBITMAP hCandHpBmp, hCandUpBmp, hCandDpBmp, hCandEpBmp;
HBITMAP hOldBmp;
HDC hMemDC;
// change candlist
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
if (!hIMC) {
return;
}
// get lpIMC
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
// get lpImcP
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
return;
}
// get lpCandInfo
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
return;
}
// get lpCandList and init dwCount & dwSelection
lpCandList = (LPCANDIDATELIST)
((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]);
switch(uCandDownUp) {
case uCandHome:
ChooseCand(0x24, lpIMC, lpCandInfo, lpImcP);
NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0);
break;
case uCandUp:
ChooseCand('-', lpIMC, lpCandInfo, lpImcP);
NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0);
break;
case uCandDown:
ChooseCand('=', lpIMC, lpCandInfo, lpImcP);
NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0);
break;
case uCandEnd:
ChooseCand(0x23, lpIMC, lpCandInfo, lpImcP);
NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0);
break;
default:
break;
}
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMCC(lpIMC->hCandInfo);
ImmUnlockIMC(hIMC);
// draw button down
hDC = GetDC(hCandWnd);
if ( hDC == NULL )
return;
hMemDC = CreateCompatibleDC(hDC);
if ( hMemDC == NULL )
{
ReleaseDC(hCandWnd, hDC);
return;
}
hOldBmp = NULL;
switch(uCandDownUp) {
case uCandHome:
hCandHpBmp = LoadBitmap(hInst, TEXT("CandHp"));
if ( hCandHpBmp != NULL)
{
hOldBmp = SelectObject(hMemDC, hCandHpBmp);
BitBlt(hDC, sImeG.rcCandBTH.left, sImeG.rcCandBTH.top,
sImeG.rcCandBTH.right - sImeG.rcCandBTH.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
DeleteObject(hCandHpBmp);
}
break;
case uCandUp:
hCandUpBmp = LoadBitmap(hInst, TEXT("CandUp"));
if ( hCandUpBmp != NULL )
{
hOldBmp = SelectObject(hMemDC, hCandUpBmp);
BitBlt(hDC, sImeG.rcCandBTU.left, sImeG.rcCandBTU.top,
sImeG.rcCandBTU.right - sImeG.rcCandBTU.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
DeleteObject(hCandUpBmp);
}
break;
case uCandDown:
hCandDpBmp = LoadBitmap(hInst, TEXT("CandDp"));
if ( hCandDpBmp != NULL)
{
hOldBmp = SelectObject(hMemDC, hCandDpBmp);
BitBlt(hDC, sImeG.rcCandBTD.left, sImeG.rcCandBTD.top,
sImeG.rcCandBTD.right - sImeG.rcCandBTD.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
DeleteObject(hCandDpBmp);
}
break;
case uCandEnd:
hCandEpBmp = LoadBitmap(hInst, TEXT("CandEp"));
if ( hCandEpBmp != NULL)
{
hOldBmp = SelectObject(hMemDC, hCandEpBmp);
BitBlt(hDC, sImeG.rcCandBTE.left, sImeG.rcCandBTE.top,
sImeG.rcCandBTE.right - sImeG.rcCandBTE.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
DeleteObject(hCandEpBmp);
}
break;
default:
break;
}
if ( hOldBmp != NULL)
SelectObject(hMemDC, hOldBmp);
DeleteDC(hMemDC);
ReleaseDC(hCandWnd, hDC);
return;
}
/**********************************************************************/
/* CandSetCursor() */
/**********************************************************************/
void PASCAL CandSetCursor(
HWND hCandWnd,
LPARAM lParam)
{
POINT ptCursor;
RECT rcWnd;
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) !=
WINDOW_NOT_DRAG) {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
return;
}
if (HIWORD(lParam) == WM_LBUTTONDOWN) {
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
GetCursorPos(&ptCursor);
ScreenToClient(hCandWnd, &ptCursor);
if (PtInRect(&sImeG.rcCandText, ptCursor)
&& sImeG.IC_Trace) {
SetCursor(LoadCursor(hInst, szHandCursor));
MouseSelectCandStr(hCandWnd, &ptCursor);
return;
} else if (PtInRect(&sImeG.rcCandBTH, ptCursor)) {
CandPageDownUP(hCandWnd, uCandHome);
return;
} else if (PtInRect(&sImeG.rcCandBTU, ptCursor)) {
CandPageDownUP(hCandWnd, uCandUp);
return;
} else if (PtInRect(&sImeG.rcCandBTD, ptCursor)) {
CandPageDownUP(hCandWnd, uCandDown);
return;
} else if (PtInRect(&sImeG.rcCandBTE, ptCursor)) {
CandPageDownUP(hCandWnd, uCandEnd);
return;
} else {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
}
} else if (HIWORD(lParam) == WM_LBUTTONUP) {
HDC hDC;
HBITMAP hCandHBmp, hCandUBmp, hCandDBmp, hCandEBmp;
HBITMAP hOldBmp;
HDC hMemDC;
hDC = GetDC(hCandWnd);
hMemDC = CreateCompatibleDC(hDC);
if ( hMemDC )
{
hCandHBmp = LoadBitmap(hInst, TEXT("CandH"));
if ( hCandHBmp )
{
hOldBmp = SelectObject(hMemDC, hCandHBmp);
BitBlt(hDC, sImeG.rcCandBTH.left, sImeG.rcCandBTH.top,
sImeG.rcCandBTH.right - sImeG.rcCandBTH.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandHBmp);
}
hCandUBmp = LoadBitmap(hInst, TEXT("CandU"));
if ( hCandUBmp )
{
hOldBmp=SelectObject(hMemDC, hCandUBmp);
BitBlt(hDC, sImeG.rcCandBTU.left, sImeG.rcCandBTU.top,
sImeG.rcCandBTU.right - sImeG.rcCandBTU.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandUBmp);
}
hCandDBmp = LoadBitmap(hInst, TEXT("CandD"));
if ( hCandDBmp )
{
hOldBmp=SelectObject(hMemDC, hCandDBmp);
BitBlt(hDC, sImeG.rcCandBTD.left, sImeG.rcCandBTD.top,
sImeG.rcCandBTD.right - sImeG.rcCandBTD.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandDBmp);
}
hCandEBmp = LoadBitmap(hInst, TEXT("CandE"));
if ( hCandEBmp )
{
hOldBmp=SelectObject(hMemDC, hCandEBmp);
BitBlt(hDC, sImeG.rcCandBTE.left, sImeG.rcCandBTE.top,
sImeG.rcCandBTE.right - sImeG.rcCandBTE.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandEBmp);
}
DeleteDC(hMemDC);
}
ReleaseDC(hCandWnd, hDC);
return;
} else {
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
GetCursorPos(&ptCursor);
ScreenToClient(hCandWnd, &ptCursor);
if (PtInRect(&sImeG.rcCandText, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
return;
} else if (PtInRect(&sImeG.rcCandBTH, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
} else if (PtInRect(&sImeG.rcCandBTU, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
} else if (PtInRect(&sImeG.rcCandBTD, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
} else if (PtInRect(&sImeG.rcCandBTE, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
} else {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
}
return;
}
SetCapture(hCandWnd);
GetCursorPos(&ptCursor);
SetWindowLong(hCandWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
GetWindowRect(hCandWnd, &rcWnd);
SetWindowLong(hCandWnd, UI_MOVE_OFFSET,
MAKELONG(ptCursor.x - rcWnd.left, ptCursor.y - rcWnd.top));
DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
return;
}
/**********************************************************************/
/* CandButtonUp() */
/**********************************************************************/
BOOL PASCAL CandButtonUp(
HWND hCandWnd)
{
LONG lTmpCursor, lTmpOffset;
POINT pt;
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) {
return (FALSE);
}
lTmpCursor = GetWindowLong(hCandWnd, UI_MOVE_XY);
// calculate the org by the offset
lTmpOffset = GetWindowLong(hCandWnd, UI_MOVE_OFFSET);
pt.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x;
pt.y = (*(LPPOINTS)&lTmpCursor).y - (*(LPPOINTS)&lTmpOffset).y;
DrawDragBorder(hCandWnd, lTmpCursor, lTmpOffset);
SetWindowLong(hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
ReleaseCapture();
hUIWnd = GetWindow(hCandWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (FALSE);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
AdjustCandBoundry(&pt);
ScreenToClient(lpIMC->hWnd, &pt);
lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS;
lpIMC->cfCandForm[0].ptCurrentPos = pt;
ImmUnlockIMC(hIMC);
PostMessage(hCandWnd, WM_IME_NOTIFY, IMN_SETCANDIDATEPOS, 0x0001);
return (TRUE);
}
/**********************************************************************/
/* UpdateCandWindow() */
/**********************************************************************/
void PASCAL PaintCandWindow(
HWND hCandWnd,
HDC hDC)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
LPPRIVCONTEXT lpImcP;
HGDIOBJ hOldFont;
DWORD dwStart, dwEnd;
TCHAR szStrBuf[2 * MAXSTRLEN * sizeof(WCHAR) / sizeof(TCHAR) + 1];
int i;
HBITMAP hCandIconBmp, hCandInfBmp;
HBITMAP hOldBmp, hCandHBmp, hCandUBmp, hCandDBmp, hCandEBmp;
HDC hMemDC;
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (!lpIMC->hCandInfo) {
goto UpCandW2UnlockIMC;
}
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
goto UpCandW2UnlockIMC;
}
if (!lpIMC->hPrivate) {
goto UpCandW2UnlockCandInfo;
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
goto UpCandW2UnlockCandInfo;
}
// set font
if (sImeG.fDiffSysCharSet) {
LOGFONT lfFont;
ZeroMemory(&lfFont, sizeof(lfFont));
hOldFont = GetCurrentObject(hDC, OBJ_FONT);
lfFont.lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
lfFont.lfCharSet = NATIVE_CHARSET;
lstrcpy(lfFont.lfFaceName, TEXT("Simsun"));
SelectObject(hDC, CreateFontIndirect(&lfFont));
}
lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
lpCandInfo->dwOffset[0]);
dwStart = lpCandList->dwSelection;
dwEnd = dwStart + lpCandList->dwPageSize;
if (dwEnd > lpCandList->dwCount) {
dwEnd = lpCandList->dwCount;
}
// draw CandWnd Layout
if (sImeG.IC_Trace) {
RECT rcWnd;
GetClientRect(hCandWnd, &rcWnd);
DrawConcaveRect(hDC,
rcWnd.left,
rcWnd.top + UI_CANDINF,
rcWnd.right - 1,
rcWnd.bottom - 1);
} else {
RECT rcWnd;
GetClientRect(hCandWnd, &rcWnd);
DrawConcaveRect(hDC,
sImeG.rcCandText.left - 1,
rcWnd.top,
sImeG.rcCandText.right + 1,
rcWnd.bottom - 1);
}
SetTextColor(hDC, RGB(0x00, 0x00, 0x00));
SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
if (sImeG.IC_Trace) {
ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top,
ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL);
szStrBuf[0] = TEXT('1');
szStrBuf[1] = TEXT(':');
for (i = 0; dwStart < dwEnd; dwStart++, i++) {
int iLen;
iLen = 0;
szStrBuf[0] = szDigit[i + CAND_START];
#if defined(COMBO_IME)
if(sImeL.dwRegImeIndex == INDEX_GB || sImeL.dwRegImeIndex == INDEX_GBK){
iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
lpCandList->dwOffset[dwStart]));
if (iLen > 10 * 2 / sizeof(TCHAR)) {
iLen = 10 * 2 / sizeof(TCHAR);
CopyMemory(&szStrBuf[2],
((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])),
(iLen - 2) * sizeof(TCHAR));
// maybe not good for UNICODE
szStrBuf[iLen] = TEXT('.');
szStrBuf[iLen+1] = TEXT('.');
szStrBuf[iLen+2] = TEXT('\0');
} else {
CopyMemory(&szStrBuf[2],
(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]),
iLen*sizeof(TCHAR));
}
}else if(sImeL.dwRegImeIndex == INDEX_UNICODE){
WORD wCode;
wCode = *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]);
#ifdef UNICODE
szStrBuf[2]= wCode;
szStrBuf[3]=TEXT('\0');
#else
szStrBuf[2]= LOBYTE(wCode);
szStrBuf[3]= HIBYTE(wCode);
szStrBuf[4]=TEXT('\0');
#endif
iLen = 2/sizeof(TCHAR);
}
#else
iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
lpCandList->dwOffset[dwStart]));
if (iLen > 10 * 2 / sizeof(TCHAR)) {
iLen = 10 * 2 / sizeof(TCHAR);
CopyMemory(&szStrBuf[2],
((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]),
(iLen - 2) * sizeof(TCHAR));
szStrBuf[iLen] = TEXT('.');
szStrBuf[iLen+1] = TEXT('.');
szStrBuf[iLen+2] = TEXT('\0');
} else {
CopyMemory(&szStrBuf[2],
((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]),
iLen*sizeof(TCHAR));
}
#endif //COMBO_IME
ExtTextOut(hDC, sImeG.rcCandText.left,
sImeG.rcCandText.top + i * sImeG.yChiCharHi,
(UINT)0, NULL,
szStrBuf,
iLen + 2, NULL);
// QW/GB info
{
int iMyLen;
WORD wCode, wGB;
TCHAR AbSeq[5];
TCHAR GbSeq[5];
TCHAR szMyStrBuf[12 * sizeof(WCHAR) / sizeof(TCHAR)];
RECT GBARInfo;
#ifdef UNICODE
wCode = *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]);
AbSeq[0] = wCode;
AbSeq[1] = TEXT('\0');
// change the CP_ACP to 936, so that it can work under Multilingul Env.
WideCharToMultiByte(NATIVE_ANSI_CP, WC_COMPOSITECHECK, AbSeq, 1, (BYTE*)GbSeq, sizeof(GbSeq), NULL, NULL);
wGB = HIBYTE(GbSeq[0]) | (LOBYTE(GbSeq[0]) << 8);
wsprintf (GbSeq,TEXT("%04lx"),wGB); // get GB string
wGB -= 0xa0a0;
wsprintf (AbSeq,TEXT("%02d%02d"),HIBYTE(wGB),LOBYTE(wGB));
#else
wCode = *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]);
MultiByteToWideChar(CP_ACP, NULL, &wCode, 2, &wGB, 1);
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
wsprintf (GbSeq,"%04lx",wCode); // get GB string
wCode -= 0xa0a0;
wsprintf (AbSeq,"%02d%02d",HIBYTE(wCode),LOBYTE(wCode));
#endif
// if (lpImcP->fdwGB & IME_SELECT_GB) {
#if defined(COMBO_IME)
switch(sImeL.dwRegImeIndex){
case INDEX_GB:
lstrcpy (szMyStrBuf,TEXT("("));
lstrcat (szMyStrBuf,GbSeq);
lstrcat (szMyStrBuf,TEXT(", "));
lstrcat (szMyStrBuf,AbSeq);
lstrcat (szMyStrBuf,TEXT(")"));
iMyLen = 12;
break;
case INDEX_GBK:
lstrcpy (szMyStrBuf,TEXT(" "));
lstrcat (szMyStrBuf,TEXT("("));
lstrcat (szMyStrBuf,GbSeq);
lstrcat (szMyStrBuf,TEXT(")"));
iMyLen = 10;
break;
case INDEX_UNICODE: //adjust code display info
lstrcpy (szMyStrBuf,TEXT("("));
lstrcat (szMyStrBuf,GbSeq);
lstrcat (szMyStrBuf,TEXT(", "));
wsprintf (AbSeq,TEXT("%04lx"),wCode);
lstrcat (szMyStrBuf, AbSeq);
lstrcat (szMyStrBuf,TEXT(")"));
iMyLen = lstrlen(szMyStrBuf);
break;
}
#else //COMBO_IME
#ifdef GB
lstrcpy (szMyStrBuf,TEXT("("));
lstrcat (szMyStrBuf,GbSeq);
lstrcat (szMyStrBuf,TEXT(", "));
lstrcat (szMyStrBuf,AbSeq);
lstrcat (szMyStrBuf,TEXT(")"));
iMyLen = 12;
#else
lstrcpy (szMyStrBuf,TEXT(" "));
lstrcat (szMyStrBuf,TEXT("("));
lstrcat (szMyStrBuf,GbSeq);
lstrcat (szMyStrBuf,TEXT(")"));
iMyLen = 10;
#endif //GB
#endif //COMBO_IME
GBARInfo.top = sImeG.rcCandText.top + i * sImeG.yChiCharHi;
GBARInfo.left = sImeG.rcCandText.left;
GBARInfo.right = sImeG.rcCandText.right;
GBARInfo.bottom = sImeG.rcCandText.bottom;
DrawText(hDC, szMyStrBuf, lstrlen(szMyStrBuf),
&GBARInfo, DT_RIGHT | DT_SINGLELINE);
}
}
} else {
int nX;
ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top + 1,
ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL);
nX = 0;
for (i = 0; dwStart < dwEnd; dwStart++, i++) {
int iLen;
int j, k;
TCHAR AnsiStr[MAXCODE+1];
SIZE StrSize;
// display numbers
AnsiStr[0] = szDigit[i + CAND_START];
AnsiStr[1] = TEXT(':');
AnsiStr[2] = 0;
ExtTextOut(hDC, sImeG.rcCandText.left + nX,
sImeG.rcCandText.top + 1,
ETO_CLIPPED, &sImeG.rcCandText,
AnsiStr,
lstrlen(AnsiStr), NULL);
if(!GetTextExtentPoint(hDC, (LPCTSTR)AnsiStr, lstrlen(AnsiStr), &StrSize))
memset(&StrSize, 0, sizeof(SIZE));
nX += StrSize.cx;
// display chinese word and code
iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
lpCandList->dwOffset[dwStart]));
CopyMemory(szStrBuf,
((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]),
iLen*sizeof(TCHAR));
for(j=0; j<iLen; j++) {
#ifdef UNICODE
if(szStrBuf[j] > 0x100) {
#else
if(szStrBuf[j] & 0x80) {
#endif
j++;
continue;
}
break;
}
k = j-1;
for(j=0; j<iLen - k; j++) {
AnsiStr[j] = szStrBuf[j+k];
}
AnsiStr[j] = 0;
szStrBuf[k] = 0;
ExtTextOut(hDC, sImeG.rcCandText.left + nX,
sImeG.rcCandText.top + 1,
ETO_CLIPPED, &sImeG.rcCandText,
szStrBuf,
lstrlen(szStrBuf), NULL);
if(!GetTextExtentPoint(hDC, (LPCTSTR)szStrBuf, lstrlen(szStrBuf), &StrSize))
memset(&StrSize, 0, sizeof(SIZE));
nX += StrSize.cx;
ExtTextOut(hDC, sImeG.rcCandText.left + nX,
sImeG.rcCandText.top + 1,
ETO_CLIPPED, &sImeG.rcCandText,
AnsiStr,
lstrlen(AnsiStr), NULL);
if(!GetTextExtentPoint(hDC, (LPCTSTR)AnsiStr, lstrlen(AnsiStr), &StrSize))
memset(&StrSize, 0, sizeof(SIZE));
nX += StrSize.cx;
}
}
// load all bitmap
if (sImeG.IC_Trace) {
hCandInfBmp = LoadBitmap(hInst, TEXT("Candinf"));
} else {
hCandInfBmp = NULL;
}
hMemDC = CreateCompatibleDC(hDC);
if ( hMemDC != NULL )
{
hCandIconBmp = LoadBitmap(hInst, TEXT("CandSel"));
if ( hCandIconBmp )
{
hOldBmp = SelectObject(hMemDC, hCandIconBmp);
BitBlt(hDC, sImeG.rcCandIcon.left, sImeG.rcCandIcon.top,
sImeG.rcCandIcon.right - sImeG.rcCandIcon.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandIconBmp);
}
if(hCandInfBmp) {
hOldBmp = SelectObject(hMemDC, hCandInfBmp);
BitBlt(hDC, sImeG.rcCandInf.left, sImeG.rcCandInf.top,
sImeG.rcCandInf.right - sImeG.rcCandInf.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
}
hCandHBmp = LoadBitmap(hInst, TEXT("CandH"));
if ( hCandHBmp )
{
hOldBmp = SelectObject(hMemDC, hCandHBmp);
BitBlt(hDC, sImeG.rcCandBTH.left, sImeG.rcCandBTH.top,
sImeG.rcCandBTH.right - sImeG.rcCandBTH.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandHBmp);
}
hCandUBmp = LoadBitmap(hInst, TEXT("CandU"));
if ( hCandUBmp )
{
hOldBmp = SelectObject(hMemDC, hCandUBmp);
BitBlt(hDC, sImeG.rcCandBTU.left, sImeG.rcCandBTU.top,
sImeG.rcCandBTU.right - sImeG.rcCandBTU.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandUBmp);
}
hCandDBmp = LoadBitmap(hInst, TEXT("CandD"));
if ( hCandDBmp )
{
hOldBmp = SelectObject(hMemDC, hCandDBmp);
BitBlt(hDC, sImeG.rcCandBTD.left, sImeG.rcCandBTD.top,
sImeG.rcCandBTD.right - sImeG.rcCandBTD.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandDBmp);
}
hCandEBmp = LoadBitmap(hInst, TEXT("CandE"));
if ( hCandEBmp )
{
hOldBmp = SelectObject(hMemDC, hCandEBmp);
BitBlt(hDC, sImeG.rcCandBTE.left, sImeG.rcCandBTE.top,
sImeG.rcCandBTE.right - sImeG.rcCandBTE.left,
STATUS_DIM_Y,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteObject(hCandEBmp);
}
DeleteDC(hMemDC);
}
if ( hCandInfBmp )
DeleteObject(hCandInfBmp);
if (sImeG.fDiffSysCharSet) {
DeleteObject(SelectObject(hDC, hOldFont));
}
ImmUnlockIMCC(lpIMC->hPrivate);
UpCandW2UnlockCandInfo:
ImmUnlockIMCC(lpIMC->hCandInfo);
UpCandW2UnlockIMC:
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* CandWndProc() */
/**********************************************************************/
LRESULT CALLBACK CandWndProc(
HWND hCandWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_DESTROY:
DestroyCandWindow(hCandWnd);
break;
case WM_SETCURSOR:
CandSetCursor(hCandWnd, lParam);
break;
case WM_MOUSEMOVE:
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
POINT ptCursor;
DrawDragBorder(hCandWnd,
GetWindowLong(hCandWnd, UI_MOVE_XY),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
GetCursorPos(&ptCursor);
SetWindowLong(hCandWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
} else {
return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
}
break;
case WM_LBUTTONUP:
if (!CandButtonUp(hCandWnd)) {
return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
}
break;
case WM_IME_NOTIFY:
if (wParam == IMN_SETCANDIDATEPOS) {
return SetCandPosition(hCandWnd);
}
break;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hCandWnd, &ps);
PaintCandWindow(hCandWnd, hDC);
EndPaint(hCandWnd, &ps);
}
break;
case WM_MOUSEACTIVATE:
return (MA_NOACTIVATE);
default:
return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
}
return (0L);
}