windows-nt/Source/XPSP1/NT/windows/feime/ddk/jpn/ui.c
2020-09-26 16:20:57 +08:00

912 lines
31 KiB
C

/*++
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
Module Name:
UI.C
++*/
/**********************************************************************/
#include "windows.h"
#include "immdev.h"
#include "fakeime.h"
void PASCAL ShowUIWindows(HWND hWnd, BOOL fFlag);
#ifdef DEBUG
void PASCAL DumpUIExtra(LPUIEXTRA lpUIExtra);
#endif
#define CS_FAKEIME (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_IME)
/**********************************************************************/
/* */
/* IMERegisterClass() */
/* */
/* This function is called by IMMInquire. */
/* Register the classes for the child windows. */
/* Create global GDI objects. */
/* */
/**********************************************************************/
BOOL IMERegisterClass( hInstance )
HANDLE hInstance;
{
WNDCLASSEX wc;
//
// register class of UI window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FAKEIME;
wc.lpfnWndProc = FAKEIMEWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 8;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPTSTR)NULL;
wc.lpszClassName = (LPTSTR)szUIClassName;
wc.hbrBackground = NULL;
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of composition window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FAKEIME;
wc.lpfnWndProc = CompStrWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UIEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPTSTR)NULL;
wc.lpszClassName = (LPTSTR)szCompStrClassName;
wc.hbrBackground = NULL;
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of candidate window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FAKEIME;
wc.lpfnWndProc = CandWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UIEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPTSTR)NULL;
wc.lpszClassName = (LPTSTR)szCandClassName;
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of status window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FAKEIME;
wc.lpfnWndProc = StatusWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UIEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPTSTR)NULL;
wc.lpszClassName = (LPTSTR)szStatusClassName;
wc.hbrBackground = NULL;
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of guideline window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FAKEIME;
wc.lpfnWndProc = GuideWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UIEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPTSTR)NULL;
wc.lpszClassName = (LPTSTR)szGuideClassName;
wc.hbrBackground = NULL;
//wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
return TRUE;
}
/**********************************************************************/
/* */
/* FAKEIMEWndProc() */
/* */
/* IME UI window procedure */
/* */
/**********************************************************************/
LRESULT CALLBACK FAKEIMEWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
HIMC hUICurIMC;
LPINPUTCONTEXT lpIMC;
LPUIEXTRA lpUIExtra;
HGLOBAL hUIExtra;
LONG lRet = 0L;
int i;
hUICurIMC = (HIMC)GetWindowLongPtr(hWnd,IMMGWLP_IMC);
//
// Even if there is no current UI. these messages should not be pass to
// DefWindowProc().
//
if (!hUICurIMC)
{
switch (message)
{
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_NOTIFY:
case WM_IME_CONTROL:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case WM_IME_CHAR:
#ifdef _DEBUG
{
TCHAR szDev[80];
OutputDebugString((LPTSTR)TEXT("Why hUICurIMC is NULL????\r\n"));
wsprintf((LPTSTR)szDev,TEXT("\thWnd is %x\r\n"),hWnd);
OutputDebugString((LPTSTR)szDev);
wsprintf((LPTSTR)szDev,TEXT("\tmessage is %x\r\n"),message);
OutputDebugString((LPTSTR)szDev);
wsprintf((LPTSTR)szDev,TEXT("\twParam is %x\r\n"),wParam);
OutputDebugString((LPTSTR)szDev);
wsprintf((LPTSTR)szDev,TEXT("\tlParam is %x\r\n"),lParam);
OutputDebugString((LPTSTR)szDev);
}
#endif
return 0L;
default:
break;
}
}
switch (message)
{
case WM_CREATE:
//
// Allocate UI's extra memory block.
//
hUIExtra = GlobalAlloc(GHND,sizeof(UIEXTRA));
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
//
// Initialize the extra memory block.
//
lpUIExtra->uiStatus.pt.x = -1;
lpUIExtra->uiStatus.pt.y = -1;
lpUIExtra->uiDefComp.pt.x = -1;
lpUIExtra->uiDefComp.pt.y = -1;
lpUIExtra->uiCand.pt.x = -1;
lpUIExtra->uiCand.pt.y = -1;
lpUIExtra->uiGuide.pt.x = -1;
lpUIExtra->uiGuide.pt.y = -1;
lpUIExtra->hFont = (HFONT)NULL;
GlobalUnlock(hUIExtra);
SetWindowLongPtr(hWnd,IMMGWLP_PRIVATE,(LONG_PTR)hUIExtra);
break;
case WM_IME_SETCONTEXT:
if (wParam)
{
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->hIMC = hUICurIMC;
if (hUICurIMC)
{
LPINPUTCONTEXT lpIMCT = NULL;
//
// input context was chenged.
// if there are the child windows, the diplay have to be
// updated.
//
lpIMC = ImmLockIMC(hUICurIMC);
if (lpIMC)
{
LPCOMPOSITIONSTRING lpCompStr;
LPCANDIDATEINFO lpCandInfo;
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (IsWindow(lpUIExtra->uiCand.hWnd))
HideCandWindow(lpUIExtra);
if (lParam & ISC_SHOWUICANDIDATEWINDOW)
{
if (lpCandInfo->dwCount)
{
CreateCandWindow(hWnd,lpUIExtra,lpIMC );
ResizeCandWindow(lpUIExtra,lpIMC);
MoveCandWindow(hWnd,lpIMC,lpUIExtra,FALSE);
}
}
if (IsWindow(lpUIExtra->uiDefComp.hWnd))
HideCompWindow(lpUIExtra);
if (lParam & ISC_SHOWUICANDIDATEWINDOW)
{
if (lpCompStr->dwCompStrLen)
{
CreateCompWindow(hWnd,lpUIExtra,lpIMC );
MoveCompWindow(lpUIExtra,lpIMC);
}
}
ImmUnlockIMCC(lpIMC->hCompStr);
ImmUnlockIMCC(lpIMC->hCandInfo);
}
else
{
HideCandWindow(lpUIExtra);
HideCompWindow(lpUIExtra);
}
UpdateStatusWindow(lpUIExtra);
ImmUnlockIMC(hUICurIMC);
}
else // it is NULL input context.
{
HideCandWindow(lpUIExtra);
HideCompWindow(lpUIExtra);
}
GlobalUnlock(hUIExtra);
}
//else
// ShowUIWindows(hWnd, FALSE);
break;
case WM_IME_STARTCOMPOSITION:
//
// Start composition! Ready to display the composition string.
//
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpIMC = ImmLockIMC(hUICurIMC);
CreateCompWindow(hWnd,lpUIExtra,lpIMC );
ImmUnlockIMC(hUICurIMC);
GlobalUnlock(hUIExtra);
break;
case WM_IME_COMPOSITION:
//
// Update to display the composition string.
//
lpIMC = ImmLockIMC(hUICurIMC);
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
MoveCompWindow(lpUIExtra,lpIMC);
MoveCandWindow(hWnd,lpIMC,lpUIExtra, TRUE);
GlobalUnlock(hUIExtra);
ImmUnlockIMC(hUICurIMC);
break;
case WM_IME_ENDCOMPOSITION:
//
// Finish to display the composition string.
//
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
HideCompWindow(lpUIExtra);
GlobalUnlock(hUIExtra);
break;
case WM_IME_COMPOSITIONFULL:
break;
case WM_IME_SELECT:
if (wParam)
{
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->hIMC = hUICurIMC;
GlobalUnlock(hUIExtra);
}
break;
case WM_IME_CONTROL:
lRet = ControlCommand(hUICurIMC, hWnd,message,wParam,lParam);
break;
case WM_IME_NOTIFY:
lRet = NotifyCommand(hUICurIMC, hWnd,message,wParam,lParam);
break;
case WM_DESTROY:
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
if (IsWindow(lpUIExtra->uiStatus.hWnd))
DestroyWindow(lpUIExtra->uiStatus.hWnd);
if (IsWindow(lpUIExtra->uiCand.hWnd))
DestroyWindow(lpUIExtra->uiCand.hWnd);
if (IsWindow(lpUIExtra->uiDefComp.hWnd))
DestroyWindow(lpUIExtra->uiDefComp.hWnd);
for (i = 0; i < MAXCOMPWND; i++)
{
if (IsWindow(lpUIExtra->uiComp[i].hWnd))
DestroyWindow(lpUIExtra->uiComp[i].hWnd);
}
if (IsWindow(lpUIExtra->uiGuide.hWnd))
DestroyWindow(lpUIExtra->uiGuide.hWnd);
if (lpUIExtra->hFont)
DeleteObject(lpUIExtra->hFont);
GlobalUnlock(hUIExtra);
GlobalFree(hUIExtra);
break;
case WM_UI_STATEMOVE:
//
// Set the position of the status window to UIExtra.
// This message is sent by the status window.
//
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->uiStatus.pt.x = (long)LOWORD(lParam);
lpUIExtra->uiStatus.pt.y = (long)HIWORD(lParam);
GlobalUnlock(hUIExtra);
break;
case WM_UI_DEFCOMPMOVE:
//
// Set the position of the composition window to UIExtra.
// This message is sent by the composition window.
//
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
if (!lpUIExtra->dwCompStyle)
{
lpUIExtra->uiDefComp.pt.x = (long)LOWORD(lParam);
lpUIExtra->uiDefComp.pt.y = (long)HIWORD(lParam);
}
GlobalUnlock(hUIExtra);
break;
case WM_UI_CANDMOVE:
//
// Set the position of the candidate window to UIExtra.
// This message is sent by the candidate window.
//
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->uiCand.pt.x = (long)LOWORD(lParam);
lpUIExtra->uiCand.pt.y = (long)HIWORD(lParam);
GlobalUnlock(hUIExtra);
break;
case WM_UI_GUIDEMOVE:
//
// Set the position of the status window to UIExtra.
// This message is sent by the status window.
//
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->uiGuide.pt.x = (long)LOWORD(lParam);
lpUIExtra->uiGuide.pt.y = (long)HIWORD(lParam);
GlobalUnlock(hUIExtra);
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return lRet;
}
int PASCAL GetCompFontHeight(LPUIEXTRA lpUIExtra)
{
HDC hIC;
HFONT hOldFont = 0;
SIZE sz;
hIC = CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);
if (lpUIExtra->hFont)
hOldFont = SelectObject(hIC,lpUIExtra->hFont);
GetTextExtentPoint(hIC,TEXT("A"),1,&sz);
if (hOldFont)
SelectObject(hIC,hOldFont);
DeleteDC(hIC);
return sz.cy;
}
/**********************************************************************/
/* */
/* NotifyCommand() */
/* */
/* Handle WM_IME_NOTIFY messages. */
/* */
/**********************************************************************/
LONG PASCAL NotifyCommand(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 0L;
LPINPUTCONTEXT lpIMC;
HGLOBAL hUIExtra;
LPUIEXTRA lpUIExtra;
RECT rc;
LOGFONT lf;
if (!(lpIMC = ImmLockIMC(hUICurIMC)))
return 0L;
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
switch (wParam)
{
case IMN_CLOSESTATUSWINDOW:
if (IsWindow(lpUIExtra->uiStatus.hWnd))
{
GetWindowRect(lpUIExtra->uiStatus.hWnd,(LPRECT)&rc);
lpUIExtra->uiStatus.pt.x = rc.left;
lpUIExtra->uiStatus.pt.y = rc.top;
ShowWindow(lpUIExtra->uiStatus.hWnd,SW_HIDE);
lpUIExtra->uiStatus.bShow = FALSE;
}
break;
case IMN_OPENSTATUSWINDOW:
if (lpUIExtra->uiStatus.pt.x == -1)
{
GetWindowRect(lpIMC->hWnd,&rc);
lpUIExtra->uiStatus.pt.x = rc.right + 1;
lpUIExtra->uiStatus.pt.y = rc.top;
}
if (!IsWindow(lpUIExtra->uiStatus.hWnd))
{
lpUIExtra->uiStatus.hWnd =
CreateWindowEx( WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME,
(LPTSTR)szStatusClassName,NULL,
WS_DISABLED | WS_POPUP | WS_BORDER ,
lpUIExtra->uiStatus.pt.x,
lpUIExtra->uiStatus.pt.y,
BTX * 3 + 2 * GetSystemMetrics(SM_CXBORDER)
+ 2 * GetSystemMetrics(SM_CXEDGE),
BTX + GetSystemMetrics(SM_CYSMCAPTION)
+ 2 * GetSystemMetrics(SM_CYBORDER)
+ 2 * GetSystemMetrics(SM_CYEDGE),
hWnd,NULL,hInst,NULL);
}
ShowWindow(lpUIExtra->uiStatus.hWnd,SW_SHOWNOACTIVATE);
lpUIExtra->uiStatus.bShow = TRUE;
SetWindowLongPtr(lpUIExtra->uiStatus.hWnd,FIGWL_SVRWND,(LONG_PTR)hWnd);
break;
case IMN_SETCONVERSIONMODE:
UpdateStatusWindow(lpUIExtra);
break;
case IMN_SETSENTENCEMODE:
break;
case IMN_SETCOMPOSITIONFONT:
#if defined(UNICODE)
lf = lpIMC->lfFont.W;
#else
lf = lpIMC->lfFont.A;
#endif
if (lpUIExtra->hFont)
DeleteObject(lpUIExtra->hFont);
if (lf.lfEscapement == 2700)
lpUIExtra->bVertical = TRUE;
else
{
lf.lfEscapement = 0;
lpUIExtra->bVertical = FALSE;
}
//
// if current font can't display Japanese characters,
// try to find Japanese font
//
if (lf.lfCharSet != NATIVE_CHARSET) {
lf.lfCharSet = NATIVE_CHARSET;
lf.lfFaceName[0] = TEXT('\0');
}
lpUIExtra->hFont = CreateFontIndirect((LPLOGFONT)&lf);
SetFontCompWindow(lpUIExtra);
MoveCompWindow(lpUIExtra,lpIMC);
break;
case IMN_SETOPENSTATUS:
UpdateStatusWindow(lpUIExtra);
break;
case IMN_OPENCANDIDATE:
CreateCandWindow(hWnd,lpUIExtra,lpIMC );
break;
case IMN_CHANGECANDIDATE:
ResizeCandWindow(lpUIExtra,lpIMC);
MoveCandWindow(hWnd,lpIMC,lpUIExtra, FALSE);
break;
case IMN_CLOSECANDIDATE:
HideCandWindow(lpUIExtra);
break;
case IMN_GUIDELINE:
if (ImmGetGuideLine(hUICurIMC,GGL_LEVEL,NULL,0))
{
if (!IsWindow(lpUIExtra->uiGuide.hWnd))
{
HDC hdcIC;
TEXTMETRIC tm;
int dx,dy;
if (lpUIExtra->uiGuide.pt.x == -1)
{
GetWindowRect(lpIMC->hWnd,&rc);
lpUIExtra->uiGuide.pt.x = rc.left;
lpUIExtra->uiGuide.pt.y = rc.bottom;
}
hdcIC = CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);
GetTextMetrics(hdcIC,&tm);
dx = tm.tmAveCharWidth * MAXGLCHAR;
dy = tm.tmHeight + tm.tmExternalLeading;
DeleteDC(hdcIC);
lpUIExtra->uiGuide.hWnd =
CreateWindowEx( WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME,
(LPTSTR)szGuideClassName,NULL,
WS_DISABLED | WS_POPUP | WS_BORDER,
lpUIExtra->uiGuide.pt.x,
lpUIExtra->uiGuide.pt.y,
dx + 2 * GetSystemMetrics(SM_CXBORDER)
+ 2 * GetSystemMetrics(SM_CXEDGE),
dy + GetSystemMetrics(SM_CYSMCAPTION)
+ 2 * GetSystemMetrics(SM_CYBORDER)
+ 2 * GetSystemMetrics(SM_CYEDGE),
hWnd,NULL,hInst,NULL);
}
ShowWindow(lpUIExtra->uiGuide.hWnd,SW_SHOWNOACTIVATE);
lpUIExtra->uiGuide.bShow = TRUE;
SetWindowLongPtr(lpUIExtra->uiGuide.hWnd,FIGWL_SVRWND,(LONG_PTR)hWnd);
UpdateGuideWindow(lpUIExtra);
}
break;
case IMN_SETCANDIDATEPOS:
// FAKEIME supports only one candidate list.
if (lParam != 0x01)
break;
MoveCandWindow(hWnd,lpIMC,lpUIExtra, FALSE);
break;
case IMN_SETCOMPOSITIONWINDOW:
MoveCompWindow(lpUIExtra,lpIMC);
MoveCandWindow(hWnd,lpIMC,lpUIExtra, TRUE);
break;
case IMN_SETSTATUSWINDOWPOS:
case IMN_PRIVATE:
break;
default:
break;
}
GlobalUnlock(hUIExtra);
ImmUnlockIMC(hUICurIMC);
return lRet;
}
/**********************************************************************/
/* */
/* ControlCommand() */
/* */
/* Handle WM_IME_CONTROL messages. */
/* */
/**********************************************************************/
#define lpcfCandForm ((LPCANDIDATEFORM)lParam)
LONG PASCAL ControlCommand(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 1L;
LPINPUTCONTEXT lpIMC;
HGLOBAL hUIExtra;
LPUIEXTRA lpUIExtra;
if (!(lpIMC = ImmLockIMC(hUICurIMC)))
return 1L;
hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
switch (wParam)
{
case IMC_GETCANDIDATEPOS:
if (IsWindow(lpUIExtra->uiCand.hWnd))
{
// FAKEIME has only one candidate list.
*(LPCANDIDATEFORM)lParam = lpIMC->cfCandForm[0];
lRet = 0;
}
break;
case IMC_GETCOMPOSITIONWINDOW:
*(LPCOMPOSITIONFORM)lParam = lpIMC->cfCompForm;
lRet = 0;
break;
case IMC_GETSTATUSWINDOWPOS:
lRet = (lpUIExtra->uiStatus.pt.x << 16) & lpUIExtra->uiStatus.pt.x;
break;
default:
break;
}
GlobalUnlock(hUIExtra);
ImmUnlockIMC(hUICurIMC);
return lRet;
}
/**********************************************************************/
/* */
/* DrawUIBorder() */
/* */
/* When draging the child window, this function draws the border. */
/* */
/**********************************************************************/
void PASCAL DrawUIBorder( LPRECT lprc )
{
HDC hDC;
int sbx, sby;
hDC = CreateDC( TEXT("DISPLAY"), NULL, NULL, NULL );
SelectObject( hDC, GetStockObject( GRAY_BRUSH ) );
sbx = GetSystemMetrics( SM_CXBORDER );
sby = GetSystemMetrics( SM_CYBORDER );
PatBlt( hDC, lprc->left,
lprc->top,
lprc->right - lprc->left-sbx,
sby, PATINVERT );
PatBlt( hDC, lprc->right - sbx,
lprc->top,
sbx,
lprc->bottom - lprc->top-sby, PATINVERT );
PatBlt( hDC, lprc->right,
lprc->bottom-sby,
-(lprc->right - lprc->left-sbx),
sby, PATINVERT );
PatBlt( hDC, lprc->left,
lprc->bottom,
sbx,
-(lprc->bottom - lprc->top-sby), PATINVERT );
DeleteDC( hDC );
}
/**********************************************************************/
/* */
/* DragUI(hWnd,message,wParam,lParam) */
/* */
/* Handling mouse messages for the child windows. */
/* */
/**********************************************************************/
void PASCAL DragUI( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT pt;
static POINT ptdif;
static RECT drc;
static RECT rc;
DWORD dwT;
switch (message)
{
case WM_SETCURSOR:
if ( HIWORD(lParam) == WM_LBUTTONDOWN
|| HIWORD(lParam) == WM_RBUTTONDOWN )
{
GetCursorPos( &pt );
SetCapture(hWnd);
GetWindowRect(hWnd,&drc);
ptdif.x = pt.x - drc.left;
ptdif.y = pt.y - drc.top;
rc = drc;
rc.right -= rc.left;
rc.bottom -= rc.top;
SetWindowLong(hWnd,FIGWL_MOUSE,FIM_CAPUTURED);
}
break;
case WM_MOUSEMOVE:
dwT = GetWindowLong(hWnd,FIGWL_MOUSE);
if (dwT & FIM_MOVED)
{
DrawUIBorder(&drc);
GetCursorPos( &pt );
drc.left = pt.x - ptdif.x;
drc.top = pt.y - ptdif.y;
drc.right = drc.left + rc.right;
drc.bottom = drc.top + rc.bottom;
DrawUIBorder(&drc);
}
else if (dwT & FIM_CAPUTURED)
{
DrawUIBorder(&drc);
SetWindowLong(hWnd,FIGWL_MOUSE,dwT | FIM_MOVED);
}
break;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
dwT = GetWindowLong(hWnd,FIGWL_MOUSE);
if (dwT & FIM_CAPUTURED)
{
ReleaseCapture();
if (dwT & FIM_MOVED)
{
DrawUIBorder(&drc);
GetCursorPos( &pt );
MoveWindow(hWnd,pt.x - ptdif.x,
pt.y - ptdif.y,
rc.right,
rc.bottom,TRUE);
}
}
break;
}
}
/**********************************************************************/
/* */
/* MyIsIMEMessage(message) */
/* */
/* Any UI window should not pass the IME messages to DefWindowProc. */
/* */
/**********************************************************************/
BOOL PASCAL MyIsIMEMessage(UINT message)
{
switch(message)
{
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_NOTIFY:
case WM_IME_SETCONTEXT:
case WM_IME_CONTROL:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case WM_IME_CHAR:
return TRUE;
}
return FALSE;
}
/**********************************************************************/
/* */
/* ShowUIWindows(hWnd,fFlag) */
/* */
/**********************************************************************/
void PASCAL ShowUIWindows(HWND hWnd, BOOL fFlag)
{
HGLOBAL hUIExtra;
LPUIEXTRA lpUIExtra;
int nsw = fFlag ? SW_SHOWNOACTIVATE : SW_HIDE;
if (!(hUIExtra = (HGLOBAL)GetWindowLongPtr(hWnd,IMMGWLP_PRIVATE)))
return;
if (!(lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra)))
return;
if (IsWindow(lpUIExtra->uiStatus.hWnd))
{
ShowWindow(lpUIExtra->uiStatus.hWnd,nsw);
lpUIExtra->uiStatus.bShow = fFlag;
}
if (IsWindow(lpUIExtra->uiCand.hWnd))
{
ShowWindow(lpUIExtra->uiCand.hWnd,nsw);
lpUIExtra->uiCand.bShow = fFlag;
}
if (IsWindow(lpUIExtra->uiDefComp.hWnd))
{
ShowWindow(lpUIExtra->uiDefComp.hWnd,nsw);
lpUIExtra->uiDefComp.bShow = fFlag;
}
if (IsWindow(lpUIExtra->uiGuide.hWnd))
{
ShowWindow(lpUIExtra->uiGuide.hWnd,nsw);
lpUIExtra->uiGuide.bShow = fFlag;
}
GlobalUnlock(hUIExtra);
}
#ifdef DEBUG
void PASCAL DumpUIExtra(LPUIEXTRA lpUIExtra)
{
TCHAR szDev[80];
int i;
wsprintf((LPTSTR)szDev,TEXT("Status hWnd %lX [%d,%d]\r\n"),
lpUIExtra->uiStatus.hWnd,
lpUIExtra->uiStatus.pt.x,
lpUIExtra->uiStatus.pt.y);
OutputDebugString((LPTSTR)szDev);
wsprintf((LPTSTR)szDev,TEXT("Cand hWnd %lX [%d,%d]\r\n"),
lpUIExtra->uiCand.hWnd,
lpUIExtra->uiCand.pt.x,
lpUIExtra->uiCand.pt.y);
OutputDebugString((LPTSTR)szDev);
wsprintf((LPTSTR)szDev,TEXT("CompStyle hWnd %lX]\r\n"), lpUIExtra->dwCompStyle);
OutputDebugString((LPTSTR)szDev);
wsprintf((LPTSTR)szDev,TEXT("DefComp hWnd %lX [%d,%d]\r\n"),
lpUIExtra->uiDefComp.hWnd,
lpUIExtra->uiDefComp.pt.x,
lpUIExtra->uiDefComp.pt.y);
OutputDebugString((LPTSTR)szDev);
for (i=0;i<5;i++)
{
wsprintf((LPTSTR)szDev,TEXT("Comp hWnd %lX [%d,%d]-[%d,%d]\r\n"),
lpUIExtra->uiComp[i].hWnd,
lpUIExtra->uiComp[i].rc.left,
lpUIExtra->uiComp[i].rc.top,
lpUIExtra->uiComp[i].rc.right,
lpUIExtra->uiComp[i].rc.bottom);
OutputDebugString((LPTSTR)szDev);
}
}
#endif