IMEAPPS.C

/**********************************************************************/ 
/* */
/* IMEAPPS.C */
/* */
/* Copyright (c) 1995-1997 Microsoft Corporation */
/* */
/**********************************************************************/

#include "windows.h"
#include "commdlg.h"
#include "commctrl.h"
#include "imm.h"
#include "resource.h"
#include "imeapps.h"


/**********************************************************************/
/* */
/* WinMain(HINSTANCE, HINSTANCE, LPSTR, int) */
/* */
/**********************************************************************/
int APIENTRY WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HINSTANCE hInstance;
HINSTANCE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
MSG msg;

if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);

if (!InitInstance(hInstance, nCmdShow))
return (FALSE);


while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}

/**********************************************************************/
/* */
/* InitApplication(HANDLE) */
/* */
/**********************************************************************/
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
WNDCLASS wc;

wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance,"MyIcon");
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = "ImeAppsMenu";
wc.lpszClassName = "ImeAppsWClass";

if (! RegisterClass (&wc))
return FALSE;

wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = CompStrWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 4;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "CompStrWndClass";

if (! RegisterClass (&wc))
return FALSE;

wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = CandListWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "CandListWndClass";

if (! RegisterClass (&wc))
return FALSE;

hFont = GetStockObject(DEFAULT_GUI_FONT);

return TRUE;
}

/**********************************************************************/
/* */
/* InitInstance(HANDLE, int) */
/* */
/**********************************************************************/
BOOL InitInstance(hInstance, nCmdShow)
HANDLE hInstance;
int nCmdShow;
{
#ifdef USEWAPI
char szTitle[] = "ImeApps W API version";
#else
char szTitle[] = "ImeApps";
#endif

hInst = hInstance;


ptImeUIPos.x = 0;
ptImeUIPos.y = 0;

if (!(hWndMain = CreateWindowEx(0L,
"ImeAppsWClass", (LPSTR)szTitle,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL)))
return FALSE;

/* display each windows */
ShowWindow (hWndMain, nCmdShow);
UpdateWindow (hWndMain);


return TRUE;

}

/**********************************************************************/
/* */
/* InitIMEUIPosition(HWND) */
/* */
/**********************************************************************/
void InitIMEUIPosition(hWnd)
HWND hWnd;
{
HDC hDC;
int y;
SIZE sz;
HFONT hOldFont;
HFONT hDefFont;
int height, defheight;

hDefFont = GetStockObject(DEFAULT_GUI_FONT);

hOldFont = NULL;

y = ORG_Y;

hDC = GetDC(hWnd);

if (hFont)
hOldFont = SelectObject(hDC,hDefFont);


// Get the height of the default gui font.
GetTextExtentPoint(hDC,"A",1,&sz);
defheight = sz.cy + 1;

// Get the height of the font.
SelectObject(hDC,hFont);
GetTextExtentPoint(hDC,"A",1,&sz);
height = sz.cy + 1;

SelectObject(hDC,hDefFont);
y += defheight;

y += height;

y += height;

y += defheight;

y += height;

y += height;

ptImeUIPos.y = y;

SelectObject(hDC,hOldFont);
ReleaseDC(hWnd, hDC);

return;
}

/**********************************************************************/
/* */
/* MainWndProc(HWND, UINT, WPARAM, LPARAM) */
/* */
/**********************************************************************/
LRESULT CALLBACK MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
FARPROC lpProc;
RECT rect;
HMENU hMenu;
HIMC hIMC;
BOOL fOpen;

switch (message) {
case WM_CREATE:

// Create Status Window
CreateTBar(hWnd);
CreateStatus(hWnd);

// Create Child Window
GetClientRect(hWnd, &rect);
if (!(hWndCompStr = CreateWindowEx(WS_EX_CLIENTEDGE,
"CompStrWndClass", NULL,
WS_CHILD | WS_VISIBLE,
// 0, 0, rect.right, rect.bottom - nStatusHeight,
0, 0, 0, 0,
hWnd, NULL, hInst, NULL)))
return FALSE;


InitIMEUIPosition(hWndCompStr);


if (!(hWndCandList = CreateWindowEx(WS_EX_CLIENTEDGE,
"CandListWndClass", NULL,
WS_CHILD | WS_VISIBLE,
0, 0, 0, 0,
hWnd, NULL, hInst, NULL)))
return FALSE;

ShowWindow(hWndCompStr, SW_SHOW);
ShowWindow(hWndCandList, SW_SHOWNA);

SetStatusItems(hWnd);

hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu,IDM_SHOWCAND,
(fShowCand ? MF_CHECKED : MF_UNCHECKED));

break;

case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_ABOUT:
lpProc = MakeProcInstance(AboutDlg, hInst);
DialogBox(hInst, "ABOUTBOX", hWnd, (DLGPROC)lpProc);
FreeProcInstance(lpProc);
break;

case IDM_FONT:
{
CHOOSEFONT cf;
LOGFONT lfT;

/* Set all structure fields to zero. */

memset(&cf, 0, sizeof(CHOOSEFONT));
memcpy(&lfT, &lf, sizeof(LOGFONT));

cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = hWnd;
cf.lpLogFont = &lfT;
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
cf.nFontType = SCREEN_FONTTYPE;

if (ChooseFont(&cf))
{
if (hFont)
DeleteObject(hFont);

memcpy(&lf, &lfT, sizeof(LOGFONT));
hFont = CreateFontIndirect(&lf);
InvalidateRect(hWndCompStr,NULL,TRUE);
UpdateWindow(hWndCompStr);
}
}
break;


case IDM_SHOWCAND:
hMenu = GetMenu(hWnd);
fShowCand = !fShowCand;
CheckMenuItem(hMenu,IDM_SHOWCAND,
(fShowCand ? MF_CHECKED : MF_UNCHECKED));
MoveCompCandWindow(hWnd);
UpdateShowCandButton();
break;

case IDM_OPENSTATUS:
hIMC = ImmGetContext(hWndCompStr);
fOpen = ImmGetOpenStatus(hIMC);
ImmSetOpenStatus(hIMC,!fOpen);
UpdateShowOpenStatusButton(!fOpen);
ImmReleaseContext(hWndCompStr,hIMC);

hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu,IDM_OPENSTATUS,
(fOpen ? MF_UNCHECKED : MF_CHECKED));
break;

case IDM_NATIVEMODE:
case IDM_FULLHALF:
case IDM_ROMAN:
case IDM_CHARCODE:
case IDM_HANJA:
case IDM_SOFTKBD:
case IDM_EUDC:
case IDM_SYMBOL:
HandleModeCommand(hWnd,wParam,lParam);
break;

case IDM_CONVERT:
case IDM_CANCEL:
case IDM_REVERT:
case IDM_COMPLETE:
case IDM_OPENCAND:
case IDM_CLOSECAND:
case IDM_NEXTCAND:
case IDM_PREVCAND:
HandleConvertCommand(hWnd,wParam,lParam);
break;

case IDM_NEXTCLAUSE:
case IDM_PREVCLAUSE:
HandleChangeAttr(hWnd,(LOWORD(wParam) == IDM_NEXTCLAUSE));
break;

default:
break;


}
break;

case WM_SETFOCUS:
SetFocus(hWndCompStr);
break;

case WM_NOTIFY:
SetTooltipText(hWnd, lParam);
break;

case WM_SIZE:
SendMessage(hWndStatus,message,wParam,lParam);
SendMessage(hWndToolBar,message,wParam,lParam);

if (wParam != SIZE_MINIMIZED)
MoveCompCandWindow(hWnd);

break;

case WM_IME_NOTIFY:
switch (wParam)
{
case IMN_OPENSTATUSWINDOW:
case IMN_CLOSESTATUSWINDOW:
break;

case IMN_SETCONVERSIONMODE:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;


case WM_DESTROY:
if (hFont)
DeleteObject(hFont);
PostQuitMessage(0);
break;

default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}
/**********************************************************************/
/* */
/* CompStrWndProc(HWND, UINT, WPARAM, LPARAM) */
/* */
/**********************************************************************/
LRESULT CALLBACK CompStrWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
HIMC hIMC;
HIMC hOldIMC;

switch (message) {
case WM_CREATE:
hIMC = ImmCreateContext();
hOldIMC = ImmAssociateContext(hWnd,hIMC);
SetWindowLong(hWnd, 0, (LONG)hOldIMC);
fdwProperty = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
break;

case WM_CHAR:
HandleChar(hWnd,wParam,lParam);
break;

case WM_LBUTTONUP:
case WM_RBUTTONUP:
if (hIMC = ImmGetContext(hWnd))
{
HMENU hMenu;

InitMenuItemIDTable();
hMenu = CreateImeMenu(hWnd, hIMC, NULL,(message == WM_RBUTTONUP));

if (hMenu)
{
DWORD dwItemData;
DWORD dwPos = (DWORD)GetMessagePos();
int nCmd;

nCmd = TrackPopupMenuEx(hMenu,
TPM_RETURNCMD | TPM_NONOTIFY |
TPM_LEFTBUTTON | TPM_LEFTALIGN | TPM_TOPALIGN,
LOWORD(dwPos), HIWORD(dwPos),
hWnd, NULL);

if (nCmd)
{
nCmd -= IDM_STARTIMEMENU;
dwItemData = FindItemData(nCmd);
ImmNotifyIME(hIMC, NI_IMEMENUSELECTED, nCmd, dwItemData);
}
}
EndMenuItemIDTable();

DestroyMenu(hMenu);
}
break;

case WM_IME_SETCONTEXT:
if (fShowCand)
lParam &= ~ISC_SHOWUICANDIDATEWINDOW;

if (fdwProperty & IME_PROP_SPECIAL_UI)
{
}
else if (fdwProperty & IME_PROP_AT_CARET)
{
lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
}
else
{
}

return (DefWindowProc(hWnd, message, wParam, lParam));

case WM_IME_STARTCOMPOSITION:
// Normally, we should not call into HandleStartComposition
// for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs
// we should pass this message to DefWindowProc directly for
// this kind of IMEs

HandleStartComposition(hWnd,wParam,lParam);

// pass this message to DefWindowProc for IME_PROP_SPECIAL_UI
// and not IME_PROP_AT_CARET IMEs

if (fdwProperty & IME_PROP_SPECIAL_UI)
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}
else if (fdwProperty & IME_PROP_AT_CARET)
{
}
else
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}

break;

case WM_IME_ENDCOMPOSITION:
// Normally, we should not call into HandleEndComposition
// for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs
// we should pass this message to DefWindowProc directly for
// this kind of IMEs

HandleEndComposition(hWnd,wParam,lParam);

// pass this message to DefWindowProc for IME_PROP_SPECIAL_UI
// and not IME_PROP_AT_CARET IMEs

if (fdwProperty & IME_PROP_SPECIAL_UI)
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}
else if (fdwProperty & IME_PROP_AT_CARET)
{
}
else
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}

break;

case WM_IME_COMPOSITION:
// Normally, we should not call into HandleComposition
// for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs
// we should pass this message to DefWindowProc directly for
// this kind of IMEs

HandleComposition(hWnd,wParam,lParam);

// pass this message to DefWindowProc for IME_PROP_SPECIAL_UI
// and not IME_PROP_AT_CARET IMEs

if (fdwProperty & IME_PROP_SPECIAL_UI)
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}
else if (fdwProperty & IME_PROP_AT_CARET)
{
}
else
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}

break;

case WM_PAINT:
HandlePaint(hWnd,wParam,lParam);
break;

case WM_IME_NOTIFY:
{
LRESULT lRet;

// Normally, we should not call into HandleNotify
// for IME_PROP_SPECIAL_UI and not IME_PROP_AT_CARET IMEs
// we should pass this message to DefWindowProc directly for
// this kind of IMEs

lRet = HandleNotify(hWnd, message, wParam, lParam);

// pass this message to DefWindowProc for IME_PROP_SPECIAL_UI
// and not IME_PROP_AT_CARET IMEs

if (fdwProperty & IME_PROP_SPECIAL_UI)
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}
else if (fdwProperty & IME_PROP_AT_CARET)
{
}
else
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}

return lRet;
}

case WM_DESTROY:
hOldIMC = (HIMC)GetWindowLong(hWnd, 0);
hIMC = ImmAssociateContext(hWnd, hOldIMC);
ImmDestroyContext(hIMC);
break;

case WM_INPUTLANGCHANGE:
fdwProperty = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);

if (hIMC = ImmGetContext(hWnd))
{
CANDIDATEFORM cdf;

if (fdwProperty & IME_PROP_AT_CARET)
{
cdf.dwIndex = 0;
cdf.dwStyle = CFS_CANDIDATEPOS;
cdf.ptCurrentPos.x = ptImeUIPos.x;
cdf.ptCurrentPos.y = ptImeUIPos.y;
ImmSetCandidateWindow(hIMC, &cdf);
}
else
{
UINT i;

// The candidate position should be decided by a near caret
// IME. There are 4 candidate form in the input context

for (i = 0; i < 4; i++)
{
if (!ImmGetCandidateWindow(hIMC, i, &cdf))
{
continue;
}

if (cdf.dwStyle == CFS_DEFAULT)
{
continue;
}

cdf.dwStyle = CFS_DEFAULT;

ImmSetCandidateWindow(hIMC, &cdf);
}

}

ImmReleaseContext(hWnd, hIMC);
}

return (DefWindowProc(hWnd, message, wParam, lParam));

default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}


/**********************************************************************/
/* */
/* CandListWndProc(HWND, UINT, WPARAM, LPARAM) */
/* */
/**********************************************************************/
LRESULT CALLBACK CandListWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
switch (message) {

case WM_PAINT:
HandleCandPaint(hWnd,wParam,lParam);
break;

case WM_SETFOCUS:
SetFocus(hWndCompStr);
break;

default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}


/**********************************************************************/
/* */
/* About(HWND, UINT, WPARAM, LPARAM) */
/* */
/**********************************************************************/
LRESULT CALLBACK AboutDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WPARAM wParam;
LPARAM lParam;
{
switch (message) {
case WM_INITDIALOG:
return (TRUE);

case WM_COMMAND:
if (wParam == IDOK
|| wParam == IDCANCEL) {
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}