1335 lines
48 KiB
C
1335 lines
48 KiB
C
/******************************************************************************
|
||
*
|
||
* File Name: imeui.c
|
||
*
|
||
* - User Interface routines.
|
||
*
|
||
* Author: Beomseok Oh (BeomOh)
|
||
*
|
||
* Copyright (C) Microsoft Corp 1993-1995. All rights reserved.
|
||
*
|
||
******************************************************************************/
|
||
|
||
// include files
|
||
#include "precomp.h"
|
||
|
||
// local definitions
|
||
#define UIGWL_FLAGS 0
|
||
#define UIF_WNDMOVE 0x00000001UL
|
||
#define UIF_HANPRESS 0x00000002UL
|
||
#define UIF_JUNPRESS 0x00000004UL
|
||
#define UIF_CHIPRESS 0x00000008UL
|
||
#define UIF_MOUSEIN 0x00000010UL
|
||
#define UIF_SHOWSTATUS 0x00000020UL
|
||
#define UIF_PRIVATEPOS 0x00000040UL
|
||
|
||
extern BOOL fWndOpen[3];
|
||
extern WORD wWndCmd[3];
|
||
|
||
// public data
|
||
#pragma data_seg(".text", "CODE")
|
||
const TCHAR szUIClassName[] = TEXT("MSIME95K");
|
||
const TCHAR szStateWndName[] = TEXT("IMESTATE");
|
||
const TCHAR szCompWndName[] = TEXT("IMECOMP");
|
||
const TCHAR szCandWndName[] = TEXT("IMECAND");
|
||
const static RECT rcHan = { 4, 2, 21, 19 }, rcJun = { 24, 2, 41, 19 },
|
||
rcChi = { 44, 2, 61, 19 };
|
||
|
||
const static RECT rcCandCli = { 0, 0, 319, 29 },
|
||
rcLArrow = { 15, 4, 27, 25 }, rcRArrow = { 292, 4, 304, 25 },
|
||
rcBtn[9] = { { 30, 4, 57, 25 }, { 59, 4, 86, 25 },
|
||
{ 88, 4, 115, 25 }, { 117, 4, 144, 25 },
|
||
{ 146, 4, 173, 25 }, { 175, 4, 202, 25 },
|
||
{ 204, 4, 231, 25 }, { 233, 4, 260, 25 },
|
||
{ 262, 4, 289, 25 } };
|
||
#pragma data_seg()
|
||
|
||
HBITMAP hBMClient, hBMComp, hBMCand, hBMCandNum, hBMCandArr[2];
|
||
HBITMAP hBMEng, hBMHan, hBMBan, hBMJun, hBMChi[2];
|
||
HCURSOR hIMECursor;
|
||
HFONT hFontFix = NULL;
|
||
#pragma data_seg("SHAREDDATA")
|
||
RECT rcScreen = { 0, 0, 0, 0 };
|
||
RECT rcOldScrn = { 0, 0, 0, 0 };
|
||
POINT ptDefPos[3] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
|
||
POINT ptState = { -1, -1 };
|
||
POINT ptComp = { -1, -1 };
|
||
POINT ptCand = { -1, -1 };
|
||
DWORD dwScreenRes = 0;
|
||
#pragma data_seg()
|
||
|
||
static POINT ptPos;
|
||
static RECT rc;
|
||
|
||
|
||
void UpdateUIPosition(void)
|
||
{
|
||
HKEY hKey;
|
||
DWORD dwBuf, dwCb;
|
||
|
||
SystemParametersInfo(SPI_GETWORKAREA, sizeof(rcScreen), &rcScreen, FALSE);
|
||
if (!EqualRect(&rcOldScrn, &rcScreen))
|
||
{
|
||
ptDefPos[STATE_WINDOW].x = rcScreen.right - STATEXSIZE - GetSystemMetrics(SM_CXBORDER)
|
||
- GetSystemMetrics(SM_CXVSCROLL) - GetSystemMetrics(SM_CXHSCROLL);
|
||
ptDefPos[STATE_WINDOW].y = rcScreen.bottom - STATEYSIZE;
|
||
ptDefPos[COMP_WINDOW].x = ptDefPos[STATE_WINDOW].x + STATEXSIZE + GAPX;
|
||
ptDefPos[COMP_WINDOW].y = ptDefPos[STATE_WINDOW].y + GAPY;
|
||
ptDefPos[CAND_WINDOW].x = rcScreen.right - CANDXSIZE;
|
||
ptDefPos[CAND_WINDOW].y = rcScreen.bottom - CANDYSIZE;
|
||
if (ptState.x == -1 && ptState.y == -1)
|
||
{
|
||
if (RegOpenKey(HKEY_CURRENT_USER, szIMEKey, &hKey) == ERROR_SUCCESS)
|
||
{
|
||
dwCb = sizeof(dwBuf);
|
||
if (RegQueryValueEx(hKey, szStatePos, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
|
||
== ERROR_SUCCESS)
|
||
{
|
||
ptState.x = HIWORD(dwBuf);
|
||
ptState.y = LOWORD(dwBuf);
|
||
wWndCmd[STATE_WINDOW] = wWndCmd[COMP_WINDOW] = 0x04; // MCW_SCREEN
|
||
}
|
||
else
|
||
ptState = ptDefPos[STATE_WINDOW];
|
||
dwCb = sizeof(dwBuf);
|
||
if (RegQueryValueEx(hKey, szCandPos, NULL, NULL, (LPBYTE)&dwBuf, &dwCb)
|
||
== ERROR_SUCCESS)
|
||
{
|
||
ptCand.x = HIWORD(dwBuf);
|
||
ptCand.y = LOWORD(dwBuf);
|
||
}
|
||
else
|
||
ptCand = ptDefPos[CAND_WINDOW];
|
||
RegCloseKey(hKey);
|
||
}
|
||
else
|
||
{
|
||
ptState = ptDefPos[STATE_WINDOW];
|
||
ptCand = ptDefPos[CAND_WINDOW];
|
||
}
|
||
dwScreenRes = MAKELONG(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
||
}
|
||
else
|
||
{
|
||
ptState.x += rcScreen.left - rcOldScrn.left;
|
||
ptState.y += rcScreen.top - rcOldScrn.top;
|
||
ptComp.x += rcScreen.left - rcOldScrn.left;
|
||
ptComp.y += rcScreen.top - rcOldScrn.top;
|
||
ptCand.x += rcScreen.left - rcOldScrn.left;
|
||
ptCand.y += rcScreen.top - rcOldScrn.top;
|
||
}
|
||
if (ptState.x < rcScreen.left)
|
||
ptState.x = rcScreen.left;
|
||
else if (ptState.x > rcScreen.right - STATEXSIZE)
|
||
ptState.x = rcScreen.right - STATEXSIZE;
|
||
if (ptState.y < rcScreen.top)
|
||
ptState.y = rcScreen.top;
|
||
else if (ptState.y > rcScreen.bottom - STATEYSIZE)
|
||
ptState.y = rcScreen.bottom - STATEYSIZE;
|
||
ptComp.x = (ptState.x + STATEXSIZE + GAPX + COMPSIZE > rcScreen.right)?
|
||
ptState.x - GAPX - COMPSIZE: ptState.x + STATEXSIZE + GAPX;
|
||
ptComp.y = ptState.y + GAPY;
|
||
if (ptCand.x < rcScreen.left)
|
||
ptCand.x = rcScreen.left;
|
||
else if (ptCand.x > rcScreen.right - CANDXSIZE)
|
||
ptCand.x = rcScreen.right - CANDXSIZE;
|
||
if (ptCand.y < rcScreen.top)
|
||
ptCand.y = rcScreen.top;
|
||
else if (ptCand.y > rcScreen.bottom - CANDYSIZE)
|
||
ptCand.y = rcScreen.bottom - CANDYSIZE;
|
||
rcOldScrn = rcScreen;
|
||
}
|
||
}
|
||
|
||
|
||
BOOL InitializeResource(HANDLE hInstance)
|
||
{
|
||
hBMClient = MyCreateMappedBitmap(hInst, TEXT("Client"));
|
||
hBMEng = MyCreateMappedBitmap(hInst, TEXT("English"));
|
||
hBMHan = MyCreateMappedBitmap(hInst, TEXT("Hangeul"));
|
||
hBMBan = MyCreateMappedBitmap(hInst, TEXT("Banja"));
|
||
hBMJun = MyCreateMappedBitmap(hInst, TEXT("Junja"));
|
||
hBMChi[0] = MyCreateMappedBitmap(hInst, TEXT("ChineseOff"));
|
||
hBMChi[1] = MyCreateMappedBitmap(hInst, TEXT("ChineseOn"));
|
||
hBMComp = MyCreateMappedBitmap(hInst, TEXT("Composition"));
|
||
hBMCand = MyCreateMappedBitmap(hInst, TEXT("Candidate"));
|
||
hBMCandNum = MyCreateMappedBitmap(hInst, TEXT("CandNumber"));
|
||
hBMCandArr[0] = MyCreateMappedBitmap(hInst, TEXT("CandArrow1"));
|
||
hBMCandArr[1] = MyCreateMappedBitmap(hInst, TEXT("CandArrow2"));
|
||
hIMECursor = LoadCursor(hInstance, TEXT("MyHand"));
|
||
#ifdef JOHAB_IME
|
||
hFontFix = CreateFont(-16,0,0,0,0,0,0,0,130,OUT_DEFAULT_PRECIS,
|
||
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH,TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"));
|
||
#else
|
||
hFontFix = CreateFont(-16,0,0,0,0,0,0,0,129,OUT_DEFAULT_PRECIS,
|
||
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH,TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"));
|
||
#endif
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL RegisterUIClass(HANDLE hInstance)
|
||
{
|
||
BOOL fRet = TRUE;
|
||
WNDCLASSEX wc;
|
||
|
||
wc.cbSize = sizeof(WNDCLASSEX);
|
||
wc.style = CS_VREDRAW | CS_HREDRAW | CS_IME;
|
||
wc.cbClsExtra = 0;
|
||
wc.hInstance = hInstance;
|
||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
wc.hIcon = NULL;
|
||
wc.hIconSm = NULL;
|
||
wc.lpszMenuName = (LPTSTR)NULL;
|
||
wc.hbrBackground = NULL;
|
||
|
||
wc.cbWndExtra = 8;
|
||
wc.lpfnWndProc = UIWndProc;
|
||
wc.lpszClassName = (LPTSTR)szUIClassName;
|
||
if (!RegisterClassEx((LPWNDCLASSEX)&wc))
|
||
{
|
||
MyDebugOut(MDB_LOG, "RegisterClassEx() Failed for UIWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
wc.style = CS_VREDRAW | CS_HREDRAW | CS_IME;
|
||
wc.cbWndExtra = 4;
|
||
wc.lpfnWndProc = StateWndProc;
|
||
wc.lpszClassName = (LPTSTR)szStateWndName;
|
||
if (!RegisterClassEx((LPWNDCLASSEX)&wc))
|
||
{
|
||
MyDebugOut(MDB_LOG, "RegisterClassEx() Failed for StateWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
wc.lpfnWndProc = CompWndProc;
|
||
wc.lpszClassName = (LPTSTR)szCompWndName;
|
||
if (!RegisterClassEx((LPWNDCLASSEX)&wc))
|
||
{
|
||
MyDebugOut(MDB_LOG, "RegisterClassEx() Failed for CompWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
wc.lpfnWndProc = CandWndProc;
|
||
wc.lpszClassName = (LPTSTR)szCandWndName;
|
||
if (!RegisterClassEx((LPWNDCLASSEX)&wc))
|
||
{
|
||
MyDebugOut(MDB_LOG, "RegisterClassEx() Failed for CandWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
return fRet;
|
||
}
|
||
|
||
|
||
BOOL UnregisterUIClass(HANDLE hInstance)
|
||
{
|
||
BOOL fRet = TRUE;
|
||
|
||
if (!UnregisterClass(szUIClassName, hInstance))
|
||
{
|
||
MyDebugOut(MDB_LOG, "UnregisterClass() Failed for UIWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
if (!UnregisterClass(szStateWndName, hInstance))
|
||
{
|
||
MyDebugOut(MDB_LOG, "UnregisterClass() Failed for StateWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
if (!UnregisterClass(szCompWndName, hInstance))
|
||
{
|
||
MyDebugOut(MDB_LOG, "UnregisterClass() Failed for CompWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
if (!UnregisterClass(szCandWndName, hInstance))
|
||
{
|
||
MyDebugOut(MDB_LOG, "UnregisterClass() Failed for CandWindow.");
|
||
fRet = FALSE;
|
||
}
|
||
return fRet;
|
||
}
|
||
|
||
|
||
void DrawBitmap(HDC hDC, long xStart, long yStart, HBITMAP hBitmap)
|
||
{
|
||
HDC hMemDC;
|
||
HBITMAP hBMOld;
|
||
BITMAP bm;
|
||
POINT pt;
|
||
|
||
hMemDC = CreateCompatibleDC(hDC);
|
||
hBMOld = SelectObject(hMemDC, hBitmap);
|
||
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
|
||
pt.x = bm.bmWidth;
|
||
pt.y = bm.bmHeight;
|
||
BitBlt(hDC, xStart, yStart, pt.x, pt.y, hMemDC, 0, 0, SRCCOPY);
|
||
SelectObject(hMemDC, hBMOld);
|
||
DeleteDC(hMemDC);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
void ShowWindowBorder(RECT rc)
|
||
{
|
||
HDC hDC;
|
||
HBRUSH hBrOld;
|
||
int cxBorder, cyBorder;
|
||
|
||
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
|
||
hBrOld = SelectObject(hDC, GetStockObject(GRAY_BRUSH));
|
||
cxBorder = GetSystemMetrics(SM_CXBORDER);
|
||
cyBorder = GetSystemMetrics(SM_CYBORDER);
|
||
PatBlt(hDC, rc.left, rc.top, rc.right-rc.left-cxBorder, cyBorder, PATINVERT);
|
||
PatBlt(hDC, rc.right-cxBorder, rc.top, cxBorder, rc.bottom-rc.top-cyBorder, PATINVERT);
|
||
PatBlt(hDC, rc.right, rc.bottom-cyBorder, -(rc.right-rc.left-cxBorder), cyBorder, PATINVERT);
|
||
PatBlt(hDC, rc.left, rc.bottom, cxBorder, -(rc.bottom-rc.top-cyBorder), PATINVERT);
|
||
SelectObject(hDC, hBrOld);
|
||
DeleteDC(hDC);
|
||
|
||
return;
|
||
}
|
||
|
||
void ShowHideUIWnd(HIMC hIMC, LPUIINSTANCE lpUIInst, BOOL fShow, LPARAM lParam)
|
||
{
|
||
LPINPUTCONTEXT lpIMC;
|
||
LPCOMPOSITIONSTRING lpCompStr;
|
||
DWORD fdwUIFlags;
|
||
|
||
if (fShow && hIMC && (lpIMC = ImmLockIMC(hIMC)))
|
||
{
|
||
UpdateUIPosition();
|
||
fdwUIFlags = (DWORD)GetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS);
|
||
if (!(fdwUIFlags & UIF_PRIVATEPOS))
|
||
lpIMC->ptStatusWndPos = ptState;
|
||
MoveWindow(lpUIInst->rghWnd[STATE_WINDOW], lpIMC->ptStatusWndPos.x,
|
||
lpIMC->ptStatusWndPos.y, STATEXSIZE, STATEYSIZE, TRUE);
|
||
if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT)
|
||
{
|
||
MoveWindow(lpUIInst->rghWnd[COMP_WINDOW], ptComp.x, ptComp.y, COMPSIZE, COMPSIZE, TRUE);
|
||
}
|
||
if (fWndOpen[STATE_WINDOW] != FALSE && (fdwUIFlags & UIF_SHOWSTATUS))
|
||
ShowWindow(lpUIInst->rghWnd[STATE_WINDOW], SW_SHOWNOACTIVATE);
|
||
else
|
||
ShowWindow(lpUIInst->rghWnd[STATE_WINDOW], SW_HIDE);
|
||
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
|
||
if (lpCompStr && lpCompStr->dwCompStrLen
|
||
&& fWndOpen[COMP_WINDOW] && (lParam & ISC_SHOWUICOMPOSITIONWINDOW))
|
||
ShowWindow(lpUIInst->rghWnd[COMP_WINDOW], SW_SHOWNOACTIVATE);
|
||
else
|
||
ShowWindow(lpUIInst->rghWnd[COMP_WINDOW], SW_HIDE);
|
||
if (lpIMC->fdwConversion & IME_CMODE_HANJACONVERT
|
||
&& fWndOpen[CAND_WINDOW] && (lParam & ISC_SHOWUICANDIDATEWINDOW))
|
||
ShowWindow(lpUIInst->rghWnd[CAND_WINDOW], SW_SHOWNOACTIVATE);
|
||
else
|
||
ShowWindow(lpUIInst->rghWnd[CAND_WINDOW], SW_HIDE);
|
||
ImmUnlockIMCC(lpIMC->hCompStr);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
else
|
||
{
|
||
ShowWindow(lpUIInst->rghWnd[STATE_WINDOW], SW_HIDE);
|
||
ShowWindow(lpUIInst->rghWnd[COMP_WINDOW], SW_HIDE);
|
||
ShowWindow(lpUIInst->rghWnd[CAND_WINDOW], SW_HIDE);
|
||
}
|
||
}
|
||
|
||
|
||
LRESULT CALLBACK UIWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
HGLOBAL hUIInst;
|
||
LPUIINSTANCE lpUIInst;
|
||
|
||
switch (uMessage)
|
||
{
|
||
case WM_CREATE:
|
||
hUIInst = GlobalAlloc(GHND, sizeof(UIINSTANCE));
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
lpUIInst->rghWnd[STATE_WINDOW] = CreateWindow(szStateWndName, TEXT("\0"),
|
||
WS_DISABLED | WS_POPUP, ptState.x, ptState.y,
|
||
STATEXSIZE, STATEYSIZE, hWnd, NULL, hInst, NULL);
|
||
lpUIInst->rghWnd[COMP_WINDOW] = CreateWindow(szCompWndName, TEXT("\0"),
|
||
WS_DISABLED | WS_POPUP, ptComp.x, ptComp.y,
|
||
COMPSIZE, COMPSIZE, hWnd, NULL, hInst, NULL );
|
||
lpUIInst->rghWnd[CAND_WINDOW] = CreateWindow(szCandWndName, TEXT("\0"),
|
||
WS_DISABLED | WS_POPUP, ptCand.x, ptCand.y,
|
||
CANDXSIZE, CANDYSIZE, hWnd, NULL, hInst, NULL );
|
||
GlobalUnlock(hUIInst);
|
||
SetWindowLongPtr(hWnd, IMMGWL_PRIVATE, (LONG_PTR)hUIInst);
|
||
return 0;
|
||
|
||
case WM_DESTROY:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
DestroyWindow(lpUIInst->rghWnd[STATE_WINDOW]);
|
||
DestroyWindow(lpUIInst->rghWnd[COMP_WINDOW]);
|
||
DestroyWindow(lpUIInst->rghWnd[CAND_WINDOW]);
|
||
GlobalUnlock(hUIInst);
|
||
GlobalFree(hUIInst);
|
||
SetWindowLongPtr(hWnd, IMMGWL_PRIVATE, (LONG_PTR)0);
|
||
return 0;
|
||
|
||
case WM_IME_SELECT:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
ShowHideUIWnd(GetWindowLongPtr(hWnd, IMMGWL_IMC), lpUIInst, wParam, ISC_SHOWUIALL);
|
||
GlobalUnlock(hUIInst);
|
||
return 0;
|
||
|
||
case WM_IME_COMPOSITION:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
InvalidateRect(lpUIInst->rghWnd[COMP_WINDOW], NULL, TRUE);
|
||
GlobalUnlock(hUIInst);
|
||
return 0;
|
||
|
||
case WM_IME_CONTROL:
|
||
return (LRESULT)DoIMEControl(hWnd, wParam, lParam);
|
||
|
||
case WM_IME_NOTIFY:
|
||
return (LRESULT)DoIMENotify(hWnd, wParam, lParam);
|
||
|
||
case WM_IME_SETCONTEXT:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
ShowHideUIWnd(GetWindowLongPtr(hWnd, IMMGWL_IMC), lpUIInst, wParam, lParam);
|
||
GlobalUnlock(hUIInst);
|
||
return 0;
|
||
|
||
case WM_IME_STARTCOMPOSITION:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
ShowWindow(lpUIInst->rghWnd[COMP_WINDOW], fWndOpen[COMP_WINDOW]? SW_SHOWNOACTIVATE: SW_HIDE);
|
||
GlobalUnlock(hUIInst);
|
||
return 0;
|
||
|
||
case WM_IME_ENDCOMPOSITION:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
ShowWindow(lpUIInst->rghWnd[COMP_WINDOW], SW_HIDE);
|
||
GlobalUnlock(hUIInst);
|
||
return 0;
|
||
|
||
case WM_SYSCOLORCHANGE:
|
||
GetSysColorsAndMappedBitmap();
|
||
return 0;
|
||
|
||
case WM_DISPLAYCHANGE:
|
||
if (dwScreenRes != (DWORD)lParam)
|
||
{
|
||
ptState.x += LOWORD(lParam) - LOWORD(dwScreenRes);
|
||
ptState.y += HIWORD(lParam) - HIWORD(dwScreenRes);
|
||
ptComp.x += LOWORD(lParam) - LOWORD(dwScreenRes);
|
||
ptComp.y += HIWORD(lParam) - HIWORD(dwScreenRes);
|
||
ptCand.x += LOWORD(lParam) - LOWORD(dwScreenRes);
|
||
ptCand.y += HIWORD(lParam) - HIWORD(dwScreenRes);
|
||
dwScreenRes = MAKELONG(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
||
}
|
||
return 0;
|
||
}
|
||
return DefWindowProc(hWnd, uMessage, wParam, lParam);
|
||
}
|
||
|
||
|
||
LRESULT CALLBACK StateWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
switch (uMessage)
|
||
{
|
||
HANDLE_DUMMYMSG(WM_IME_CHAR);
|
||
HANDLE_DUMMYMSG(WM_IME_COMPOSITIONFULL);
|
||
HANDLE_DUMMYMSG(WM_IME_COMPOSITION);
|
||
HANDLE_DUMMYMSG(WM_IME_CONTROL);
|
||
HANDLE_DUMMYMSG(WM_IME_NOTIFY);
|
||
HANDLE_DUMMYMSG(WM_IME_SELECT);
|
||
HANDLE_DUMMYMSG(WM_IME_SETCONTEXT);
|
||
HANDLE_DUMMYMSG(WM_IME_STARTCOMPOSITION);
|
||
HANDLE_DUMMYMSG(WM_IME_ENDCOMPOSITION);
|
||
HANDLE_MSG(hWnd, WM_SETCURSOR, State_OnSetCursor);
|
||
HANDLE_MSG(hWnd, WM_MOUSEMOVE, State_OnMouseMove);
|
||
HANDLE_MSG(hWnd, WM_LBUTTONUP, State_OnLButtonUp);
|
||
HANDLE_MSG(hWnd, WM_PAINT, State_OnPaint);
|
||
HANDLE_MSG(hWnd, WM_COMMAND, State_OnCommand);
|
||
}
|
||
return DefWindowProc(hWnd, uMessage, wParam, lParam);
|
||
}
|
||
|
||
|
||
BOOL State_OnSetCursor(HWND hWnd, HWND hWndCursor, UINT codeHitTest, UINT msg)
|
||
{
|
||
HWND hWndUI;
|
||
HIMC hIMC;
|
||
DWORD fdwUIFlags;
|
||
|
||
SetCursor(hIMECursor);
|
||
|
||
switch (msg)
|
||
{
|
||
case WM_LBUTTONDOWN:
|
||
GetCursorPos(&ptPos);
|
||
ScreenToClient(hWnd, &ptPos);
|
||
fdwUIFlags = (DWORD)GetWindowLong(hWnd, UIGWL_FLAGS);
|
||
if (PtInRect((LPRECT)&rcHan, ptPos))
|
||
{
|
||
fdwUIFlags |= UIF_HANPRESS;
|
||
}
|
||
else if (PtInRect((LPRECT)&rcJun, ptPos))
|
||
{
|
||
fdwUIFlags |= UIF_JUNPRESS;
|
||
}
|
||
else if (PtInRect((LPRECT)&rcChi, ptPos))
|
||
{
|
||
fdwUIFlags |= UIF_CHIPRESS;
|
||
}
|
||
else
|
||
{
|
||
fdwUIFlags |= UIF_WNDMOVE;
|
||
GetWindowRect(hWnd, &rc);
|
||
ShowWindowBorder(rc);
|
||
SetCapture(hWnd);
|
||
}
|
||
SetWindowLong(hWnd, UIGWL_FLAGS, fdwUIFlags);
|
||
break;
|
||
|
||
case WM_LBUTTONUP:
|
||
GetCursorPos(&ptPos);
|
||
ScreenToClient(hWnd, &ptPos);
|
||
fdwUIFlags = (DWORD)GetWindowLong( hWnd, UIGWL_FLAGS );
|
||
if ((fdwUIFlags & UIF_HANPRESS) && PtInRect((LPRECT)&rcHan, ptPos))
|
||
{
|
||
fdwUIFlags &= ~UIF_HANPRESS;
|
||
keybd_event(VK_HANGEUL, 0, 0, 0);
|
||
keybd_event(VK_HANGEUL, 0, KEYEVENTF_KEYUP, 0);
|
||
}
|
||
else if ((fdwUIFlags & UIF_JUNPRESS) && PtInRect((LPRECT)&rcJun, ptPos))
|
||
{
|
||
fdwUIFlags &= ~UIF_JUNPRESS;
|
||
keybd_event(VK_JUNJA, 0, 0, 0);
|
||
keybd_event(VK_JUNJA, 0, KEYEVENTF_KEYUP, 0);
|
||
}
|
||
else if ((fdwUIFlags & UIF_CHIPRESS) && PtInRect((LPRECT)&rcChi, ptPos))
|
||
{
|
||
fdwUIFlags &= ~UIF_CHIPRESS;
|
||
keybd_event(VK_HANJA, 0, 0, 0);
|
||
keybd_event(VK_HANJA, 0, KEYEVENTF_KEYUP, 0);
|
||
}
|
||
else
|
||
fdwUIFlags &= ~(UIF_HANPRESS | UIF_JUNPRESS | UIF_CHIPRESS);
|
||
SetWindowLong(hWnd, UIGWL_FLAGS, fdwUIFlags);
|
||
break;
|
||
|
||
case WM_RBUTTONDOWN:
|
||
hWndUI = GetWindow(hWnd, GW_OWNER);
|
||
hIMC = (HIMC)GetWindowLongPtr(hWndUI, IMMGWL_IMC);
|
||
if (bState) MakeFinalMsgBuf(hIMC, 0);
|
||
break;
|
||
|
||
case WM_RBUTTONUP:
|
||
State_OnMyMenu(hWnd);
|
||
break;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void State_OnMouseMove(HWND hWnd, int x, int y, UINT keyFlags)
|
||
{
|
||
DWORD fdwUIFlags;
|
||
|
||
fdwUIFlags = (DWORD)GetWindowLong(hWnd, UIGWL_FLAGS);
|
||
if (fdwUIFlags & UIF_WNDMOVE)
|
||
{
|
||
ShowWindowBorder(rc);
|
||
rc.left += x - ptPos.x;
|
||
rc.top += y - ptPos.y;
|
||
rc.right += x - ptPos.x;
|
||
rc.bottom += y - ptPos.y;
|
||
ShowWindowBorder(rc);
|
||
ptPos.x = x;
|
||
ptPos.y = y;
|
||
}
|
||
return;
|
||
|
||
UNREFERENCED_PARAMETER(keyFlags);
|
||
}
|
||
|
||
|
||
void State_OnLButtonUp(HWND hWnd, int x, int y, UINT keyFlags)
|
||
{
|
||
HKEY hKey;
|
||
DWORD fdwUIFlags, dwBuf, dwCb;
|
||
HGLOBAL hUIInst;
|
||
LPUIINSTANCE lpUIInst;
|
||
HWND hWndUI;
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
|
||
ReleaseCapture();
|
||
fdwUIFlags = (DWORD)GetWindowLong(hWnd, UIGWL_FLAGS);
|
||
if (fdwUIFlags & UIF_WNDMOVE)
|
||
{
|
||
ShowWindowBorder(rc);
|
||
MoveWindow(hWnd, rc.left, rc.top, STATEXSIZE, STATEYSIZE, TRUE);
|
||
ptState.x = rc.left;
|
||
ptState.y = rc.top;
|
||
if (RegCreateKey(HKEY_CURRENT_USER, szIMEKey, &hKey) == ERROR_SUCCESS)
|
||
{
|
||
dwCb = sizeof(dwBuf);
|
||
dwBuf = (ptState.x << 16) | (ptState.y & 0x0FFFF); // HIWORD : X, LOWORD : Y
|
||
RegSetValueEx(hKey, szStatePos, 0, REG_DWORD, (LPBYTE)&dwBuf, dwCb);
|
||
RegCloseKey(hKey);
|
||
}
|
||
ptComp.x = (ptState.x + STATEXSIZE + GAPX + COMPSIZE > rcScreen.right)?
|
||
ptState.x - GAPX - COMPSIZE: ptState.x + STATEXSIZE + GAPX;
|
||
ptComp.y = ptState.y + GAPY;
|
||
|
||
hWndUI = GetWindow(hWnd, GW_OWNER);
|
||
hIMC = (HIMC)GetWindowLongPtr(hWndUI, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC != NULL) {
|
||
lpIMC->ptStatusWndPos = ptState;
|
||
if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT)
|
||
{
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(GetWindow(hWnd, GW_OWNER), IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
MoveWindow(lpUIInst->rghWnd[COMP_WINDOW], ptComp.x, ptComp.y, COMPSIZE, COMPSIZE, TRUE);
|
||
GlobalUnlock(hUIInst);
|
||
lpIMC->cfCompForm.ptCurrentPos = ptComp;
|
||
}
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
wWndCmd[STATE_WINDOW] = wWndCmd[COMP_WINDOW] = 0x04; // MCW_SCREEN
|
||
fdwUIFlags &= ~UIF_WNDMOVE;
|
||
}
|
||
SetWindowLong(hWnd, UIGWL_FLAGS, fdwUIFlags);
|
||
|
||
return;
|
||
|
||
UNREFERENCED_PARAMETER(x);
|
||
UNREFERENCED_PARAMETER(y);
|
||
UNREFERENCED_PARAMETER(keyFlags);
|
||
}
|
||
|
||
|
||
typedef struct tagCOLORMAP
|
||
{
|
||
COLORREF bgrfrom;
|
||
COLORREF bgrto;
|
||
COLORREF sysColor;
|
||
} COLORMAP;
|
||
|
||
// these are the default colors used to map the dib colors
|
||
// to the current system colors
|
||
|
||
#define BGR_BUTTONTEXT (RGB(000,000,000)) // black
|
||
#define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
|
||
#define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
|
||
#define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
|
||
#define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
|
||
#define BGR_BACKGROUND (RGB(255,000,255)) // magenta
|
||
#define FlipColor(rgb) (RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)))
|
||
|
||
HBITMAP MyCreateMappedBitmap(HINSTANCE hInstance, LPTSTR lpszBitmap)
|
||
{
|
||
HDC hdc, hdcMem = NULL;
|
||
HANDLE h;
|
||
LPDWORD p;
|
||
LPSTR lpBits;
|
||
HANDLE hRes;
|
||
LPBITMAPINFOHEADER lpBitmapInfo, lpTmpBMInfo;
|
||
HBITMAP hbm = NULL, hbmOld;
|
||
int numcolors, i, wid, hgt;
|
||
static COLORMAP ColorMap[] =
|
||
{
|
||
{BGR_BUTTONTEXT, BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black
|
||
{BGR_BUTTONSHADOW, BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey
|
||
{BGR_BUTTONFACE, BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey
|
||
{BGR_BUTTONHILIGHT, BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
|
||
{BGR_BACKGROUNDSEL, BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue
|
||
{BGR_BACKGROUND, BGR_BACKGROUND, COLOR_WINDOW} // magenta
|
||
};
|
||
|
||
#define NUM_MAPS (sizeof(ColorMap)/sizeof(COLORMAP))
|
||
|
||
h = FindResource(hInstance, lpszBitmap, RT_BITMAP);
|
||
if (!h)
|
||
return NULL;
|
||
|
||
hRes = LoadResource(hInstance, h);
|
||
|
||
/* Lock the bitmap and get a pointer to the color table. */
|
||
lpBitmapInfo = (LPBITMAPINFOHEADER)LockResource(hRes);
|
||
if (!lpBitmapInfo)
|
||
return NULL;
|
||
|
||
// HACK: We need to use temp copy of BITMAPINFO because original info is destroyed
|
||
// after change color. It cause next time LoadResource result has wrong info.
|
||
i = sizeof(BITMAPINFOHEADER) + 16*sizeof(RGBQUAD);
|
||
lpTmpBMInfo = (LPBITMAPINFOHEADER) LocalAlloc(LPTR, i);
|
||
if (!lpTmpBMInfo) {
|
||
UnlockResource(hRes);
|
||
FreeResource(hRes);
|
||
return NULL;
|
||
}
|
||
CopyMemory(lpTmpBMInfo, lpBitmapInfo, i);
|
||
|
||
//
|
||
// So what are the new colors anyway ?
|
||
//
|
||
for (i=0; i < NUM_MAPS; i++)
|
||
ColorMap[i].bgrto = FlipColor(GetSysColor((int)ColorMap[i].sysColor));
|
||
|
||
// HACK: ??? p = (LPDWORD)(((LPSTR)lpBitmapInfo) + lpBitmapInfo->biSize);
|
||
p = (LPDWORD)(((LPSTR)lpTmpBMInfo) + lpTmpBMInfo->biSize);
|
||
|
||
/* Replace button-face and button-shadow colors with the current values
|
||
*/
|
||
numcolors = 16;
|
||
|
||
while (numcolors-- > 0)
|
||
{
|
||
for (i = 0; i < NUM_MAPS; i++)
|
||
{
|
||
if (*p == ColorMap[i].bgrfrom)
|
||
{
|
||
*p = ColorMap[i].bgrto;
|
||
break;
|
||
}
|
||
}
|
||
p++;
|
||
}
|
||
|
||
/* First skip over the header structure */
|
||
lpBits = (LPSTR)(lpBitmapInfo + 1);
|
||
|
||
/* Skip the color table entries, if any */
|
||
lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);
|
||
|
||
/* Create a color bitmap compatible with the display device */
|
||
i = wid = (int)lpBitmapInfo->biWidth;
|
||
hgt = (int)lpBitmapInfo->biHeight;
|
||
hdc = GetDC(NULL);
|
||
|
||
hdcMem = CreateCompatibleDC(hdc);
|
||
if (hdcMem)
|
||
{
|
||
hbm = CreateDiscardableBitmap(hdc, i, hgt);
|
||
if (hbm)
|
||
{
|
||
hbmOld = SelectObject(hdcMem, hbm);
|
||
// set the main image
|
||
StretchDIBits(hdcMem, 0, 0, wid, hgt, 0, 0, wid, hgt, lpBits,
|
||
(LPBITMAPINFO)lpTmpBMInfo, DIB_RGB_COLORS, SRCCOPY);
|
||
SelectObject(hdcMem, hbmOld);
|
||
}
|
||
DeleteObject(hdcMem);
|
||
}
|
||
ReleaseDC(NULL, hdc);
|
||
UnlockResource(hRes);
|
||
FreeResource(hRes);
|
||
// HACK: Remove hack temp BITMAPINFO.
|
||
LocalFree(lpTmpBMInfo);
|
||
|
||
return hbm;
|
||
}
|
||
|
||
|
||
void GetSysColorsAndMappedBitmap(void)
|
||
{
|
||
static DWORD rgbFace, rgbShadow, rgbHilight, rgbFrame;
|
||
static COLORREF rgbSaveFace = 0xFFFFFFFFL,
|
||
rgbSaveShadow = 0xFFFFFFFFL,
|
||
rgbSaveHilight = 0xFFFFFFFFL,
|
||
rgbSaveFrame = 0xFFFFFFFFL;
|
||
|
||
rgbFace = GetSysColor(COLOR_BTNFACE);
|
||
rgbShadow = GetSysColor(COLOR_BTNSHADOW);
|
||
rgbHilight = GetSysColor(COLOR_BTNHIGHLIGHT);
|
||
rgbFrame = GetSysColor(COLOR_WINDOWFRAME);
|
||
|
||
if (rgbSaveFace != rgbFace || rgbSaveShadow != rgbShadow
|
||
|| rgbSaveHilight != rgbHilight || rgbSaveFrame != rgbFrame)
|
||
{
|
||
rgbSaveFace = rgbFace;
|
||
rgbSaveShadow = rgbShadow;
|
||
rgbSaveHilight = rgbHilight;
|
||
rgbSaveFrame = rgbFrame;
|
||
|
||
DeleteObject(hBMClient);
|
||
DeleteObject(hBMEng);
|
||
DeleteObject(hBMHan);
|
||
DeleteObject(hBMBan);
|
||
DeleteObject(hBMJun);
|
||
DeleteObject(hBMChi[0]);
|
||
DeleteObject(hBMChi[1]);
|
||
DeleteObject(hBMComp);
|
||
DeleteObject(hBMCand);
|
||
DeleteObject(hBMCandNum);
|
||
DeleteObject(hBMCandArr[0]);
|
||
DeleteObject(hBMCandArr[1]);
|
||
|
||
hBMClient = MyCreateMappedBitmap(hInst, TEXT("Client"));
|
||
hBMEng = MyCreateMappedBitmap(hInst, TEXT("English"));
|
||
hBMHan = MyCreateMappedBitmap(hInst, TEXT("Hangeul"));
|
||
hBMBan = MyCreateMappedBitmap(hInst, TEXT("Banja"));
|
||
hBMJun = MyCreateMappedBitmap(hInst, TEXT("Junja"));
|
||
hBMChi[0] = MyCreateMappedBitmap(hInst, TEXT("ChineseOff"));
|
||
hBMChi[1] = MyCreateMappedBitmap(hInst, TEXT("ChineseOn"));
|
||
hBMComp = MyCreateMappedBitmap(hInst, TEXT("Composition"));
|
||
hBMCand = MyCreateMappedBitmap(hInst, TEXT("Candidate"));
|
||
hBMCandNum = MyCreateMappedBitmap(hInst, TEXT("CandNumber"));
|
||
hBMCandArr[0] = MyCreateMappedBitmap(hInst, TEXT("CandArrow1"));
|
||
hBMCandArr[1] = MyCreateMappedBitmap(hInst, TEXT("CandArrow2"));
|
||
}
|
||
}
|
||
|
||
|
||
void State_OnPaint(HWND hWnd)
|
||
{
|
||
HDC hDC;
|
||
HWND hWndUI;
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
PAINTSTRUCT ps;
|
||
DWORD fdwUIFlags;
|
||
|
||
hDC = BeginPaint(hWnd, &ps);
|
||
hWndUI = GetWindow(hWnd, GW_OWNER);
|
||
hIMC = (HIMC)GetWindowLongPtr(hWndUI, IMMGWL_IMC);
|
||
if (hIMC && (lpIMC = ImmLockIMC(hIMC)))
|
||
{
|
||
fdwUIFlags = (DWORD)GetWindowLong(hWnd, UIGWL_FLAGS);
|
||
DrawBitmap(hDC, 0, 0, hBMClient);
|
||
DrawBitmap(hDC, rcHan.left, rcHan.top,
|
||
(lpIMC->fOpen && (lpIMC->fdwConversion & IME_CMODE_HANGEUL))? hBMHan: hBMEng);
|
||
DrawBitmap(hDC, rcJun.left, rcJun.top,
|
||
(lpIMC->fOpen && (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE))? hBMJun: hBMBan);
|
||
DrawBitmap(hDC, rcChi.left, rcChi.top,
|
||
(lpIMC->fdwConversion & IME_CMODE_HANJACONVERT)? hBMChi[1]: hBMChi[0]);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
EndPaint(hWnd, &ps);
|
||
}
|
||
|
||
|
||
void State_OnCommand(HWND hWnd, int id, HWND hWndCtl, UINT codeNotify)
|
||
{
|
||
switch (id)
|
||
{
|
||
case IDM_CONFIG:
|
||
State_OnMyConfig(hWnd);
|
||
break;
|
||
|
||
case IDM_ABOUT:
|
||
State_OnMyAbout(hWnd);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
void State_OnMyMenu(HWND hWnd)
|
||
{
|
||
HMENU hMenu;
|
||
POINT ptCurrent;
|
||
TCHAR szBuffer[256];
|
||
|
||
GetCursorPos(&ptCurrent);
|
||
hMenu = CreatePopupMenu();
|
||
LoadString(hInst, IDS_CONFIG, szBuffer, sizeof(szBuffer));
|
||
AppendMenu(hMenu, MF_ENABLED, IDM_CONFIG, szBuffer);
|
||
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
|
||
LoadString(hInst, IDS_ABOUT, szBuffer, sizeof(szBuffer));
|
||
AppendMenu(hMenu, MF_ENABLED, IDM_ABOUT, szBuffer);
|
||
TrackPopupMenu(hMenu, TPM_LEFTALIGN, ptCurrent.x, ptCurrent.y, 0, hWnd, NULL);
|
||
DestroyMenu(hMenu);
|
||
}
|
||
|
||
|
||
void State_OnMyConfig(HWND hWnd)
|
||
{
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
|
||
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hWnd, GW_OWNER), IMMGWL_IMC);
|
||
if (lpIMC = ImmLockIMC(hIMC))
|
||
{
|
||
ImeConfigure(0, lpIMC->hWnd, IME_CONFIG_GENERAL, NULL);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
}
|
||
|
||
|
||
void State_OnMyAbout(HWND hWnd)
|
||
{
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
TCHAR szBuffer[256];
|
||
|
||
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hWnd, GW_OWNER), IMMGWL_IMC);
|
||
if (lpIMC = ImmLockIMC(hIMC))
|
||
{
|
||
LoadString(hInst, IDS_PROGRAM, szBuffer, sizeof(szBuffer));
|
||
ShellAbout(lpIMC->hWnd, szBuffer, NULL, LoadIcon(hInst, TEXT("IMEIcon")));
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
}
|
||
|
||
|
||
LRESULT CALLBACK CompWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
switch (uMessage)
|
||
{
|
||
HANDLE_DUMMYMSG(WM_IME_CHAR);
|
||
HANDLE_DUMMYMSG(WM_IME_COMPOSITIONFULL);
|
||
HANDLE_DUMMYMSG(WM_IME_COMPOSITION);
|
||
HANDLE_DUMMYMSG(WM_IME_CONTROL);
|
||
HANDLE_DUMMYMSG(WM_IME_NOTIFY);
|
||
HANDLE_DUMMYMSG(WM_IME_SELECT);
|
||
HANDLE_DUMMYMSG(WM_IME_SETCONTEXT);
|
||
HANDLE_DUMMYMSG(WM_IME_STARTCOMPOSITION);
|
||
HANDLE_DUMMYMSG(WM_IME_ENDCOMPOSITION);
|
||
HANDLE_MSG(hWnd, WM_PAINT, Comp_OnPaint);
|
||
}
|
||
return DefWindowProc(hWnd, uMessage, wParam, lParam);
|
||
}
|
||
|
||
|
||
void Comp_OnPaint(HWND hWnd)
|
||
{
|
||
HDC hDC;
|
||
HWND hWndUI;
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
LPCOMPOSITIONSTRING lpUICompStr;
|
||
PAINTSTRUCT ps;
|
||
HFONT hOldFont;
|
||
int iSaveBkMode;
|
||
|
||
hDC = BeginPaint(hWnd, &ps);
|
||
hWndUI = GetWindow(hWnd, GW_OWNER);
|
||
hIMC = (HIMC)GetWindowLongPtr(hWndUI, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC) {
|
||
lpUICompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
|
||
if (lpUICompStr && lpUICompStr->dwCompStrLen)
|
||
{
|
||
DrawBitmap(hDC, 0, 0, hBMComp);
|
||
iSaveBkMode = SetBkMode(hDC, TRANSPARENT);
|
||
hOldFont = SelectObject(hDC, hFontFix);
|
||
TextOut(hDC, 3, 3, (LPTSTR)lpUICompStr + lpUICompStr->dwCompStrOffset, 2);
|
||
SelectObject(hDC, hOldFont);
|
||
SetBkMode(hDC, iSaveBkMode);
|
||
}
|
||
ImmUnlockIMCC(lpIMC->hCompStr);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
EndPaint(hWnd, &ps);
|
||
}
|
||
|
||
|
||
LRESULT CALLBACK CandWndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
switch (uMessage)
|
||
{
|
||
HANDLE_DUMMYMSG(WM_IME_CHAR);
|
||
HANDLE_DUMMYMSG(WM_IME_COMPOSITIONFULL);
|
||
HANDLE_DUMMYMSG(WM_IME_COMPOSITION);
|
||
HANDLE_DUMMYMSG(WM_IME_CONTROL);
|
||
HANDLE_DUMMYMSG(WM_IME_NOTIFY);
|
||
HANDLE_DUMMYMSG(WM_IME_SELECT);
|
||
HANDLE_DUMMYMSG(WM_IME_SETCONTEXT);
|
||
HANDLE_DUMMYMSG(WM_IME_STARTCOMPOSITION);
|
||
HANDLE_DUMMYMSG(WM_IME_ENDCOMPOSITION);
|
||
HANDLE_MSG(hWnd, WM_SETCURSOR, Cand_OnSetCursor);
|
||
HANDLE_MSG(hWnd, WM_PAINT, Cand_OnPaint);
|
||
}
|
||
return DefWindowProc(hWnd, uMessage, wParam, lParam);
|
||
}
|
||
|
||
|
||
BOOL Cand_OnSetCursor(HWND hWnd, HWND hWndCursor, UINT codeHitTest, UINT msg)
|
||
{
|
||
int iLoop;
|
||
|
||
SetCursor(hIMECursor);
|
||
|
||
switch (msg)
|
||
{
|
||
case WM_LBUTTONDOWN:
|
||
GetCursorPos(&ptPos);
|
||
ScreenToClient(hWnd, &ptPos);
|
||
if (PtInRect((LPRECT)&rcCandCli, ptPos))
|
||
{
|
||
if (!PtInRect((LPRECT)&rcLArrow, ptPos)
|
||
&& !PtInRect((LPRECT)&rcRArrow, ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[0], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[1], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[2], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[3], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[4], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[5], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[6], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[7], ptPos)
|
||
&& !PtInRect((LPRECT)&rcBtn[8], ptPos))
|
||
MessageBeep(MB_ICONEXCLAMATION);
|
||
}
|
||
break;
|
||
|
||
case WM_LBUTTONUP:
|
||
GetCursorPos(&ptPos);
|
||
ScreenToClient(hWnd, &ptPos);
|
||
if (PtInRect((LPRECT)&rcLArrow, ptPos))
|
||
{
|
||
keybd_event(VK_LEFT, 0, 0, 0);
|
||
keybd_event(VK_LEFT, 0, KEYEVENTF_KEYUP, 0);
|
||
}
|
||
else if (PtInRect((LPRECT)&rcRArrow, ptPos))
|
||
{
|
||
keybd_event(VK_RIGHT, 0, 0, 0);
|
||
keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
|
||
}
|
||
else
|
||
{
|
||
for (iLoop = 0; iLoop < 9; iLoop++)
|
||
if (PtInRect((LPRECT)&rcBtn[iLoop], ptPos))
|
||
{
|
||
keybd_event((BYTE)(iLoop + '1'), 0, 0, 0);
|
||
keybd_event((BYTE)(iLoop + '1'), 0, KEYEVENTF_KEYUP, 0);
|
||
break;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void Cand_OnPaint(HWND hWnd)
|
||
{
|
||
HDC hDC;
|
||
HWND hWndUI;
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
LPCANDIDATEINFO lpCandInfo;
|
||
LPCANDIDATELIST lpCandList;
|
||
LPTSTR lpCandStr;
|
||
PAINTSTRUCT ps;
|
||
HFONT hOldFont;
|
||
DWORD iLoop, iStart;
|
||
int iSaveBkMode;
|
||
|
||
hDC = BeginPaint(hWnd, &ps);
|
||
hWndUI = GetWindow(hWnd, GW_OWNER);
|
||
hIMC = (HIMC)GetWindowLongPtr(hWndUI, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC != NULL) {
|
||
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
|
||
lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + sizeof(CANDIDATEINFO));
|
||
if (lpCandInfo && lpCandList->dwCount)
|
||
{
|
||
hOldFont = SelectObject(hDC, hFontFix);
|
||
DrawBitmap(hDC, 0, 0, hBMCand);
|
||
iSaveBkMode = SetBkMode(hDC, TRANSPARENT);
|
||
iStart = (lpCandList->dwSelection / lpCandList->dwPageSize) * lpCandList->dwPageSize;
|
||
for (iLoop = 0; iLoop < 9 && iStart+iLoop < lpCandList->dwCount; iLoop++)
|
||
{
|
||
lpCandStr = (LPTSTR)lpCandList + lpCandList->dwOffset[iStart + iLoop];
|
||
TextOut(hDC, rcBtn[iLoop].left + 10, rcBtn[iLoop].top +3, lpCandStr, 2);
|
||
}
|
||
SetBkMode(hDC, iSaveBkMode);
|
||
for (iLoop = iLoop; iLoop < 9; iLoop++)
|
||
DrawBitmap(hDC, rcBtn[iLoop].left + 3, rcBtn[iLoop].top + 6, hBMCandNum);
|
||
if (iStart)
|
||
DrawBitmap(hDC, 19, 8, hBMCandArr[0]);
|
||
if (iStart + 9 < lpCandList->dwCount)
|
||
DrawBitmap(hDC, 296, 8, hBMCandArr[1]);
|
||
SelectObject(hDC, hOldFont);
|
||
}
|
||
ImmUnlockIMCC(lpIMC->hCandInfo);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
EndPaint(hWnd, &ps);
|
||
}
|
||
|
||
|
||
LRESULT DoIMEControl(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
HGLOBAL hUIInst;
|
||
LPUIINSTANCE lpUIInst;
|
||
LPCANDIDATEFORM lpCandForm;
|
||
LPLOGFONT lpLogFont;
|
||
LOGFONT lfFont;
|
||
LPCOMPOSITIONFORM lpCompForm;
|
||
PPOINTS pPointS;
|
||
RECT rcRect;
|
||
LRESULT lRet = FALSE;
|
||
|
||
switch (wParam)
|
||
{
|
||
case IMC_GETCANDIDATEPOS:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
if (hIMC && (lpIMC = ImmLockIMC(hIMC)))
|
||
{
|
||
lpCandForm = (LPCANDIDATEFORM)lParam;
|
||
*lpCandForm = lpIMC->cfCandForm[0];
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
GetWindowRect(lpUIInst->rghWnd[CAND_WINDOW], (LPRECT)&rcRect);
|
||
lpCandForm->ptCurrentPos.x = rcRect.left;
|
||
lpCandForm->ptCurrentPos.y = rcRect.top;
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
break;
|
||
|
||
case IMC_GETCOMPOSITIONFONT:
|
||
lpLogFont = (LPLOGFONT)lParam;
|
||
if (GetObject(hFontFix, sizeof(lfFont), (LPVOID)&lfFont))
|
||
*lpLogFont = lfFont;
|
||
break;
|
||
|
||
case IMC_GETCOMPOSITIONWINDOW:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
if (hIMC && (lpIMC = ImmLockIMC(hIMC)))
|
||
{
|
||
lpCompForm = (LPCOMPOSITIONFORM)lParam;
|
||
*lpCompForm = lpIMC->cfCompForm;
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
GetWindowRect(lpUIInst->rghWnd[COMP_WINDOW], (LPRECT)&rcRect);
|
||
lpCompForm->ptCurrentPos.x = rcRect.left;
|
||
lpCompForm->ptCurrentPos.y = rcRect.top;
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
break;
|
||
|
||
case IMC_GETSTATUSWINDOWPOS:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
GetWindowRect(lpUIInst->rghWnd[STATE_WINDOW], (LPRECT)&rcRect);
|
||
pPointS = (PPOINTS)&lRet;
|
||
pPointS->x = (short)rcRect.left;
|
||
pPointS->y = (short)rcRect.top;
|
||
GlobalUnlock(hUIInst);
|
||
break;
|
||
|
||
default:
|
||
lRet = TRUE;
|
||
}
|
||
return lRet;
|
||
}
|
||
|
||
|
||
LRESULT DoIMENotify(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
HIMC hIMC;
|
||
LPINPUTCONTEXT lpIMC;
|
||
HGLOBAL hUIInst;
|
||
LPUIINSTANCE lpUIInst;
|
||
LPCANDIDATEINFO lpCandInfo;
|
||
DWORD fdwUIFlags;
|
||
POINT pt, ptTmp;
|
||
RECT rcTmp;
|
||
BOOL lRet = FALSE;
|
||
|
||
switch (wParam)
|
||
{
|
||
case IMN_OPENSTATUSWINDOW:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
fdwUIFlags = (DWORD)GetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS);
|
||
fdwUIFlags |= UIF_SHOWSTATUS;
|
||
SetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS, fdwUIFlags);
|
||
if (fWndOpen[STATE_WINDOW] != FALSE && GetWindowLongPtr(hWnd, IMMGWL_IMC)) {
|
||
ShowWindow(lpUIInst->rghWnd[STATE_WINDOW], SW_SHOWNOACTIVATE);
|
||
}
|
||
GlobalUnlock(hUIInst);
|
||
break;
|
||
|
||
case IMN_CLOSESTATUSWINDOW:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
fdwUIFlags = (DWORD)GetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS);
|
||
fdwUIFlags &= ~UIF_SHOWSTATUS;
|
||
SetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS, fdwUIFlags);
|
||
ShowWindow(lpUIInst->rghWnd[STATE_WINDOW], SW_HIDE);
|
||
GlobalUnlock(hUIInst);
|
||
break;
|
||
|
||
case IMN_CHANGECANDIDATE:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
InvalidateRect(lpUIInst->rghWnd[CAND_WINDOW], NULL, TRUE);
|
||
GlobalUnlock(hUIInst);
|
||
break;
|
||
|
||
case IMN_CLOSECANDIDATE:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC != NULL) {
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
if (lpUIInst == NULL) {
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
}
|
||
lpIMC->hCandInfo = ImmReSizeIMCC(lpIMC->hCandInfo, sizeof(CANDIDATEINFO));
|
||
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
|
||
lpCandInfo->dwSize = sizeof(CANDIDATEINFO);
|
||
lpCandInfo->dwCount = 0;
|
||
ImmUnlockIMCC(lpIMC->hCandInfo);
|
||
InvalidateRect(lpUIInst->rghWnd[STATE_WINDOW], NULL, TRUE);
|
||
ShowWindow(lpUIInst->rghWnd[CAND_WINDOW], SW_HIDE);
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
break;
|
||
|
||
case IMN_OPENCANDIDATE:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC != NULL) {
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
if (lpUIInst == NULL) {
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
}
|
||
InvalidateRect(lpUIInst->rghWnd[STATE_WINDOW], NULL, TRUE);
|
||
ShowWindow(lpUIInst->rghWnd[CAND_WINDOW], fWndOpen[CAND_WINDOW]? SW_SHOWNOACTIVATE: SW_HIDE);
|
||
UpdateWindow(lpUIInst->rghWnd[STATE_WINDOW]);
|
||
UpdateWindow(lpUIInst->rghWnd[CAND_WINDOW]);
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
}
|
||
break;
|
||
|
||
case IMN_SETCONVERSIONMODE:
|
||
case IMN_SETOPENSTATUS:
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
if (lpUIInst != NULL) {
|
||
InvalidateRect(lpUIInst->rghWnd[STATE_WINDOW], NULL, TRUE);
|
||
GlobalUnlock(hUIInst);
|
||
}
|
||
break;
|
||
|
||
case IMN_SETCANDIDATEPOS:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC == NULL)
|
||
break;
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
if (lpUIInst == NULL) {
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
}
|
||
if (lpIMC->cfCandForm[0].dwIndex == -1)
|
||
pt = ptCand;
|
||
else
|
||
{
|
||
switch (lpIMC->cfCandForm[0].dwStyle)
|
||
{
|
||
case CFS_CANDIDATEPOS:
|
||
pt = lpIMC->cfCandForm[0].ptCurrentPos;
|
||
ClientToScreen(lpIMC->hWnd, &pt);
|
||
if (pt.x < rcScreen.left)
|
||
pt.x = rcScreen.left;
|
||
else if (pt.x > rcScreen.right - CANDXSIZE)
|
||
pt.x = rcScreen.right - CANDXSIZE;
|
||
if (pt.y < rcScreen.top)
|
||
pt.y = rcScreen.top;
|
||
else if (pt.y > rcScreen.bottom - CANDYSIZE)
|
||
pt.y = rcScreen.bottom - CANDYSIZE;
|
||
break;
|
||
|
||
case CFS_EXCLUDE:
|
||
pt = lpIMC->cfCandForm[0].ptCurrentPos;
|
||
rcTmp.left = pt.x;
|
||
rcTmp.top = pt.y;
|
||
rcTmp.right = pt.x + CANDXSIZE;
|
||
rcTmp.bottom = pt.y + CANDYSIZE;
|
||
ClientToScreen(lpIMC->hWnd, &pt);
|
||
if (pt.x < rcScreen.left)
|
||
pt.x = rcScreen.left;
|
||
else if (pt.x > rcScreen.right - CANDXSIZE)
|
||
pt.x = rcScreen.right - CANDXSIZE;
|
||
if (pt.y < rcScreen.top)
|
||
pt.y = rcScreen.top;
|
||
else if (pt.y > rcScreen.bottom - CANDYSIZE)
|
||
pt.y = rcScreen.bottom - CANDYSIZE;
|
||
if (IntersectRect(&rcTmp, &rcTmp, &lpIMC->cfCandForm[0].rcArea))
|
||
{
|
||
ptTmp.x = lpIMC->cfCandForm[0].rcArea.right;
|
||
ptTmp.y = lpIMC->cfCandForm[0].rcArea.bottom;
|
||
ClientToScreen(lpIMC->hWnd, &ptTmp);
|
||
pt.y = (ptTmp.y < rcScreen.bottom - CANDYSIZE)? ptTmp.y:
|
||
ptTmp.y - lpIMC->cfCandForm[0].rcArea.bottom
|
||
+ lpIMC->cfCandForm[0].rcArea.top - CANDYSIZE;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
pt = ptCand;
|
||
}
|
||
}
|
||
MoveWindow(lpUIInst->rghWnd[CAND_WINDOW], pt.x, pt.y, CANDXSIZE, CANDYSIZE, TRUE);
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
|
||
case IMN_SETCOMPOSITIONWINDOW:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC == NULL)
|
||
break;
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
if (lpUIInst == NULL) {
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
}
|
||
if (lpIMC->cfCompForm.dwStyle & CFS_RECT)
|
||
{
|
||
pt.x = lpIMC->cfCompForm.rcArea.left;
|
||
pt.y = lpIMC->cfCompForm.rcArea.top;
|
||
ClientToScreen(lpIMC->hWnd, &pt);
|
||
}
|
||
else if (lpIMC->cfCompForm.dwStyle & CFS_POINT)
|
||
{
|
||
pt = lpIMC->cfCompForm.ptCurrentPos;
|
||
ClientToScreen(lpIMC->hWnd, &pt);
|
||
}
|
||
else // For CFS_DEFAULT
|
||
pt = lpIMC->cfCompForm.ptCurrentPos = ptComp;
|
||
MoveWindow(lpUIInst->rghWnd[COMP_WINDOW], pt.x, pt.y, COMPSIZE, COMPSIZE, TRUE);
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
|
||
case IMN_SETSTATUSWINDOWPOS:
|
||
hIMC = (HIMC)GetWindowLongPtr(hWnd, IMMGWL_IMC);
|
||
lpIMC = ImmLockIMC(hIMC);
|
||
if (lpIMC == NULL)
|
||
break;
|
||
hUIInst = (HGLOBAL)GetWindowLongPtr(hWnd, IMMGWL_PRIVATE);
|
||
lpUIInst = (LPUIINSTANCE)GlobalLock(hUIInst);
|
||
if (lpUIInst == NULL) {
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
}
|
||
MoveWindow(lpUIInst->rghWnd[STATE_WINDOW], lpIMC->ptStatusWndPos.x,
|
||
lpIMC->ptStatusWndPos.y, STATEXSIZE, STATEYSIZE, TRUE);
|
||
fdwUIFlags = (DWORD)GetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS);
|
||
fdwUIFlags |= UIF_PRIVATEPOS;
|
||
SetWindowLong(lpUIInst->rghWnd[STATE_WINDOW], UIGWL_FLAGS, fdwUIFlags);
|
||
GlobalUnlock(hUIInst);
|
||
ImmUnlockIMC(hIMC);
|
||
break;
|
||
|
||
default:
|
||
lRet = TRUE;
|
||
}
|
||
return lRet;
|
||
|
||
UNREFERENCED_PARAMETER(lParam);
|
||
}
|