📄 candui.c
字号:
/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
candui.c
++*/
#include <windows.h>
#include <imm.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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -