420 lines
14 KiB
C
420 lines
14 KiB
C
/*++
|
|
|
|
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
|
|
|
|
Module Name:
|
|
|
|
UICAND.C
|
|
|
|
++*/
|
|
|
|
/**********************************************************************/
|
|
#include "windows.h"
|
|
#include "immdev.h"
|
|
#include "fakeime.h"
|
|
|
|
int PASCAL GetCompFontHeight(LPUIEXTRA lpUIExtra);
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* CandWndProc() */
|
|
/* IME UI window procedure */
|
|
/* */
|
|
/**********************************************************************/
|
|
LRESULT CALLBACK CandWndProc( hWnd, message, wParam, lParam )
|
|
HWND hWnd;
|
|
UINT message;
|
|
WPARAM wParam;
|
|
LPARAM lParam;
|
|
{
|
|
HWND hUIWnd;
|
|
|
|
switch (message)
|
|
{
|
|
case WM_PAINT:
|
|
PaintCandWindow(hWnd);
|
|
break;
|
|
|
|
case WM_SETCURSOR:
|
|
case WM_MOUSEMOVE:
|
|
case WM_LBUTTONUP:
|
|
case WM_RBUTTONUP:
|
|
DragUI(hWnd,message,wParam,lParam);
|
|
if ((message == WM_SETCURSOR) &&
|
|
(HIWORD(lParam) != WM_LBUTTONDOWN) &&
|
|
(HIWORD(lParam) != WM_RBUTTONDOWN))
|
|
return DefWindowProc(hWnd,message,wParam,lParam);
|
|
if ((message == WM_LBUTTONUP) || (message == WM_RBUTTONUP))
|
|
SetWindowLong(hWnd,FIGWL_MOUSE,0L);
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
hUIWnd = (HWND)GetWindowLongPtr(hWnd,FIGWL_SVRWND);
|
|
if (IsWindow(hUIWnd))
|
|
SendMessage(hUIWnd,WM_UI_CANDMOVE,wParam,lParam);
|
|
break;
|
|
|
|
default:
|
|
if (!MyIsIMEMessage(message))
|
|
return DefWindowProc(hWnd,message,wParam,lParam);
|
|
break;
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* GetCandPosFromCompWnd() */
|
|
/* */
|
|
/**********************************************************************/
|
|
BOOL PASCAL GetCandPosFromCompWnd(LPUIEXTRA lpUIExtra,LPPOINT lppt)
|
|
{
|
|
RECT rc;
|
|
|
|
if (lpUIExtra->dwCompStyle)
|
|
{
|
|
if (lpUIExtra->uiComp[0].bShow)
|
|
{
|
|
GetWindowRect(lpUIExtra->uiComp[0].hWnd,&rc);
|
|
lppt->x = rc.left;
|
|
lppt->y = rc.bottom+1;
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lpUIExtra->uiDefComp.bShow)
|
|
{
|
|
GetWindowRect(lpUIExtra->uiDefComp.hWnd,&rc);
|
|
lppt->x = rc.left;
|
|
lppt->y = rc.bottom+1;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* GetCandPosFromCompForm() */
|
|
/* */
|
|
/**********************************************************************/
|
|
BOOL PASCAL GetCandPosFromCompForm(LPINPUTCONTEXT lpIMC, LPUIEXTRA lpUIExtra,LPPOINT lppt)
|
|
{
|
|
if (lpUIExtra->dwCompStyle)
|
|
{
|
|
if (lpIMC && lpIMC->fdwInit & INIT_COMPFORM)
|
|
{
|
|
if (!lpUIExtra->bVertical)
|
|
{
|
|
lppt->x = lpIMC->cfCompForm.ptCurrentPos.x;
|
|
lppt->y = lpIMC->cfCompForm.ptCurrentPos.y +
|
|
GetCompFontHeight(lpUIExtra);
|
|
}
|
|
else
|
|
{
|
|
lppt->x = lpIMC->cfCompForm.ptCurrentPos.x -
|
|
GetCompFontHeight(lpUIExtra);
|
|
lppt->y = lpIMC->cfCompForm.ptCurrentPos.y;
|
|
}
|
|
return TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GetCandPosFromCompWnd(lpUIExtra,lppt))
|
|
{
|
|
ScreenToClient(lpIMC->hWnd,lppt);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* CreateCandWindow() */
|
|
/* */
|
|
/**********************************************************************/
|
|
void PASCAL CreateCandWindow( HWND hUIWnd,LPUIEXTRA lpUIExtra, LPINPUTCONTEXT lpIMC )
|
|
{
|
|
POINT pt;
|
|
|
|
if (GetCandPosFromCompWnd(lpUIExtra,&pt))
|
|
{
|
|
lpUIExtra->uiCand.pt.x = pt.x;
|
|
lpUIExtra->uiCand.pt.y = pt.y;
|
|
}
|
|
|
|
if (!IsWindow(lpUIExtra->uiCand.hWnd))
|
|
{
|
|
lpUIExtra->uiCand.hWnd =
|
|
CreateWindowEx(WS_EX_WINDOWEDGE,
|
|
(LPTSTR)szCandClassName,NULL,
|
|
WS_COMPDEFAULT | WS_DLGFRAME,
|
|
lpUIExtra->uiCand.pt.x,
|
|
lpUIExtra->uiCand.pt.y,
|
|
1,1,
|
|
hUIWnd,NULL,hInst,NULL);
|
|
}
|
|
|
|
SetWindowLongPtr(lpUIExtra->uiCand.hWnd,FIGWL_SVRWND,(LONG_PTR)hUIWnd);
|
|
ShowWindow(lpUIExtra->uiCand.hWnd, SW_HIDE);
|
|
lpUIExtra->uiCand.bShow = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* PaintCandWindow() */
|
|
/* */
|
|
/**********************************************************************/
|
|
void PASCAL PaintCandWindow( HWND hCandWnd)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HIMC hIMC;
|
|
LPINPUTCONTEXT lpIMC;
|
|
LPCANDIDATEINFO lpCandInfo;
|
|
LPCANDIDATELIST lpCandList;
|
|
HBRUSH hbr;
|
|
HDC hDC;
|
|
RECT rc;
|
|
LPMYSTR lpstr;
|
|
int height;
|
|
DWORD i;
|
|
SIZE sz;
|
|
HWND hSvrWnd;
|
|
HBRUSH hbrHightLight = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
|
|
HBRUSH hbrLGR = GetStockObject(LTGRAY_BRUSH);
|
|
HFONT hOldFont;
|
|
|
|
GetClientRect(hCandWnd,&rc);
|
|
hDC = BeginPaint(hCandWnd,&ps);
|
|
SetBkMode(hDC,TRANSPARENT);
|
|
hSvrWnd = (HWND)GetWindowLongPtr(hCandWnd,FIGWL_SVRWND);
|
|
|
|
if (hIMC = (HIMC)GetWindowLongPtr(hSvrWnd,IMMGWLP_IMC))
|
|
{
|
|
lpIMC = ImmLockIMC(hIMC);
|
|
hOldFont = CheckNativeCharset(hDC);
|
|
if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo))
|
|
{
|
|
height = GetSystemMetrics(SM_CYEDGE);
|
|
lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]);
|
|
for (i = lpCandList->dwPageStart;
|
|
i < (lpCandList->dwPageStart + lpCandList->dwPageSize); i++)
|
|
{
|
|
lpstr = (LPMYSTR)((LPSTR)lpCandList + lpCandList->dwOffset[i]);
|
|
MyGetTextExtentPoint(hDC,lpstr,Mylstrlen(lpstr),&sz);
|
|
if (((LPMYCAND)lpCandInfo)->cl.dwSelection == (DWORD)i)
|
|
{
|
|
hbr = SelectObject(hDC,hbrHightLight);
|
|
PatBlt(hDC,0,height,rc.right,sz.cy,PATCOPY);
|
|
SelectObject(hDC,hbr);
|
|
SetTextColor(hDC,GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
else
|
|
{
|
|
hbr = SelectObject(hDC,hbrLGR);
|
|
PatBlt(hDC,0,height,rc.right,sz.cy,PATCOPY);
|
|
SelectObject(hDC,hbr);
|
|
SetTextColor(hDC,RGB(0,0,0));
|
|
}
|
|
MyTextOut(hDC,GetSystemMetrics(SM_CXEDGE),height,lpstr,Mylstrlen(lpstr));
|
|
height += sz.cy;
|
|
}
|
|
ImmUnlockIMCC(lpIMC->hCandInfo);
|
|
}
|
|
if (hOldFont) {
|
|
DeleteObject(SelectObject(hDC, hOldFont));
|
|
}
|
|
ImmUnlockIMC(hIMC);
|
|
}
|
|
EndPaint(hCandWnd,&ps);
|
|
|
|
DeleteObject(hbrHightLight);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* ResizeCandWindow() */
|
|
/* */
|
|
/**********************************************************************/
|
|
void PASCAL ResizeCandWindow( LPUIEXTRA lpUIExtra,LPINPUTCONTEXT lpIMC )
|
|
{
|
|
LPCANDIDATEINFO lpCandInfo;
|
|
LPCANDIDATELIST lpCandList;
|
|
HDC hDC;
|
|
LPMYSTR lpstr;
|
|
int width;
|
|
int height;
|
|
DWORD i;
|
|
RECT rc;
|
|
SIZE sz;
|
|
|
|
if (IsWindow(lpUIExtra->uiCand.hWnd))
|
|
{
|
|
HFONT hOldFont;
|
|
|
|
hDC = GetDC(lpUIExtra->uiCand.hWnd);
|
|
hOldFont = CheckNativeCharset(hDC);
|
|
|
|
if (lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo))
|
|
{
|
|
width = 0;
|
|
height = 0;
|
|
lpCandList = (LPCANDIDATELIST)((LPSTR)lpCandInfo + lpCandInfo->dwOffset[0]);
|
|
for (i = lpCandList->dwPageStart;
|
|
i < (lpCandList->dwPageStart + lpCandList->dwPageSize); i++)
|
|
{
|
|
lpstr = (LPMYSTR)((LPSTR)lpCandList + lpCandList->dwOffset[i]);
|
|
MyGetTextExtentPoint(hDC,lpstr,Mylstrlen(lpstr),&sz);
|
|
if (width < sz.cx)
|
|
width = sz.cx;
|
|
height += sz.cy;
|
|
}
|
|
ImmUnlockIMCC(lpIMC->hCandInfo);
|
|
}
|
|
if (hOldFont) {
|
|
DeleteObject(SelectObject(hDC, hOldFont));
|
|
}
|
|
ReleaseDC(lpUIExtra->uiCand.hWnd,hDC);
|
|
|
|
GetWindowRect(lpUIExtra->uiCand.hWnd,&rc);
|
|
MoveWindow(lpUIExtra->uiCand.hWnd,
|
|
rc.left,
|
|
rc.top,
|
|
width+ 4 * GetSystemMetrics(SM_CXEDGE),
|
|
height+ 4 * GetSystemMetrics(SM_CYEDGE),
|
|
TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* HideCandWindow() */
|
|
/* */
|
|
/**********************************************************************/
|
|
void PASCAL HideCandWindow( LPUIEXTRA lpUIExtra)
|
|
{
|
|
RECT rc;
|
|
|
|
if (IsWindow(lpUIExtra->uiCand.hWnd))
|
|
{
|
|
GetWindowRect(lpUIExtra->uiCand.hWnd,(LPRECT)&rc);
|
|
lpUIExtra->uiCand.pt.x = rc.left;
|
|
lpUIExtra->uiCand.pt.y = rc.top;
|
|
MoveWindow(lpUIExtra->uiCand.hWnd, -1 , -1 , 0 , 0, TRUE);
|
|
ShowWindow(lpUIExtra->uiCand.hWnd, SW_HIDE);
|
|
lpUIExtra->uiCand.bShow = FALSE;
|
|
}
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/* */
|
|
/* MoveCandWindow() */
|
|
/* */
|
|
/**********************************************************************/
|
|
void PASCAL MoveCandWindow(HWND hUIWnd, LPINPUTCONTEXT lpIMC, LPUIEXTRA lpUIExtra, BOOL fForceComp)
|
|
{
|
|
RECT rc;
|
|
POINT pt;
|
|
CANDIDATEFORM caf;
|
|
|
|
if (fForceComp)
|
|
{
|
|
if (GetCandPosFromCompForm(lpIMC, lpUIExtra, &pt))
|
|
{
|
|
caf.dwIndex = 0;
|
|
caf.dwStyle = CFS_CANDIDATEPOS;
|
|
caf.ptCurrentPos.x = pt.x;
|
|
caf.ptCurrentPos.y = pt.y;
|
|
ImmSetCandidateWindow(lpUIExtra->hIMC,&caf);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Not initialized !!
|
|
if (lpIMC->cfCandForm[0].dwIndex == -1)
|
|
{
|
|
if (GetCandPosFromCompWnd(lpUIExtra,&pt))
|
|
{
|
|
lpUIExtra->uiCand.pt.x = pt.x;
|
|
lpUIExtra->uiCand.pt.y = pt.y;
|
|
GetWindowRect(lpUIExtra->uiCand.hWnd,&rc);
|
|
MoveWindow(lpUIExtra->uiCand.hWnd,pt.x,pt.y, rc.right - rc.left ,rc.bottom - rc.top ,TRUE);
|
|
ShowWindow(lpUIExtra->uiCand.hWnd,SW_SHOWNOACTIVATE);
|
|
lpUIExtra->uiCand.bShow = TRUE;
|
|
InvalidateRect(lpUIExtra->uiCand.hWnd,NULL,FALSE);
|
|
SendMessage(hUIWnd,WM_UI_CANDMOVE, 0,MAKELONG((WORD)pt.x,(WORD)pt.y));
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!IsCandidate(lpIMC))
|
|
return;
|
|
|
|
if (lpIMC->cfCandForm[0].dwStyle == CFS_EXCLUDE)
|
|
{
|
|
RECT rcWork;
|
|
RECT rcAppWnd;
|
|
|
|
SystemParametersInfo(SPI_GETWORKAREA,0,&rcWork,FALSE);
|
|
GetClientRect(lpUIExtra->uiCand.hWnd,&rc);
|
|
GetWindowRect(lpIMC->hWnd,&rcAppWnd);
|
|
|
|
if (!lpUIExtra->bVertical)
|
|
{
|
|
pt.x = lpIMC->cfCandForm[0].ptCurrentPos.x;
|
|
pt.y = lpIMC->cfCandForm[0].rcArea.bottom;
|
|
ClientToScreen(lpIMC->hWnd,&pt);
|
|
|
|
if (pt.y + rc.bottom > rcWork.bottom)
|
|
pt.y = rcAppWnd.top +
|
|
lpIMC->cfCandForm[0].rcArea.top - rc.bottom;
|
|
}
|
|
else
|
|
{
|
|
pt.x = lpIMC->cfCandForm[0].rcArea.left - rc.right;
|
|
pt.y = lpIMC->cfCandForm[0].ptCurrentPos.y;
|
|
ClientToScreen(lpIMC->hWnd,&pt);
|
|
|
|
if (pt.x < 0)
|
|
pt.x = rcAppWnd.left +
|
|
lpIMC->cfCandForm[0].rcArea.right;
|
|
}
|
|
|
|
|
|
if (IsWindow(lpUIExtra->uiCand.hWnd))
|
|
{
|
|
GetWindowRect(lpUIExtra->uiCand.hWnd,&rc);
|
|
MoveWindow(lpUIExtra->uiCand.hWnd,pt.x,pt.y, rc.right - rc.left ,rc.bottom - rc.top ,TRUE);
|
|
ShowWindow(lpUIExtra->uiCand.hWnd,SW_SHOWNOACTIVATE);
|
|
lpUIExtra->uiCand.bShow = TRUE;
|
|
InvalidateRect(lpUIExtra->uiCand.hWnd,NULL,FALSE);
|
|
|
|
}
|
|
SendMessage(hUIWnd,WM_UI_CANDMOVE, 0,MAKELONG((WORD)pt.x,(WORD)pt.y));
|
|
}
|
|
else if (lpIMC->cfCandForm[0].dwStyle == CFS_CANDIDATEPOS)
|
|
{
|
|
pt.x = lpIMC->cfCandForm[0].ptCurrentPos.x;
|
|
pt.y = lpIMC->cfCandForm[0].ptCurrentPos.y;
|
|
ClientToScreen(lpIMC->hWnd,&pt);
|
|
|
|
if (IsWindow(lpUIExtra->uiCand.hWnd))
|
|
{
|
|
GetWindowRect(lpUIExtra->uiCand.hWnd,&rc);
|
|
MoveWindow(lpUIExtra->uiCand.hWnd,pt.x,pt.y, rc.right - rc.left ,rc.bottom - rc.top ,TRUE);
|
|
ShowWindow(lpUIExtra->uiCand.hWnd,SW_SHOWNOACTIVATE);
|
|
lpUIExtra->uiCand.bShow = TRUE;
|
|
InvalidateRect(lpUIExtra->uiCand.hWnd,NULL,FALSE);
|
|
|
|
}
|
|
SendMessage(hUIWnd,WM_UI_CANDMOVE, 0,MAKELONG((WORD)pt.x,(WORD)pt.y));
|
|
}
|
|
}
|