windows-nt/Source/XPSP1/NT/windows/feime/chs/ntabc/winabc/abc95ui.c
2020-09-26 16:20:57 +08:00

9734 lines
303 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************
* abc95ui.c *
* *
* Copyright (C) 1995-1999 Microsoft Inc. *
* *
*************************************************/
#include <windows.h>
#include <winerror.h>
#include <winuser.h>
#include <windowsx.h>
#include <immdev.h>
#include <stdio.h>
#include <shlobj.h>
#include "abc95def.h"
#include "resource.h"
#include "resrc1.h"
#include "data.H"
#define IME_CMODE_SDA 0x80000000
HWND hCrtDlg = NULL;
LONG lLock = 0; // this var is for Lock and unLock.
void PASCAL ReInitIme2(HWND ,WORD);
// Get the current user's EMB file path, and IME's MB path
// fill global variable sImeG.szIMEUserPath
void GetCurrentUserEMBPath( )
{
TCHAR szModuleName[MAX_PATH], *lpszStart, *lpszDot;
int i;
// Get the path for MB and EMB
GetModuleFileName(hInst, szModuleName, sizeof(szModuleName)/sizeof(TCHAR) );
lpszStart = szModuleName + lstrlen(szModuleName) - 1;
while ( (lpszStart != szModuleName) && ( *lpszStart != TEXT('\\') ) ) {
if ( *lpszStart == TEXT('.') ) {
lpszDot = lpszStart;
*lpszDot = TEXT('\0');
}
lpszStart --;
}
if ( *lpszStart == TEXT('\\') ) {
lpszStart ++;
}
if ( lpszStart != szModuleName ) {
for (i=0; i<lstrlen(lpszStart); i++)
szModuleName[i] = lpszStart[i];
szModuleName[i] = TEXT('\0');
}
SHGetSpecialFolderPath(NULL,sImeG.szIMEUserPath,CSIDL_APPDATA, FALSE);
if ( sImeG.szIMEUserPath[lstrlen(sImeG.szIMEUserPath)-1] == TEXT('\\') )
sImeG.szIMEUserPath[lstrlen(sImeG.szIMEUserPath) - 1] = TEXT('\0');
// Because CreateDirectory( ) cannot create directory like \AA\BB,
// if AA and BB both do not exist. It can create only one layer of
// directory each time. so we must call twice CreateDirectory( ) for
// \AA\BB
lstrcat(sImeG.szIMEUserPath, TEXT("\\Microsoft") );
if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
CreateDirectory(sImeG.szIMEUserPath, NULL);
lstrcat(sImeG.szIMEUserPath, TEXT("\\IME") );
if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
CreateDirectory(sImeG.szIMEUserPath, NULL);
lstrcat(sImeG.szIMEUserPath, TEXT("\\") );
lstrcat(sImeG.szIMEUserPath, szModuleName);
//
// Create the directory, so that CreateFile( ) can work fine later.
// ortherwise, if the directory does not exist, and you try to create
// a file under that dir, CreateFile will return error.
//
if ( GetFileAttributes(sImeG.szIMEUserPath) != FILE_ATTRIBUTE_DIRECTORY)
CreateDirectory(sImeG.szIMEUserPath, NULL);
return;
}
//**************************************************************************
//* Name : *
//* void DrawConvexRect() *
//* Description : *
//* draw a convex rectangle *
//* Parameters : *
//* hDC - the handle of DC be drawed *
//* (x1,y1) *
//* +------------+ *
//* |+----1----> | *
//* ||2 x2-2| *
//* |Vy2-2 | *
//* | | *
//* +------------+ *
//* (x2,y2) *
//* Return Value: *
//* none *
//**************************************************************************
void DrawConvexRect(
HDC hDC,
int x1,
int y1,
int x2,
int y2)
{
// draw the most outer color =light gray and black
SelectObject(hDC,sImeG.LightGrayPen);
MoveToEx(hDC, x1, y1,NULL);
LineTo(hDC, x2-1, y1);
MoveToEx(hDC, x1, y1,NULL);
LineTo(hDC, x1, y2-1);
SelectObject(hDC,sImeG.BlackPen); //GetStockObject(BLACK_PEN));
MoveToEx(hDC, x1, y2,NULL);
LineTo(hDC, x2+1, y2);
MoveToEx(hDC, x2, y1,NULL);
LineTo(hDC, x2, y2);
// draw the second line color = white and grary
SelectObject(hDC, sImeG.WhitePen); //GetStockObject(WHITE_PEN));
MoveToEx(hDC, x1+1, y1+1,NULL);
LineTo(hDC, x2-1, y1+1);
MoveToEx(hDC, x1+1, y1+1,NULL);
LineTo(hDC, x1+1, y2-1);
SelectObject(hDC,sImeG.GrayPen);
MoveToEx(hDC, x1+1, y2-1,NULL);
LineTo(hDC, x2, y2-1);
MoveToEx(hDC, x2-1, y1+1,NULL);
LineTo(hDC, x2-1, y2-1);
// draw the fourth line color = gray and white
SelectObject(hDC,sImeG.GrayPen); // CreatePen(PS_SOLID, 1, 0x00808080));
MoveToEx(hDC, x1+3, y1+3,NULL);
LineTo(hDC, x2-3, y1+3);
MoveToEx(hDC, x1+3, y1+3,NULL);
LineTo(hDC, x1+3, y2-3);
SelectObject(hDC, sImeG.WhitePen);
MoveToEx(hDC, x1+3, y2-3,NULL);
LineTo(hDC, x2-2, y2-3);
MoveToEx(hDC, x2-3, y1+3,NULL);
LineTo(hDC, x2-3, y2-3);
}
//**************************************************************************
//* Name : *
//* void DrawConcaveRect() *
//* Description : *
//* draw a concave rectangle *
//* Parameters : *
//* hDC - the handle of DC be drawed *
//* (x1,y1) x2-1 *
//* +-----1----->+ *
//* | ^ y1+1 *
//* 2 | *
//* | 3 *
//* y2-1 V | *
//* <-----4------+ *
//* x1 (x2,y2) *
//* Return Value: *
//* none *
//**************************************************************************
void DrawStatusRect(
HDC hDC,
int x1,
int y1,
int x2,
int y2)
{
SelectObject(hDC,sImeG.LightGrayPen);
MoveToEx(hDC, x1, y1,NULL);
LineTo(hDC, x2-1, y1);
MoveToEx(hDC, x1, y1,NULL);
LineTo(hDC, x1, y2-1);
SelectObject(hDC,sImeG.BlackPen); //GetStockObject(BLACK_PEN));
MoveToEx(hDC, x1, y2,NULL);
LineTo(hDC, x2+1, y2);
MoveToEx(hDC, x2, y1,NULL);
LineTo(hDC, x2, y2);
// draw the second line color = white and grary
SelectObject(hDC, sImeG.WhitePen); //GetStockObject(WHITE_PEN));
MoveToEx(hDC, x1+1, y1+1,NULL);
LineTo(hDC, x2-1, y1+1);
MoveToEx(hDC, x1+1, y1+1,NULL);
LineTo(hDC, x1+1, y2-1);
SelectObject(hDC,sImeG.GrayPen);
MoveToEx(hDC, x1+1, y2-1,NULL);
LineTo(hDC, x2, y2-1);
MoveToEx(hDC, x2-1, y1+1,NULL);
LineTo(hDC, x2-1, y2-1);
}
/**********************************************************************/
/* ShowBitmap2() */
/* a subprgm for ShowBitmap */
/**********************************************************************/
void ShowBitmap2(
HDC hDC,
int x,
int y,
int Wi,
int Hi,
HBITMAP hBitmap)
{
HDC hMemDC ;
HBITMAP hOldBmp;
hMemDC = CreateCompatibleDC(hDC);
if ( hMemDC == NULL )
return;
hOldBmp = SelectObject(hMemDC, hBitmap);
BitBlt(hDC,
x,
y,
Wi,
Hi,
hMemDC,
0,
0,
SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteDC(hMemDC);
return ;
}
/**********************************************************************/
/* ShowBitmap() */
/**********************************************************************/
void ShowBitmap(
HDC hDC,
int x,
int y,
int Wi,
int Hi,
LPSTR BitmapName)
{
HBITMAP hBitmap ;
hBitmap = LoadBitmap(hInst, BitmapName);
if ( hBitmap )
{
ShowBitmap2(hDC, x,y,Wi,Hi,hBitmap);
DeleteObject(hBitmap);
}
return ;
}
/**********************************************************************/
/* CreateUIWindow() */
/**********************************************************************/
void PASCAL CreateUIWindow( // create composition window
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
// create storage for UI setting
hUIPrivate = GlobalAlloc(GHND, sizeof(UIPRIV));
if (!hUIPrivate) { // Oh! Oh!
return;
}
SetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE, (LONG_PTR)hUIPrivate);
// set the default position for UI window, it is hide now
SetWindowPos(hUIWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOZORDER);
ShowWindow(hUIWnd, SW_SHOWNOACTIVATE);
return;
}
//ui.c skd #5
/**********************************************************************/
/* ShowSoftKbd */
/**********************************************************************/
void PASCAL ShowSoftKbd( // Show the soft keyboard window
HWND hUIWnd,
int nShowSoftKbdCmd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
LPPRIVCONTEXT lpImcP;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw status window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw status window
return;
}
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC)
return;
lpIMC =(LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC)
return;
lpImcP =(LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP){
ImmUnlockIMC(hIMC);
return;
}
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL1, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL2, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL3, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL4, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL5, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL6, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL7, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL8, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL9, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL10, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL11, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL12, MF_UNCHECKED);
CheckMenuItem(lpImeL->hSKMenu, IDM_SKL13, MF_UNCHECKED);
if (!lpUIPrivate->hSoftKbdWnd) {
// not in show status window mode
} else if (lpUIPrivate->nShowSoftKbdCmd != nShowSoftKbdCmd) {
ImmShowSoftKeyboard(lpUIPrivate->hSoftKbdWnd, nShowSoftKbdCmd);
if (nShowSoftKbdCmd != SW_HIDE){
SendMessage(lpUIPrivate->hSoftKbdWnd,WM_PAINT,0,0l);
ReDrawSdaKB(hIMC, lpImeL->dwSKWant, nShowSoftKbdCmd);
}
lpUIPrivate->nShowSoftKbdCmd = nShowSoftKbdCmd;
lpImcP->nShowSoftKbdCmd = nShowSoftKbdCmd;
if(!(lpImcP == NULL)) {
if(lpImeL->dwSKState[lpImeL->dwSKWant]) {
if(!(lpImeL->hSKMenu)) {
lpImeL->hSKMenu = LoadMenu (hInst, "SKMENU");
}
CheckMenuItem(lpImeL->hSKMenu,
lpImeL->dwSKWant + IDM_SKL1, MF_CHECKED);
}
}
}
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* ChangeCompositionSize() */
/**********************************************************************/
void PASCAL ChangeCompositionSize(
HWND hUIWnd)
{
HWND hCompWnd, hCandWnd;
RECT rcWnd;
UINT nMaxKey;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
hCompWnd = GetCompWnd(hUIWnd);
if (!hCompWnd) {
return;
}
GetWindowRect(hCompWnd, &rcWnd);
if ((rcWnd.right - rcWnd.left) != lpImeL->xCompWi) {
} else if ((rcWnd.bottom - rcWnd.top) != lpImeL->yCompHi) {
} else {
return;
}
SetWindowPos(hCompWnd, NULL,
0, 0, lpImeL->xCompWi, lpImeL->yCompHi,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
if (lpImeL->nRevMaxKey >= lpImeL->nMaxKey) {
nMaxKey = lpImeL->nRevMaxKey;
} else {
nMaxKey = lpImeL->nMaxKey;
}
SetWindowLong(hCompWnd, UI_MOVE_XY, nMaxKey);
// if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
// return;
// }
hCandWnd = GetCandWnd(hUIWnd);
if (!hCandWnd) {
return;
}
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
CalcCandPos((LPPOINT)&rcWnd);
ImmUnlockIMC(hIMC);
SetWindowPos(hCandWnd, NULL,
rcWnd.left, rcWnd.top,
0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
return;
}
/**********************************************************************/
/* ShowUI() */
/**********************************************************************/
void PASCAL ShowUI( // show the sub windows
HWND hUIWnd,
int nShowCmd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
if (nShowCmd == SW_HIDE) {
} else if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC))) {
nShowCmd = SW_HIDE;
} else if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
nShowCmd = SW_HIDE;
} else if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
ImmUnlockIMC(hIMC);
nShowCmd = SW_HIDE;
} else {
}
if (nShowCmd == SW_HIDE) {
ShowStatus(
hUIWnd, nShowCmd);
ShowComp(
hUIWnd, nShowCmd);
ShowCand(
hUIWnd, nShowCmd);
ShowSoftKbd(hUIWnd, nShowCmd);
return;
}
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw status window
goto ShowUIUnlockIMCC;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw status window
goto ShowUIUnlockIMCC;
}
if( /*(lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW)&& */
(lpImcP->fdwImeMsg & MSG_ALREADY_START)
&& (step_mode &1)){
if (lpUIPrivate->hCompWnd) {
if ((UINT)GetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_XY) !=
lpImeL->nRevMaxKey) {
ChangeCompositionSize(hUIWnd);
}
if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
// some time the WM_NCPAINT is eaten by the app
// RedrawWindow(lpUIPrivate->hCompWnd, NULL, NULL,
// RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
}
SendMessage(lpUIPrivate->hCompWnd, WM_IME_NOTIFY,
IMN_SETCOMPOSITIONWINDOW, 0);
if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
ShowComp(hUIWnd, nShowCmd);
}
} else {
StartComp(hUIWnd);
}
} else if (lpUIPrivate->nShowCompCmd == SW_HIDE) {
} else {
ShowComp(hUIWnd, SW_HIDE);
}
if ((lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW) &&
(lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)&&(step_mode == 1)) {
if (lpUIPrivate->hCandWnd) {
if (lpUIPrivate->nShowCandCmd != SW_HIDE) {
// some time the WM_NCPAINT is eaten by the app
RedrawWindow(lpUIPrivate->hCandWnd, NULL, NULL,
RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
}
SendMessage(lpUIPrivate->hCandWnd, WM_IME_NOTIFY,
IMN_SETCANDIDATEPOS, 0x0001);
if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
ShowCand(hUIWnd, nShowCmd);
}
} else {
OpenCand(hUIWnd);
}
} else if (lpUIPrivate->nShowCandCmd == SW_HIDE) {
} else {
ShowCand(hUIWnd, SW_HIDE);
}
if (lpIMC->fdwInit & INIT_SENTENCE) {
// app set the sentence mode so we should not change it
// with the configure option set by end user
} else if (lpImeL->fdwModeConfig & MODE_CONFIG_PREDICT) {
if ((WORD)lpIMC->fdwSentence != IME_SMODE_PHRASEPREDICT) {
DWORD fdwSentence;
fdwSentence = lpIMC->fdwSentence;
*(LPUNAWORD)&fdwSentence = IME_SMODE_PHRASEPREDICT;
ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
}
} else {
if ((WORD)lpIMC->fdwSentence == IME_SMODE_PHRASEPREDICT) {
DWORD fdwSentence;
fdwSentence = lpIMC->fdwSentence;
*(LPUNAWORD)&fdwSentence = IME_SMODE_NONE;
ImmSetConversionStatus(hIMC, lpIMC->fdwConversion, fdwSentence);
}
}
if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
if (!lpUIPrivate->hStatusWnd) {
OpenStatus(hUIWnd);
}
if (lpUIPrivate->nShowStatusCmd != SW_HIDE) {
// some time the WM_NCPAINT is eaten by the app
RedrawWindow(lpUIPrivate->hStatusWnd, NULL, NULL,
RDW_FRAME|RDW_INVALIDATE|RDW_ERASE);
}
SendMessage(lpUIPrivate->hStatusWnd, WM_IME_NOTIFY,
IMN_SETSTATUSWINDOWPOS, 0);
if (lpUIPrivate->nShowStatusCmd == SW_HIDE) {
ShowStatus(hUIWnd, nShowCmd);
}
else // add for bug 34131, a-zhanw, 1996-4-15
ShowStatus(hUIWnd, nShowCmd);
} else if (lpUIPrivate->hStatusWnd)
DestroyWindow(lpUIPrivate->hStatusWnd);
if (!lpIMC->fOpen) {
if (lpUIPrivate->nShowCompCmd != SW_HIDE) {
ShowSoftKbd(hUIWnd, SW_HIDE);
}
} else if ((lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) &&
(lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
if (!lpUIPrivate->hSoftKbdWnd) {
UpdateSoftKbd(hUIWnd);
} else if ((UINT)SendMessage(lpUIPrivate->hSoftKbdWnd,
WM_IME_CONTROL, IMC_GETSOFTKBDSUBTYPE, 0) !=
lpImeL->nReadLayout) {
UpdateSoftKbd(hUIWnd);
} else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
ShowSoftKbd(hUIWnd, nShowCmd);
} else if (lpUIPrivate->hIMC != hIMC) {
UpdateSoftKbd(hUIWnd);
} else {
RedrawWindow(lpUIPrivate->hSoftKbdWnd, NULL, NULL,
RDW_FRAME|RDW_INVALIDATE);
}
} else if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
} else if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
lpUIPrivate->fdwSetContext |= ISC_HIDE_SOFTKBD;
ShowSoftKbd(hUIWnd, SW_HIDE);
} else {
ShowSoftKbd(hUIWnd, SW_HIDE);
}
// we switch to this hIMC
lpUIPrivate->hIMC = hIMC;
GlobalUnlock(hUIPrivate);
ShowUIUnlockIMCC:
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* MoveCompCand() */
/**********************************************************************/
void PASCAL MoveCompCand( // show the sub windows
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
if (!(hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC)))
return;
if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)))
return ;
if (!(lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate))) {
ImmUnlockIMC(hIMC);
return ;
}
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // Oh! Oh!
return;
}
// composition window need to be destroyed
if (lpUIPrivate->hCandWnd) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)
MoveWindow(lpUIPrivate->hCandWnd,
lpImeL->ptDefCand.x,
lpImeL->ptDefCand.y,
sImeG.xCandWi,
sImeG.yCandHi,
TRUE);
}
// candidate window need to be destroyed
if (lpUIPrivate->hCompWnd) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_START)
MoveWindow(
lpUIPrivate->hCompWnd,
lpImeL->ptDefComp.x,
lpImeL->ptDefComp.y,
lpImeL->xCompWi,lpImeL->yCompHi,
TRUE );
}
GlobalUnlock(hUIPrivate);
}
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* CheckSoftKbdPosition() */
/**********************************************************************/
void PASCAL CheckSoftKbdPosition(
LPUIPRIV lpUIPrivate,
LPINPUTCONTEXT lpIMC)
{
UINT fPortionBits = 0;
UINT fPortionTest;
int xPortion, yPortion, nPortion;
RECT rcWnd;
// portion of dispaly
// 0 1
// 2 3
if (lpUIPrivate->hCompWnd) {
GetWindowRect(lpUIPrivate->hCompWnd, &rcWnd);
if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
xPortion = 1;
} else {
xPortion = 0;
}
if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
yPortion = 1;
} else {
yPortion = 0;
}
fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
}
if (lpUIPrivate->hStatusWnd) {
GetWindowRect(lpUIPrivate->hStatusWnd, &rcWnd);
if (rcWnd.left > sImeG.rcWorkArea.right / 2) {
xPortion = 1;
} else {
xPortion = 0;
}
if (rcWnd.top > sImeG.rcWorkArea.bottom / 2) {
yPortion = 1;
} else {
yPortion = 0;
}
fPortionBits |= 0x0001 << (yPortion * 2 + xPortion);
}
GetWindowRect(lpUIPrivate->hSoftKbdWnd, &rcWnd);
// start from portion 3
for (nPortion = 3, fPortionTest = 0x0008; fPortionTest;
nPortion--, fPortionTest >>= 1) {
if (fPortionTest & fPortionBits) {
// someone here!
continue;
}
if (nPortion % 2) {
lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.right -
(rcWnd.right - rcWnd.left) - UI_MARGIN;
} else {
lpIMC->ptSoftKbdPos.x = sImeG.rcWorkArea.left;
}
if (nPortion / 2) {
lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.bottom -
(rcWnd.bottom - rcWnd.top) - UI_MARGIN;
} else {
lpIMC->ptSoftKbdPos.y = sImeG.rcWorkArea.top;
}
lpIMC->fdwInit |= INIT_SOFTKBDPOS;
break;
}
return;
}
// sdk #6
/**********************************************************************/
/* SetSoftKbdData() */
/**********************************************************************/
void PASCAL SetSoftKbdData(
HWND hSoftKbdWnd,
LPINPUTCONTEXT lpIMC)
{
int i;
LPSOFTKBDDATA lpSoftKbdData;
LPPRIVCONTEXT lpImcP;
HGLOBAL hsSoftKbdData;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
return;
}
hsSoftKbdData = GlobalAlloc(GHND, sizeof(SOFTKBDDATA) * 2);
if (!hsSoftKbdData) {
ImmUnlockIMCC(lpIMC->hPrivate);
return;
}
lpSoftKbdData = (LPSOFTKBDDATA)GlobalLock(hsSoftKbdData);
if (!lpSoftKbdData) { // can not draw soft keyboard window
ImmUnlockIMCC(lpIMC->hPrivate);
return;
}
lpSoftKbdData->uCount = 2;
for (i = 0; i < 48; i++) {
BYTE bVirtKey;
bVirtKey = VirtKey48Map[i];
if (!bVirtKey) {
continue;
}
{
WORD CHIByte, CLOByte;
CHIByte = SKLayout[lpImeL->dwSKWant][i*2] & 0x00ff;
CLOByte = SKLayout[lpImeL->dwSKWant][i*2 + 1] & 0x00ff;
lpSoftKbdData->wCode[0][bVirtKey] = (CHIByte << 8) | CLOByte;
CHIByte = SKLayoutS[lpImeL->dwSKWant][i*2] & 0x00ff;
CLOByte = SKLayoutS[lpImeL->dwSKWant][i*2 + 1] & 0x00ff;
lpSoftKbdData->wCode[1][bVirtKey] = (CHIByte << 8) | CLOByte;
}
}
SendMessage(hSoftKbdWnd, WM_IME_CONTROL, IMC_SETSOFTKBDDATA,
(LPARAM)lpSoftKbdData);
GlobalUnlock(hsSoftKbdData);
// free storage for UI settings
GlobalFree(hsSoftKbdData);
ImmUnlockIMCC(lpIMC->hPrivate);
return;
}
//sdk #7
/**********************************************************************/
/* UpdateSoftKbd() */
/**********************************************************************/
void PASCAL UpdateSoftKbd(
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
LPPRIVCONTEXT lpImcP;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP){
ImmUnlockIMC(hIMC);
return;
}
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw soft keyboard window
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw soft keyboard window
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return;
}
if (!(lpIMC->fdwConversion & IME_CMODE_SOFTKBD)) {
if (lpUIPrivate->hSoftKbdWnd) {
ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
lpImcP->hSoftKbdWnd = NULL;
lpUIPrivate->hSoftKbdWnd = NULL;
}
lpUIPrivate->nShowSoftKbdCmd = SW_HIDE;
lpImcP->nShowSoftKbdCmd = SW_HIDE;
} else if (!lpIMC->fOpen) {
if (lpUIPrivate->nShowSoftKbdCmd != SW_HIDE) {
ShowSoftKbd(hUIWnd, SW_HIDE/*, NULL*/);
}
} else {
if (!lpUIPrivate->hSoftKbdWnd) {
// create soft keyboard
lpUIPrivate->hSoftKbdWnd =
ImmCreateSoftKeyboard(SOFTKEYBOARD_TYPE_C1, hUIWnd,
0, 0);
lpImcP->hSoftKbdWnd = lpUIPrivate->hSoftKbdWnd;
}
if (!(lpIMC->fdwInit & INIT_SOFTKBDPOS)) {
CheckSoftKbdPosition(lpUIPrivate, lpIMC);
}
SetSoftKbdData(lpUIPrivate->hSoftKbdWnd, lpIMC);
if (lpUIPrivate->nShowSoftKbdCmd == SW_HIDE) {
SetWindowPos(lpUIPrivate->hSoftKbdWnd, NULL,
lpIMC->ptSoftKbdPos.x, lpIMC->ptSoftKbdPos.y,
0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
// only show, if the application want to show it
//if (lpUIPrivate->fdwSetContext & ISC_SHOW_SOFTKBD) { //zst 95/9/28
ShowSoftKbd(hUIWnd, SW_SHOWNOACTIVATE/*, lpImcP*/);
// } zst 95/9/28
}
}
GlobalUnlock(hUIPrivate);
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* ShowGuideLine */
/**********************************************************************/
void PASCAL ShowGuideLine(
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPGUIDELINE lpGuideLine;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
if (!lpGuideLine) {
} else if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
MessageBeep((UINT)-1);
MessageBeep((UINT)-1);
} else if (lpGuideLine->dwLevel == GL_LEVEL_WARNING) {
MessageBeep((UINT)-1);
} else {
}
ImmUnlockIMCC(lpIMC->hGuideLine);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* StatusWndMsg() */
/**********************************************************************/
void PASCAL StatusWndMsg( // set the show hide state and
HWND hUIWnd,
BOOL fOn)
{
HGLOBAL hUIPrivate;
HIMC hIMC;
HWND hStatusWnd;
register LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return;
}
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if(!hIMC){
return;
}
if (fOn) {
lpUIPrivate->fdwSetContext |= ISC_OPEN_STATUS_WINDOW;
if (!lpUIPrivate->hStatusWnd) {
OpenStatus(
hUIWnd);
}
} else {
lpUIPrivate->fdwSetContext &= ~(ISC_OPEN_STATUS_WINDOW);
}
hStatusWnd = lpUIPrivate->hStatusWnd;
GlobalUnlock(hUIPrivate);
if (!hStatusWnd) {
return;
}
if (!fOn) {
register DWORD fdwSetContext;
/*
fdwSetContext = lpUIPrivate->fdwSetContext &
(ISC_SHOWUICOMPOSITIONWINDOW|ISC_HIDE_COMP_WINDOW);
if (fdwSetContext == ISC_HIDE_COMP_WINDOW) {
ShowComp(
hUIWnd, SW_HIDE);
}
fdwSetContext = lpUIPrivate->fdwSetContext &
(ISC_SHOWUICANDIDATEWINDOW|ISC_HIDE_CAND_WINDOW);
if (fdwSetContext == ISC_HIDE_CAND_WINDOW) {
ShowCand(
hUIWnd, SW_HIDE);
}
fdwSetContext = lpUIPrivate->fdwSetContext &
(ISC_SHOW_SOFTKBD|ISC_HIDE_SOFTKBD);
if (fdwSetContext == ISC_HIDE_SOFTKBD) {
lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
ShowSoftKbd(hUIWnd, SW_HIDE, NULL);
}
ShowStatus(
hUIWnd, SW_HIDE);
*/
ShowComp(hUIWnd, SW_HIDE);
ShowCand(hUIWnd, SW_HIDE);
// ShowSoftKbd(hUIWnd, SW_HIDE);
fdwSetContext = lpUIPrivate->fdwSetContext &
(ISC_SHOW_SOFTKBD|ISC_HIDE_SOFTKBD);
if (fdwSetContext == ISC_HIDE_SOFTKBD) {
lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_SOFTKBD);
ShowSoftKbd(hUIWnd, SW_HIDE);
}
ShowStatus(hUIWnd, SW_HIDE);
} else if (hIMC) {
ShowStatus(
hUIWnd, SW_SHOWNOACTIVATE);
} else {
ShowStatus(
hUIWnd, SW_HIDE);
}
return;
}
/**********************************************************************/
/* NotifyUI() */
/**********************************************************************/
void PASCAL NotifyUI(
HWND hUIWnd,
WPARAM wParam,
LPARAM lParam)
{
HWND hStatusWnd;
switch (wParam) {
case IMN_OPENSTATUSWINDOW:
StatusWndMsg(hUIWnd, TRUE);
break;
case IMN_CLOSESTATUSWINDOW:
StatusWndMsg(hUIWnd, FALSE);
break;
case IMN_OPENCANDIDATE:
if (lParam & 0x00000001) {
OpenCand(hUIWnd);
}
break;
case IMN_CHANGECANDIDATE:
if (lParam & 0x00000001) {
HWND hCandWnd;
HDC hDC;
hCandWnd = GetCandWnd(hUIWnd);
if (!hCandWnd) {
return;
}
hDC = GetDC(hCandWnd);
UpdateCandWindow2(hCandWnd, hDC);
ReleaseDC(hCandWnd, hDC);
}
break;
case IMN_CLOSECANDIDATE:
if (lParam & 0x00000001) {
CloseCand(hUIWnd);
}
break;
case IMN_SETSENTENCEMODE:
break;
case IMN_SETCONVERSIONMODE:
case IMN_SETOPENSTATUS:
hStatusWnd = GetStatusWnd(hUIWnd);
if (hStatusWnd) {
InvalidateRect(hStatusWnd, &sImeG.rcStatusText, FALSE);
UpdateWindow(hStatusWnd);
}
break;
case IMN_SETCOMPOSITIONFONT:
// we are not going to change font, but an IME can do this if it want
break;
case IMN_SETCOMPOSITIONWINDOW:
SetCompWindow(hUIWnd);
break;
case IMN_SETSTATUSWINDOWPOS:
// SetStatusWindowPos(hUIWnd);
SetStatusWindowPos(GetStatusWnd(hUIWnd));
break;
case IMN_GUIDELINE:
ShowGuideLine(hUIWnd);
break;
case IMN_PRIVATE:
switch (lParam) {
case IMN_PRIVATE_UPDATE_SOFTKBD:
UpdateSoftKbd(hUIWnd);
break;
default:
break;
}
break;
default:
break;
}
return;
}
/**********************************************************************/
/* SetContext() */
/**********************************************************************/
void PASCAL SetContext( // the context activated/deactivated
HWND hUIWnd,
BOOL fOn,
LPARAM lShowUI)
{
HGLOBAL hUIPrivate;
register LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return;
}
if (fOn) {
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
if(!sImeG.Prop)
InitUserSetting();
ReInitIme2(lpUIPrivate->hStatusWnd, lpImeL->wImeStyle);
lpUIPrivate->fdwSetContext = (lpUIPrivate->fdwSetContext &
~ISC_SHOWUIALL) | ((DWORD)lShowUI & ISC_SHOWUIALL) | ISC_SHOW_SOFTKBD;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
goto SetCxtUnlockUIPriv;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
goto SetCxtUnlockUIPriv;
}
if (lpIMC->cfCandForm[0].dwIndex != 0) {
lpIMC->cfCandForm[0].dwStyle = CFS_DEFAULT;
}
ImmUnlockIMC(hIMC);
} else {
lpUIPrivate->fdwSetContext &= ~ISC_SETCONTEXT_UI;
}
if(fOn){
BOOL x;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
goto SetCxtUnlockUIPriv;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC)
goto SetCxtUnlockUIPriv;
x = GetKeyState(VK_CAPITAL)&1;
if(!x && (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION)){
lpIMC->fdwConversion = lpIMC->fdwConversion & (~IME_CMODE_NOCONVERSION)|IME_CMODE_NATIVE;
}
if(x && (lpIMC->fdwConversion & IME_CMODE_NATIVE)){
lpIMC->fdwConversion = lpIMC->fdwConversion & (~IME_CMODE_NATIVE) |(IME_CMODE_NOCONVERSION);
InitCvtPara();
}
//lpIMC->fdwConversion = IME_CMODE_NOCONVERSION;
ImmUnlockIMC(hIMC);
}
SetCxtUnlockUIPriv:
GlobalUnlock(hUIPrivate);
UIPaint(hUIWnd);
// PostMessage(hUIWnd, WM_PAINT, 0, 0); //zl3
return;
}
/**********************************************************************/
/* GetConversionMode() */
/* Return Value : */
/* the conversion mode */
/**********************************************************************/
LRESULT PASCAL GetConversionMode(
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
DWORD fdwConversion;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (LRESULT)NULL;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (LRESULT)NULL;
}
fdwConversion = lpIMC->fdwConversion;
ImmUnlockIMC(hIMC);
return (LRESULT)fdwConversion;
}
/**********************************************************************/
/* SetConversionMode() */
/* Return Value : */
/* NULL - successful, else - failure */
/**********************************************************************/
LRESULT PASCAL SetConversionMode( // set conversion mode
HWND hUIWnd,
DWORD dwNewConvMode)
{
HIMC hIMC;
DWORD dwOldConvMode, fdwOldSentence;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
if (!ImmGetConversionStatus(hIMC, &dwOldConvMode, &fdwOldSentence))
return (LRESULT)(1L);
return (LRESULT)!ImmSetConversionStatus(hIMC, dwNewConvMode,
fdwOldSentence);
}
/**********************************************************************/
/* GetSentenceMode() */
/* Return Value : */
/* the sentence mode */
/**********************************************************************/
LRESULT PASCAL GetSentenceMode(
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
DWORD fdwSentence;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (LRESULT)NULL;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (LRESULT)NULL;
}
fdwSentence = lpIMC->fdwSentence;
ImmUnlockIMC(hIMC);
return (LRESULT)fdwSentence;
}
/**********************************************************************/
/* SetSentenceMode() */
/* Return Value : */
/* NULL - successful, else - failure */
/**********************************************************************/
LRESULT PASCAL SetSentenceMode( // set the sentence mode
HWND hUIWnd,
DWORD dwNewSentence)
{
HIMC hIMC;
DWORD dwOldConvMode, fdwOldSentence;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
if (!ImmGetConversionStatus(hIMC, &dwOldConvMode, &fdwOldSentence)) {
return (LRESULT)(1L);
}
return (LRESULT)!ImmSetConversionStatus(hIMC, dwOldConvMode,
dwNewSentence);
}
/**********************************************************************/
/* GetOpenStatus() */
/* Return Value : */
/* the open status */
/**********************************************************************/
LRESULT PASCAL GetOpenStatus(
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
BOOL fOpen;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (LRESULT)NULL;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (LRESULT)NULL;
}
fOpen = (BOOL)lpIMC->fOpen;
ImmUnlockIMC(hIMC);
return (LRESULT)fOpen;
}
/**********************************************************************/
/* SetOpenStatus() */
/* Return Value : */
/* NULL - successful, else - failure */
/**********************************************************************/
LRESULT PASCAL SetOpenStatus( // set open/close status
HWND hUIWnd,
BOOL fNewOpenStatus)
{
HIMC hIMC;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
return (LRESULT)!ImmSetOpenStatus(hIMC, fNewOpenStatus);
}
/**********************************************************************/
/* SetCompFont() */
/**********************************************************************/
LRESULT PASCAL SetCompFont(
HWND hUIWnd,
LPLOGFONT lplfFont)
{
HIMC hIMC;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
return (LRESULT)!ImmSetCompositionFont(hIMC, lplfFont);
}
/**********************************************************************/
/* GetCompWindow() */
/**********************************************************************/
LRESULT PASCAL GetCompWindow(
HWND hUIWnd,
LPCOMPOSITIONFORM lpCompForm)
{
HWND hCompWnd;
RECT rcCompWnd;
hCompWnd = GetCompWnd(hUIWnd);
if (!hCompWnd) {
return (1L);
}
if (!GetWindowRect(hCompWnd, &rcCompWnd)) {
return (1L);
}
lpCompForm->dwStyle = CFS_POINT|CFS_RECT;
lpCompForm->ptCurrentPos = *(LPPOINT)&rcCompWnd;
lpCompForm->rcArea = rcCompWnd;
return (0L);
}
/**********************************************************************/
/* SelectIME() */
/**********************************************************************/
void PASCAL SelectIME( // switch IMEs
HWND hUIWnd,
BOOL fSelect)
{
if (!fSelect) {
ShowUI(hUIWnd, SW_HIDE);
} else {
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
MessageBeep((UINT)-1);
return;
}
if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
MessageBeep((UINT)-1);
return;
}
if(GetKeyState(VK_CAPITAL)&1){
lpIMC->fdwConversion |= IME_CMODE_NOCONVERSION;
lpIMC->fdwConversion &= ~IME_CMODE_NATIVE;
cap_mode = 1;
}else{
lpIMC->fdwConversion |= IME_CMODE_NATIVE;
lpIMC->fdwConversion &= ~IME_CMODE_NOCONVERSION;
cap_mode = 0;
}
ImmUnlockIMC(hIMC);
UpdateSoftKbd(hUIWnd);
ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
}
return;
}
/**********************************************************************/
/* ToggleUI() */
/**********************************************************************/
/*
void PASCAL ToggleUI(
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
DWORD fdwFlag;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
HWND hDestroyWnd;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return;
}
//if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
// if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
// goto ToggleUIOvr;
// } else {
// fdwFlag = 0;
// }
//} else {
// if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
// fdwFlag = ISC_OFF_CARET_UI;
// } else {
// goto ToggleUIOvr;
// }
//}
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
goto ToggleUIOvr;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
goto ToggleUIOvr;
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
goto CreateUIOvr;
}
if (fdwFlag & ISC_OFF_CARET_UI) {
lpUIPrivate->fdwSetContext |= (ISC_OFF_CARET_UI);
} else {
lpUIPrivate->fdwSetContext &= ~(ISC_OFF_CARET_UI);
}
hDestroyWnd = NULL;
// we need to dsetroy status first because lpUIPrivate->hStatusWnd
// may be NULL out in OffCreat UI destroy time
if (lpUIPrivate->hStatusWnd) {
if (lpUIPrivate->hStatusWnd != hDestroyWnd) {
hDestroyWnd = lpUIPrivate->hStatusWnd;
DestroyWindow(lpUIPrivate->hStatusWnd);
}
lpUIPrivate->hStatusWnd = NULL;
}
// destroy all off caret UI
if (lpUIPrivate->hCompWnd) {
if (lpUIPrivate->hCompWnd != hDestroyWnd) {
hDestroyWnd = lpUIPrivate->hCompWnd;
DestroyWindow(lpUIPrivate->hCompWnd);
}
lpUIPrivate->hCompWnd = NULL;
lpUIPrivate->nShowCompCmd = SW_HIDE;
}
if (lpUIPrivate->hCandWnd) {
if (lpUIPrivate->hCandWnd != hDestroyWnd) {
hDestroyWnd = lpUIPrivate->hCandWnd;
DestroyWindow(lpUIPrivate->hCandWnd);
}
lpUIPrivate->hCandWnd = NULL;
lpUIPrivate->nShowCandCmd = SW_HIDE;
}
if (lpUIPrivate->fdwSetContext & ISC_OPEN_STATUS_WINDOW) {
OpenStatus(hUIWnd);
}
if (!(lpUIPrivate->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW)) {
} else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
StartComp(hUIWnd);
} else {
}
if (!(lpUIPrivate->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW)) {
} else if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
if (!(fdwFlag & ISC_OFF_CARET_UI)) {
NotifyIME(hIMC, NI_SETCANDIDATE_PAGESIZE, 0, CANDPERPAGE);
}
OpenCand(hUIWnd);
} else {
}
ImmUnlockIMCC(lpIMC->hPrivate);
CreateUIOvr:
ImmUnlockIMC(hIMC);
ToggleUIOvr:
GlobalUnlock(hUIPrivate);
return;
}
*/
/**********************************************************************/
/* UIPaint() */
/**********************************************************************/
LRESULT PASCAL UIPaint(
HWND hUIWnd)
{
PAINTSTRUCT ps;
MSG sMsg;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
// for safety
BeginPaint(hUIWnd, &ps);
EndPaint(hUIWnd, &ps);
// some application will not remove the WM_PAINT messages
PeekMessage(&sMsg, hUIWnd, WM_PAINT, WM_PAINT, PM_REMOVE|PM_NOYIELD);
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return (0L);
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return (0L);
}
if (lpUIPrivate->fdwSetContext & ISC_SHOW_UI_ALL) { //ZL1
//if (lpUIPrivate->fdwSetContext & ISC_SETCONTEXT_UI) {
/*
if (lpUIPrivate->fdwSetContext & ISC_OFF_CARET_UI) {
if (!(lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI)){
ToggleUI(hUIWnd);
}
} else {
if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
ToggleUI(hUIWnd);
}
}
*/
ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
} else {
ShowUI(hUIWnd, SW_HIDE);
}
GlobalUnlock(hUIPrivate);
return (0L);
}
/**********************************************************************/
/* UIWndProc() */
/**********************************************************************/
LRESULT CALLBACK UIWndProc( // maybe not good but this UI
// window also is composition window
HWND hUIWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
lpImeL->TempUIWnd = hUIWnd ;
switch (uMsg) {
case WM_NEW_WORD:
// DefNewNow = 0;
UpdateUser();
break;
case WM_CREATE:
CreateUIWindow(hUIWnd);
break;
case WM_DESTROY:
DestroyUIWindow(hUIWnd);
break;
case WM_IME_STARTCOMPOSITION:
// you can create a window as the composition window here
StartComp(hUIWnd);
if (lParam==0x6699)
show_char(NULL,0);
break;
case WM_IME_COMPOSITION:
if (lParam & GCS_RESULTSTR) {
MoveDefaultCompPosition(hUIWnd);
}
UpdateCompWindow(hUIWnd);
break;
case WM_IME_ENDCOMPOSITION:
// you can destroy the composition window here
EndComp(hUIWnd);
break;
case WM_IME_NOTIFY:
NotifyUI(hUIWnd, wParam, lParam);
break;
case WM_IME_SETCONTEXT:
SetContext(hUIWnd, (BOOL)wParam, lParam);
break;
case WM_IME_CONTROL:
switch (wParam) {
case IMC_SETCONVERSIONMODE:
return SetConversionMode(hUIWnd, (DWORD)lParam);
case IMC_SETSENTENCEMODE:
return SetSentenceMode(hUIWnd, (DWORD)lParam);
case IMC_SETOPENSTATUS:
return SetOpenStatus(hUIWnd, (BOOL)lParam);
case IMC_GETCANDIDATEPOS:
return GetCandPos(hUIWnd,(LPCANDIDATEFORM)lParam);
return (1L); // not implemented yet
case IMC_SETCANDIDATEPOS:
return SetCandPosition(hUIWnd, (LPCANDIDATEFORM)lParam);
case IMC_GETCOMPOSITIONFONT:
return (1L); // not implemented yet
case IMC_SETCOMPOSITIONFONT:
return SetCompFont(hUIWnd, (LPLOGFONT)lParam);
case IMC_GETCOMPOSITIONWINDOW:
return GetCompWindow(hUIWnd, (LPCOMPOSITIONFORM)lParam);
case IMC_SETCOMPOSITIONWINDOW:
{
HIMC hIMC;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
return (LRESULT)!ImmSetCompositionWindow(hIMC,
(LPCOMPOSITIONFORM)lParam);
}
return (1L);
case IMC_GETSTATUSWINDOWPOS:
{
HWND hStatusWnd;
RECT rcStatusWnd;
LPARAM lParam;
hStatusWnd = GetStatusWnd(hUIWnd);
if (!hStatusWnd) {
return (0L); // fail, return (0, 0)?
}
if (!GetWindowRect(hStatusWnd, &rcStatusWnd)) {
return (0L); // fail, return (0, 0)?
}
lParam = MAKELRESULT(rcStatusWnd.left, rcStatusWnd.right);
return (lParam);
}
return (0L);
case IMC_SETSTATUSWINDOWPOS:
{
HIMC hIMC;
POINT ptPos;
ptPos.x = ((LPPOINTS)&lParam)->x;
ptPos.y = ((LPPOINTS)&lParam)->y;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
return ImmSetStatusWindowPos(hIMC, &ptPos);
}
return (1L);
default:
return (1L);
}
break;
case WM_IME_COMPOSITIONFULL:
return (0L);
case WM_IME_SELECT:
SelectIME(hUIWnd, (BOOL)wParam);
return (0L);
case WM_MOUSEACTIVATE:
return (MA_NOACTIVATE);
case WM_PAINT:
UIPaint(hUIWnd);
return 0L; //ZL2
default:
return DefWindowProc(hUIWnd, uMsg, wParam, lParam);
}
return (0L);
}
/**********************************************************************/
/* DrawFrameBorder() */
/**********************************************************************/
void PASCAL DrawFrameBorder( // border of IME
HDC hDC,
HWND hWnd) // window of IME
{
RECT rcWnd;
int xWi, yHi;
GetWindowRect(hWnd, &rcWnd);
xWi = rcWnd.right - rcWnd.left;
yHi = rcWnd.bottom - rcWnd.top;
// 1, ->
PatBlt(hDC, 0, 0, xWi, 1, WHITENESS);
// 1, v
PatBlt(hDC, 0, 0, 1, yHi, WHITENESS);
// 1, _>
PatBlt(hDC, 0, yHi, xWi, -1, BLACKNESS);
// 1, v
PatBlt(hDC, xWi, 0, -1, yHi, BLACKNESS);
xWi -= 2;
yHi -= 2;
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
// 2, ->
PatBlt(hDC, 1, 1, xWi, 1, PATCOPY);
// 2, v
PatBlt(hDC, 1, 1, 1, yHi, PATCOPY);
// 2, v
PatBlt(hDC, xWi + 1, 1, -1, yHi, PATCOPY);
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
// 2, _>
PatBlt(hDC, 1, yHi + 1, xWi, -1, PATCOPY);
xWi -= 2;
yHi -= 2;
// 3, ->
PatBlt(hDC, 2, 2, xWi, 1, PATCOPY);
// 3, v
PatBlt(hDC, 2, 2, 1, yHi, PATCOPY);
// 3, v
PatBlt(hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
// 3, _>
PatBlt(hDC, 2, yHi + 2, xWi, -1, PATCOPY);
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
xWi -= 2;
yHi -= 2;
// 4, ->
PatBlt(hDC, 3, 3, xWi, 1, PATCOPY);
// 4, v
PatBlt(hDC, 3, 3, 1, yHi, PATCOPY);
SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
// 4, v
PatBlt(hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
// 4, _>
PatBlt(hDC, 3, yHi + 3, xWi, -1, WHITENESS);
return;
}
/**********************************************************************/
/* GetCompWnd */
/* Return Value : */
/* window handle of composition */
/**********************************************************************/
HWND PASCAL GetCompWnd(
HWND hUIWnd) // UI window
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HWND hCompWnd;
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;
}
hCompWnd = lpUIPrivate->hCompWnd;
GlobalUnlock(hUIPrivate);
return (hCompWnd);
}
/**********************************************************************/
/* GetNearCaretPosition() */
/**********************************************************************/
void PASCAL GetNearCaretPosition( // decide a near caret position according
// to the caret position
LPPOINT lpptFont,
UINT uEsc,
UINT uRot,
LPPOINT lpptCaret,
LPPOINT lpptNearCaret,
BOOL fFlags)
{
LONG lFontSize;
LONG xWidthUI, yHeightUI, xBorder, yBorder;
if ((uEsc + uRot) & 0x0001) {
lFontSize = lpptFont->x;
} else {
lFontSize = lpptFont->y;
}
if (fFlags & NEAR_CARET_CANDIDATE) {
xWidthUI = sImeG.xCandWi;
yHeightUI = sImeG.yCandHi;
xBorder = sImeG.cxCandBorder;
yBorder = sImeG.cyCandBorder;
} else {
xWidthUI = lpImeL->xCompWi;
yHeightUI = lpImeL->yCompHi;
xBorder = lpImeL->cxCompBorder;
yBorder = lpImeL->cyCompBorder;
}
if (fFlags & NEAR_CARET_FIRST_TIME) {
lpptNearCaret->x = lpptCaret->x +
lFontSize * ncUIEsc[uEsc].iLogFontFacX +
sImeG.iPara * ncUIEsc[uEsc].iParaFacX +
sImeG.iPerp * ncUIEsc[uEsc].iPerpFacX;
if (ptInputEsc[uEsc].x >= 0) {
lpptNearCaret->x += xBorder * 2;
} else {
lpptNearCaret->x -= xWidthUI - xBorder * 2;
}
lpptNearCaret->y = lpptCaret->y +
lFontSize * ncUIEsc[uEsc].iLogFontFacY +
sImeG.iPara * ncUIEsc[uEsc].iParaFacY +
sImeG.iPerp * ncUIEsc[uEsc].iPerpFacY;
if (ptInputEsc[uEsc].y >= 0) {
lpptNearCaret->y += yBorder * 2;
} else {
lpptNearCaret->y -= yHeightUI - yBorder * 2;
}
} else {
lpptNearCaret->x = lpptCaret->x +
lFontSize * ncAltUIEsc[uEsc].iLogFontFacX +
sImeG.iPara * ncAltUIEsc[uEsc].iParaFacX +
sImeG.iPerp * ncAltUIEsc[uEsc].iPerpFacX;
if (ptAltInputEsc[uEsc].x >= 0) {
lpptNearCaret->x += xBorder * 2;
} else {
lpptNearCaret->x -= xWidthUI - xBorder * 2;
}
lpptNearCaret->y = lpptCaret->y +
lFontSize * ncAltUIEsc[uEsc].iLogFontFacY +
sImeG.iPara * ncAltUIEsc[uEsc].iParaFacY +
sImeG.iPerp * ncAltUIEsc[uEsc].iPerpFacY;
if (ptAltInputEsc[uEsc].y >= 0) {
lpptNearCaret->y += yBorder * 2;
} else {
lpptNearCaret->y -= yHeightUI - yBorder * 2;
}
}
if (lpptNearCaret->x < sImeG.rcWorkArea.left) {
lpptNearCaret->x = sImeG.rcWorkArea.left;
} else if (lpptNearCaret->x + xWidthUI > sImeG.rcWorkArea.right) {
lpptNearCaret->x = sImeG.rcWorkArea.right - xWidthUI;
} else {
}
if (lpptNearCaret->y < sImeG.rcWorkArea.top) {
lpptNearCaret->y = sImeG.rcWorkArea.top;
} else if (lpptNearCaret->y + yHeightUI > sImeG.rcWorkArea.bottom) {
lpptNearCaret->y = sImeG.rcWorkArea.bottom - yHeightUI;
} else {
}
return;
}
/**********************************************************************/
/* FitInLazyOperation() */
/* Return Value : */
/* TRUE or FALSE */
/**********************************************************************/
BOOL PASCAL FitInLazyOperation( // fit in lazy operation or not
LPPOINT lpptOrg,
LPPOINT lpptNearCaret, // the suggested near caret position
LPRECT lprcInputRect,
UINT uEsc)
{
POINT ptDelta, ptTol;
RECT rcUIRect, rcInterRect;
ptDelta.x = lpptOrg->x - lpptNearCaret->x;
ptDelta.x = (ptDelta.x >= 0) ? ptDelta.x : -ptDelta.x;
ptTol.x = sImeG.iParaTol * ncUIEsc[uEsc].iParaFacX +
sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacX;
ptTol.x = (ptTol.x >= 0) ? ptTol.x : -ptTol.x;
if (ptDelta.x > ptTol.x) {
return (FALSE);
}
ptDelta.y = lpptOrg->y - lpptNearCaret->y;
ptDelta.y = (ptDelta.y >= 0) ? ptDelta.y : -ptDelta.y;
ptTol.y = sImeG.iParaTol * ncUIEsc[uEsc].iParaFacY +
sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacY;
ptTol.y = (ptTol.y >= 0) ? ptTol.y : -ptTol.y;
if (ptDelta.y > ptTol.y) {
return (FALSE);
}
// build up the UI rectangle (composition window)
rcUIRect.left = lpptOrg->x;
rcUIRect.top = lpptOrg->y;
rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
if (IntersectRect(&rcInterRect, &rcUIRect, lprcInputRect)) {
return (FALSE);
}
return (TRUE);
}
/**********************************************************************/
/* AdjustCompPosition() */
/* Return Value : */
/* the position of composition window is changed or not */
/**********************************************************************/
BOOL PASCAL AdjustCompPosition( // IME adjust position according to
// composition form
LPINPUTCONTEXT lpIMC,
LPPOINT lpptOrg, // original composition window
// and final position
LPPOINT lpptNew) // new expect position
{
POINT ptNearCaret, ptOldNearCaret, ptCompWnd;
UINT uEsc, uRot;
RECT rcUIRect, rcInputRect, rcInterRect;
POINT ptFont;
// we need to adjust according to font attribute
if (lpIMC->lfFont.A.lfWidth > 0) {
ptFont.x = lpIMC->lfFont.A.lfWidth * 2;
} else if (lpIMC->lfFont.A.lfWidth < 0) {
ptFont.x = -lpIMC->lfFont.A.lfWidth * 2;
} else if (lpIMC->lfFont.A.lfHeight > 0) {
ptFont.x = lpIMC->lfFont.A.lfHeight;
} else if (lpIMC->lfFont.A.lfHeight < 0) {
ptFont.x = -lpIMC->lfFont.A.lfHeight;
} else {
ptFont.x = lpImeL->yCompHi;
}
if (lpIMC->lfFont.A.lfHeight > 0) {
ptFont.y = lpIMC->lfFont.A.lfHeight;
} else if (lpIMC->lfFont.A.lfHeight < 0) {
ptFont.y = -lpIMC->lfFont.A.lfHeight;
} else {
ptFont.y = ptFont.x;
}
// if the input char is too big, we don't need to consider so much
if (ptFont.x > lpImeL->yCompHi * 8) {
ptFont.x = lpImeL->yCompHi * 8;
}
if (ptFont.y > lpImeL->yCompHi * 8) {
ptFont.y = lpImeL->yCompHi * 8;
}
if (ptFont.x < sImeG.xChiCharWi) {
ptFont.x = sImeG.xChiCharWi;
}
if (ptFont.y < sImeG.yChiCharHi) {
ptFont.y = 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);
uRot = (UINT)((lpIMC->lfFont.A.lfOrientation + 450) / 900 % 4);
// decide the input rectangle
rcInputRect.left = lpptNew->x;
rcInputRect.top = lpptNew->y;
// build up an input rectangle from escapemment
rcInputRect.right = rcInputRect.left + ptFont.x * ptInputEsc[uEsc].x;
rcInputRect.bottom = rcInputRect.top + ptFont.y * ptInputEsc[uEsc].y;
// be a normal rectangle, not a negative rectangle
if (rcInputRect.left > rcInputRect.right) {
LONG tmp;
tmp = rcInputRect.left;
rcInputRect.left = rcInputRect.right;
rcInputRect.right = tmp;
}
if (rcInputRect.top > rcInputRect.bottom) {
LONG tmp;
tmp = rcInputRect.top;
rcInputRect.top = rcInputRect.bottom;
rcInputRect.bottom = tmp;
}
GetNearCaretPosition(
&ptFont, uEsc, uRot, lpptNew, &ptNearCaret, NEAR_CARET_FIRST_TIME);
// 1st, use the adjust point
// build up the new suggest UI rectangle (composition window)
rcUIRect.left = ptNearCaret.x;
rcUIRect.top = ptNearCaret.y;
rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
ptCompWnd = ptOldNearCaret = ptNearCaret;
// OK, no intersect between the near caret position and input char
if (IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
} else if (CalcCandPos(
/*lpIMC,*/ &ptCompWnd)) {
// can not fit the candidate window
} else if (FitInLazyOperation(
lpptOrg, &ptNearCaret, &rcInputRect, uEsc)) {
// happy ending!!!, don't chaqge position
return (FALSE);
} else {
*lpptOrg = ptNearCaret;
// happy ending!!
return (TRUE);
}
// unhappy case
GetNearCaretPosition(&ptFont, uEsc, uRot, lpptNew, &ptNearCaret, 0);
// build up the new suggest UI rectangle (composition window)
rcUIRect.left = ptNearCaret.x;
rcUIRect.top = ptNearCaret.y;
rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
ptCompWnd = ptNearCaret;
// OK, no intersect between the adjust position and input char
if (IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
} else if (CalcCandPos(
/*lpIMC,*/ &ptCompWnd)) {
// can not fit the candidate window
} else if (FitInLazyOperation(
lpptOrg, &ptNearCaret, &rcInputRect, uEsc)) {
// happy ending!!!, don't chaqge position
return (FALSE);
} else {
*lpptOrg = ptNearCaret;
// happy ending!!
return (TRUE);
}
// unhappy ending! :-(
*lpptOrg = ptOldNearCaret;
return (TRUE);
}
/**********************************************************************/
/* AdjustCompPosition() */
/* Return Value : */
/* the position of composition window is changed or not */
/**********************************************************************/
/*BOOL PASCAL AdjustCompPosition( // IME adjust position according to
// composition form
LPINPUTCONTEXT lpIMC,
LPPOINT lpptOrg, // original composition window
// and final position
LPPOINT lpptNew) // new expect position
{
POINT ptAdjust, ptDelta;
UINT uEsc;
RECT rcUIRect, rcInputRect, rcInterRect;
POINT ptFont;
ptAdjust.x = lpptNew->x;
ptAdjust.y = lpptNew->y;
// we need to adjust according to font attribute
if (lpIMC->lfFont.A.lfWidth > 0) {
ptFont.x = lpIMC->lfFont.A.lfWidth;
} else if (lpIMC->lfFont.A.lfWidth == 0) {
ptFont.x = lpImeL->yCompHi;
} else {
ptFont.x = -lpIMC->lfFont.A.lfWidth;
}
if (lpIMC->lfFont.A.lfHeight > 0) {
ptFont.y = lpIMC->lfFont.A.lfHeight;
} else if (lpIMC->lfFont.A.lfWidth == 0) {
ptFont.y = lpImeL->yCompHi;
} else {
ptFont.y = -lpIMC->lfFont.A.lfHeight;
}
// if the input char is too big, we don't need to consider so much
if (ptFont.x > lpImeL->yCompHi * 8) {
ptFont.x = lpImeL->yCompHi * 8;
}
if (ptFont.y > lpImeL->yCompHi * 8) {
ptFont.y = lpImeL->yCompHi * 8;
}
if (ptFont.x < sImeG.xChiCharWi) {
ptFont.x = sImeG.xChiCharWi;
}
if (ptFont.y < sImeG.yChiCharHi) {
ptFont.y = 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
ptAdjust.x = ptAdjust.x + sImeG.iPara * ncUIEsc[uEsc].iParaFacX +
sImeG.iPerp * ncUIEsc[uEsc].iPerpFacX;
ptAdjust.y = ptAdjust.y + ptFont.y * ncUIEsc[uEsc].iLogFontFac +
sImeG.iPara * ncUIEsc[uEsc].iParaFacY +
sImeG.iPerp * ncUIEsc[uEsc].iPerpFacY - lpImeL->cyCompBorder;
// Is the current location within tolerance?
ptDelta.x = lpptOrg->x - ptAdjust.x;
ptDelta.y = lpptOrg->y - ptAdjust.y;
ptDelta.x = (ptDelta.x > 0) ? ptDelta.x : -ptDelta.x;
ptDelta.y = (ptDelta.y > 0) ? ptDelta.y : -ptDelta.y;
// decide the input rectangle
rcInputRect.left = lpptNew->x;
rcInputRect.top = lpptNew->y;
// build up an input rectangle from escapemment
rcInputRect.right = rcInputRect.left + ptFont.x * ptInputEsc[uEsc].x;
rcInputRect.bottom = rcInputRect.top + ptFont.y * ptInputEsc[uEsc].y;
// be a normal rectangle, not a negative rectangle
if (rcInputRect.left > rcInputRect.right) {
int tmp;
tmp = rcInputRect.left;
rcInputRect.left = rcInputRect.right;
rcInputRect.right = tmp;
}
if (rcInputRect.top > rcInputRect.bottom) {
int tmp;
tmp = rcInputRect.top;
rcInputRect.top = rcInputRect.bottom;
rcInputRect.bottom = tmp;
}
// build up the UI rectangle (composition window)
rcUIRect.left = lpptOrg->x;
rcUIRect.top = lpptOrg->y;
rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
// will it within lazy operation range (tolerance)
if (ptDelta.x > sImeG.iParaTol * ncUIEsc[uEsc].iParaFacX +
sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacX) {
} else if (ptDelta.y > sImeG.iParaTol * ncUIEsc[uEsc].iParaFacY +
sImeG.iPerpTol * ncUIEsc[uEsc].iPerpFacY) {
} else if (IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
// If there are intersection, we need to fix that
} else {
// happy ending!!!, don't chaqge position
return (FALSE);
}
ptAdjust.x -= lpImeL->cxCompBorder;
ptAdjust.y -= lpImeL->cyCompBorder;
// lazy guy, move!
// 1st, use the adjust point
if (ptAdjust.x < sImeG.rcWorkArea.left) {
ptAdjust.x = sImeG.rcWorkArea.left;
} else if (ptAdjust.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
ptAdjust.x = sImeG.rcWorkArea.right - lpImeL->xCompWi;
}
if (ptAdjust.y < sImeG.rcWorkArea.top) {
ptAdjust.y = sImeG.rcWorkArea.top;
} else if (ptAdjust.y + lpImeL->yCompHi > sImeG.rcWorkArea.bottom) {
ptAdjust.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;
}
// build up the new suggest UI rectangle (composition window)
rcUIRect.left = ptAdjust.x;
rcUIRect.top = ptAdjust.y;
rcUIRect.right = rcUIRect.left + lpImeL->xCompWi;
rcUIRect.bottom = rcUIRect.top + lpImeL->yCompHi;
// OK, no intersect between the adjust position and input char
if (!IntersectRect(&rcInterRect, &rcUIRect, &rcInputRect)) {
// happy ending!!
lpptOrg->x = ptAdjust.x;
lpptOrg->y = ptAdjust.y;
return (TRUE);
}
// unhappy case
ptAdjust.x = lpptNew->x;
ptAdjust.y = lpptNew->y;
ClientToScreen((HWND)lpIMC->hWnd, &ptAdjust);
// IME do another adjustment
ptAdjust.x = ptAdjust.x + ptFont.x * ncUIEsc[uEsc].iParaFacX -
sImeG.iPara * ncUIEsc[uEsc].iParaFacX +
sImeG.iPerp * ncUIEsc[uEsc].iPerpFacX - lpImeL->cxCompBorder;
ptAdjust.y = ptAdjust.y + ptFont.y * ncUIEsc[uEsc].iLogFontFac -
sImeG.iPara * ncUIEsc[uEsc].iParaFacY +
sImeG.iPerp * ncUIEsc[uEsc].iPerpFacY - lpImeL->cyCompBorder;
if (ptAdjust.x < sImeG.rcWorkArea.left) {
ptAdjust.x = sImeG.rcWorkArea.left;
} else if (ptAdjust.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
ptAdjust.x = sImeG.rcWorkArea.right - lpImeL->xCompWi;
}
if (ptAdjust.y < sImeG.rcWorkArea.top) {
ptAdjust.y = sImeG.rcWorkArea.top;
} else if (ptAdjust.y + lpImeL->yCompHi > sImeG.rcWorkArea.bottom) {
ptAdjust.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;
}
// unhappy ending! :-(
lpptOrg->x = ptAdjust.x;
lpptOrg->y = ptAdjust.y;
return (TRUE);
} */
/**********************************************************************/
/* SetCompPosFix() */
/**********************************************************************/
void PASCAL SetCompPosFix( // set the composition window position
HWND hCompWnd,
LPINPUTCONTEXT lpIMC)
{
POINT ptWnd;
BOOL fChange = FALSE;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
// the client coordinate position (0, 0) of composition window
ptWnd.x = 0;
ptWnd.y = 0;
// convert to screen coordinates
ClientToScreen(hCompWnd, &ptWnd);
ptWnd.x -= lpImeL->cxCompBorder;
ptWnd.y -= lpImeL->cyCompBorder;
if (ptWnd.x != lpImeL->ptDefComp.x) {
ptWnd.x = lpImeL->ptDefComp.x;
fChange = TRUE;
}
if (ptWnd.y != lpImeL->ptDefComp.y) {
ptWnd.y = lpImeL->ptDefComp.y;
fChange = TRUE;
}
if (!fChange ) return;
//## 8
SetWindowPos(hCompWnd, NULL,
ptWnd.x, ptWnd.y,
lpImeL->xCompWi, lpImeL->yCompHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCompWnd, GW_OWNER),
IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return;
}
if (!lpUIPrivate->hCandWnd) {
GlobalUnlock(hUIPrivate);
return;
}
// decide the position of candidate window by UI's position
// ##1
SetWindowPos(lpUIPrivate->hCandWnd, NULL,
lpImeL->ptDefCand.x, lpImeL->ptDefCand.y ,
sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* SetCompPosition() */
/**********************************************************************/
void PASCAL SetCompPosition( // set the composition window position
HWND hCompWnd,
LPINPUTCONTEXT lpIMC)
{
POINT ptWnd, ptCaret;
BOOL fChange = FALSE;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HWND hCandWnd;
if (lpImeL->wImeStyle == IME_APRS_FIX){
SetCompPosFix(hCompWnd, lpIMC);
return;
}
// the client coordinate position (0, 0) of composition window
ptWnd.x = 0;
ptWnd.y = 0;
// convert to screen coordinates
ClientToScreen(hCompWnd, &ptWnd);
ptWnd.x -= lpImeL->cxCompBorder;
ptWnd.y -= lpImeL->cyCompBorder;
if (lpIMC->cfCompForm.dwStyle & CFS_FORCE_POSITION) {
POINT ptNew; // new position of UI
ptNew.x = lpIMC->cfCompForm.ptCurrentPos.x;
ptNew.y = lpIMC->cfCompForm.ptCurrentPos.y;
ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
if (ptWnd.x != ptNew.x) {
ptWnd.x = ptNew.x;
fChange = TRUE;
}
if (ptWnd.y != ptNew.y) {
ptWnd.y = ptNew.y;
fChange = TRUE;
}
if (fChange) {
ptWnd.x -= lpImeL->cxCompBorder;
ptWnd.y -= lpImeL->cyCompBorder;
}
} else if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) {
// aplication tell us the position, we need to adjust
POINT ptNew; // new position of UI
ptNew.x = lpIMC->cfCompForm.ptCurrentPos.x;
ptNew.y = lpIMC->cfCompForm.ptCurrentPos.y;
ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
fChange = AdjustCompPosition(lpIMC, &ptWnd, &ptNew);
} else {
POINT ptNew; // new position of UI
/*ptNew.x = lpIMC->ptStatusWndPos.x + sImeG.xStatusWi + UI_MARGIN;
if (ptNew.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
ptNew.x = lpIMC->ptStatusWndPos.x -
lpImeL->xCompWi - lpImeL->cxCompBorder * 2 -
UI_MARGIN;
}
ptNew.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;// - 2 * UI_MARGIN ;*/
ptNew.x = lpImeL->ptZLComp.x;
ptNew.y = lpImeL->ptZLComp.y;
if (ptWnd.x != ptNew.x) {
ptWnd.x = ptNew.x;
fChange = TRUE;
}
if (ptWnd.y != ptNew.y) {
ptWnd.y = ptNew.y;
fChange = TRUE;
}
if (fChange) {
lpIMC->cfCompForm.ptCurrentPos = ptNew;
ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
}
}
/*if (GetCaretPos(&ptCaret)) {
// application don't set position, OK we need to near caret
ClientToScreen(lpIMC->hWnd, &ptCaret);
fChange = AdjustCompPosition(lpIMC, &ptWnd, &ptCaret);
} else {
// no caret information!
if (ptWnd.x != lpImeL->ptDefComp.x) {
ptWnd.x = lpImeL->ptDefComp.y;
fChange = TRUE;
}
if (ptWnd.y != lpImeL->ptDefComp.x) {
ptWnd.y = lpImeL->ptDefComp.y;
fChange = TRUE;
}
if (ptWnd.x != lpImeL->ptDefComp.x) {
ptWnd.x =lpIMC->ptStatusWndPos.x + sImeG.TextLen+8;//lpImeL->ptDefComp.y;
fChange = TRUE;
}
if (ptWnd.y != lpImeL->ptDefComp.x) {
ptWnd.y =lpIMC->ptStatusWndPos.
} y ;//lpImeL->ptDefComp.y;
fChange = TRUE;
} */
if (!(fChange|CandWndChange)) {
return;
}
CandWndChange = 0;
// ##2
if(TypeOfOutMsg & COMP_NEEDS_END){
CloseCand(GetWindow(hCompWnd, GW_OWNER));
EndComp(GetWindow(hCompWnd, GW_OWNER));
//CloseCand(GetWindow(hCandWnd, GW_OWNER));
TypeOfOutMsg = TypeOfOutMsg & ~(COMP_NEEDS_END);
}
SetWindowPos(hCompWnd, NULL,
ptWnd.x, ptWnd.y,
lpImeL->xCompWi,lpImeL->yCompHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCompWnd, GW_OWNER),
IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return;
}
if (!lpUIPrivate->hCandWnd) {
GlobalUnlock(hUIPrivate);
return;
}
// decide the position of candidate window by UI's position
CalcCandPos(&ptWnd);
//##3
SetWindowPos(lpUIPrivate->hCandWnd, NULL,
ptWnd.x, ptWnd.y,
sImeG.xCandWi,sImeG.yCandHi , SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* SetCompWindow() */
/**********************************************************************/
void PASCAL SetCompWindow( // set the position of composition window
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HWND hCompWnd;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
hCompWnd = GetCompWnd(hUIWnd);
if (!hCompWnd) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
SetCompPosition(hCompWnd, lpIMC);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* MoveDefaultCompPosition() */
/**********************************************************************/
void PASCAL MoveDefaultCompPosition( // the default comp position
// need to near the caret
HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HWND hCompWnd;
if (lpImeL->wImeStyle == IME_APRS_FIX ) return ;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
hCompWnd = GetCompWnd(hUIWnd);
if (!hCompWnd) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (lpIMC->cfCompForm.dwStyle & CFS_FORCE_POSITION) {
} else if (!lpIMC->hPrivate) {
} else {
LPPRIVCONTEXT lpImcP;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
} else if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONPOS) {
} else {
lpImcP->fdwImeMsg |= MSG_IMN_COMPOSITIONPOS;
// lpImcP->fdwGcsFlag =lpImcP->fdwGcsFlag &~( GCS_RESULTREAD|GCS_RESULTSTR);
// if(sImeG.InbxProc){
/* sImeG.InbxProc = 0;*///}
// else{
// GenerateMessage(hIMC, lpIMC, lpImcP);//} //CHG4
}
ImmUnlockIMCC(lpIMC->hPrivate);
}
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* ShowComp() */
/**********************************************************************/
void PASCAL ShowComp( // Show the composition window
HWND hUIWnd,
int nShowCompCmd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
// show or hid the UI window
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) {
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
return;
}
if (!lpUIPrivate->hCompWnd) {
// not in show candidate window mode
} else if (lpUIPrivate->nShowCompCmd != nShowCompCmd) {
ShowWindow(lpUIPrivate->hCompWnd, nShowCompCmd);
lpUIPrivate->nShowCompCmd = nShowCompCmd;
} else {
}
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* StartComp() */
/**********************************************************************/
void PASCAL StartComp(
HWND hUIWnd)
{
HIMC hIMC;
HGLOBAL hUIPrivate;
LPINPUTCONTEXT lpIMC;
LPUIPRIV lpUIPrivate;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) { // Oh! Oh!
return;
}
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // Oh! Oh!
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) { // Oh! Oh!
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw composition window
ImmUnlockIMC(hIMC);
return;
}
lpUIPrivate->fdwSetContext |= ISC_SHOWUICOMPOSITIONWINDOW;//zl 95.9.14
if (!lpUIPrivate->hCompWnd) {
lpUIPrivate->hCompWnd = CreateWindowEx(
/* WS_EX_CLIENTEDGE|WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME|WS_EX_TOPMOST,*/
0,
szCompClassName, NULL, WS_POPUP|WS_DISABLED,//|WS_BORDER,
0, 0, lpImeL->xCompWi, lpImeL->yCompHi,
hUIWnd, (HMENU)NULL, hInst, NULL);
if ( lpUIPrivate->hCompWnd != NULL )
{
SetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_OFFSET,
WINDOW_NOT_DRAG);
SetWindowLong(lpUIPrivate->hCompWnd, UI_MOVE_XY, 0L);
}
}
// try to set the position of composition UI window near the caret
SetCompPosition(lpUIPrivate->hCompWnd, lpIMC);
ImmUnlockIMC(hIMC);
ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* EndComp() */
/**********************************************************************/
void PASCAL EndComp(
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // Oh! Oh!
return;
}
// hide the composition window
ShowWindow(lpUIPrivate->hCompWnd, SW_HIDE);
lpUIPrivate->nShowCompCmd = SW_HIDE;
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* DestroyCompWindow() */
/**********************************************************************/
void PASCAL DestroyCompWindow( // destroy composition window
HWND hCompWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCompWnd, GW_OWNER),
IMMGWLP_PRIVATE);
if (!hUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate->nShowCompCmd = SW_HIDE;
lpUIPrivate->hCompWnd = (HWND)NULL;
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* CompSetCursor() */
/**********************************************************************/
void PASCAL CompSetCursor(
HWND hCompWnd,
LPARAM lParam)
{
POINT ptCursor;
RECT rcWnd;
if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
return;
}
GetCursorPos(&ptCursor);
ScreenToClient(hCompWnd, &ptCursor);
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
if (HIWORD(lParam) == WM_RBUTTONDOWN) {
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
return;
} else if (HIWORD(lParam) == WM_LBUTTONDOWN) {
// start dragging
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
} else {
return;
}
SetCapture(hCompWnd);
GetCursorPos(&ptCursor);
SetWindowLong(hCompWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
GetWindowRect(hCompWnd, &rcWnd);
SetWindowLong(hCompWnd, UI_MOVE_OFFSET,
MAKELONG(ptCursor.x - rcWnd.left, ptCursor.y - rcWnd.top));
DrawDragBorder(hCompWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hCompWnd, UI_MOVE_OFFSET));
return;
}
/**********************************************************************/
/* CompButtonUp() */
/**********************************************************************/
BOOL PASCAL CompButtonUp( // finish drag, set comp window to this
// position
HWND hCompWnd)
{
LONG lTmpCursor, lTmpOffset;
POINT pt;
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HWND hFocusWnd;
COMPOSITIONFORM cfCompForm;
if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) {
return (FALSE);
}
lTmpCursor = GetWindowLong(hCompWnd, UI_MOVE_XY);
pt.x = (*(LPPOINTS)&lTmpCursor).x;
pt.y = (*(LPPOINTS)&lTmpCursor).y;
// calculate the org by the offset
lTmpOffset = GetWindowLong(hCompWnd, UI_MOVE_OFFSET);
pt.x -= (*(LPPOINTS)&lTmpOffset).x;
pt.y -= (*(LPPOINTS)&lTmpOffset).y;
DrawDragBorder(hCompWnd, lTmpCursor, lTmpOffset);
SetWindowLong(hCompWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
ReleaseCapture();
hUIWnd = GetWindow(hCompWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (FALSE);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
hFocusWnd = (HWND)lpIMC->hWnd;
ImmUnlockIMC(hIMC);
if (pt.x < sImeG.rcWorkArea.left) {
pt.x = sImeG.rcWorkArea.left;
} else if (pt.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) {
pt.x = sImeG.rcWorkArea.right - lpImeL->xCompWi;
}
if (pt.y < sImeG.rcWorkArea.top) {
pt.y = sImeG.rcWorkArea.top;
} else if (pt.y + lpImeL->yCompHi > sImeG.rcWorkArea.bottom) {
pt.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;
}
ScreenToClient(hFocusWnd, &pt);
cfCompForm.dwStyle = CFS_POINT|CFS_FORCE_POSITION;
cfCompForm.ptCurrentPos.x = pt.x + lpImeL->cxCompBorder;
cfCompForm.ptCurrentPos.y = pt.y + lpImeL->cyCompBorder;
// set composition window to the new poosition
SendMessage(hUIWnd, WM_IME_CONTROL, IMC_SETCOMPOSITIONWINDOW,
(LPARAM)&cfCompForm);
return (TRUE);
}
#define SHENHUI RGB(0x80,0x80,0x80)
#define QIANHUI RGB(0xe0,0xe0,0x80)
/**********************************************************************/
/* CurMovePaint() */
/* Function: While the string is longer than the Comp Window.... */
/* keep the cursor inside the Comp Window */
/* Called: By UpdateCompWindow2 */
/**********************************************************************/
void WINAPI CurMovePaint(
HDC hDC,
LPSTR srBuffer, // the source sting that to be showed...
int StrLen) // the length of that...
{
int i,xx,yy;
//SetBkColor(hDC, QIANHUI);
if(!StrLen)
return;
for (i=0; i<StrLen; i++)
InputBuffer[i] = srBuffer[i];
xx= 0;
if (InputBuffer[0]>0xa0){
for (i =0; i<StrLen; i++){
if(InputBuffer[i]<0xa0) break;
}
yy = i;
for (i=yy; i>0; i=i-2) {
//xx =sImeG.xChiCharWi*i/2;
xx=GetText32(hDC,&InputBuffer[0],i);
if ( xx <= lpImeL->rcCompText.right-4)
break;
}
i=0;
cur_start_ps=0;
cur_start_count=0;
}else {
for (i =now_cs; i>0; i--){
yy=GetText32(hDC, &InputBuffer[i-1], 1);
if ( (xx+yy) >= (lpImeL->rcCompText.right-4))
break;
else
xx+=yy;
}
cur_start_count=(WORD)i;
cur_start_ps=(WORD)GetText32(hDC, &InputBuffer[0], i);
// true_len = StrLen-cur_start_count ;
}
for(i=StrLen-cur_start_count; i>0; i--){
yy=GetText32(hDC,&InputBuffer[cur_start_count],i);
if (yy <= lpImeL->rcCompText.right-4)
break;
}
{
LOGFONT lfFont;
HGDIOBJ hOldFont;
int Top = 2;
if (sImeG.yChiCharHi > 0x10)
Top = 0;
hOldFont = GetCurrentObject(hDC, OBJ_FONT);
GetObject(hOldFont, sizeof(lfFont), &lfFont);
lfFont.lfWeight = FW_DONTCARE;
SelectObject(hDC, CreateFontIndirect(&lfFont));
ExtTextOut(hDC,
lpImeL->rcCompText.left, lpImeL->rcCompText.top + Top,
ETO_OPAQUE, &lpImeL->rcCompText,
&InputBuffer[cur_start_count],
i, NULL);
DeleteObject(SelectObject(hDC, hOldFont));
}
// TextOut(hDC,0,0,&InputBuffer[cur_start_count],
// (sizeof InputBuffer)-cur_start_count);
now_cs_dot = xx;
cur_hibit=0,cur_flag=0;
return;
}
/**********************************************************************/
/* UpdateCompWindow2() */
/**********************************************************************/
void PASCAL UpdateCompWindow2(
HWND hUIWnd,
HDC hDC)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPCOMPOSITIONSTRING lpCompStr;
LPGUIDELINE lpGuideLine;
BOOL fShowString;
LOGFONT lfFont;
HGDIOBJ hOldFont;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
hOldFont = GetCurrentObject(hDC, OBJ_FONT);
GetObject(hOldFont, sizeof(lfFont), &lfFont);
lfFont.lfWeight = FW_DONTCARE;
SelectObject(hDC, CreateFontIndirect(&lfFont));
SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
fShowString = (BOOL)0;
if (lpImeL->wImeStyle == IME_APRS_FIX){
RECT rcSunken;
DrawConvexRect(hDC,
0,
0,
lpImeL->xCompWi-1,
lpImeL->yCompHi-1);
rcSunken.left =0;
rcSunken.top =0;
rcSunken.right =lpImeL->xCompWi-1;
rcSunken.bottom = lpImeL->yCompHi-1;
// DrawEdge(hDC, &rcSunken, EDGE_RAISED,/*EDGE_SUNKEN,*/ BF_RECT);
}else
DrawConvexRect(hDC,
0,
0,
lpImeL->xCompWi-1,
lpImeL->yCompHi-1);
/* DrawConvexRect(hDC,
lpImeL->rcCompText.left-4,
lpImeL->rcCompText.top-4,
lpImeL->rcCompText.right+4,
lpImeL->rcCompText.bottom+4); */
/* DrawConcaveRect(hDC,
lpImeL->rcCompText.left-1,
lpImeL->rcCompText.top-1,
lpImeL->rcCompText.right+1,
lpImeL->rcCompText.bottom+1); */
if (!lpGuideLine) {
} else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
} else if (!lpGuideLine->dwStrLen) {
if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
fShowString |= IME_STR_ERROR;
}
} else {
// if there is information string, we will show the information
// string
if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
// red text for error
SetTextColor(hDC, RGB(0xFF, 0, 0));
// light gray background for error
SetBkColor(hDC, QIANHUI);
}
ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
ETO_OPAQUE, &lpImeL->rcCompText,
(LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset,
(UINT)lpGuideLine->dwStrLen, NULL);
fShowString |= IME_STR_SHOWED;
}
if (fShowString & IME_STR_SHOWED) {
// already show it, don't need to show
} else if (lpCompStr) {
// ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
// ETO_OPAQUE, &lpImeL->rcCompText,
// (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset,
// (UINT)lpCompStr->dwCompStrLen, NULL);
CurMovePaint(hDC,
(LPSTR)lpCompStr + lpCompStr->dwCompStrOffset,
(UINT)lpCompStr->dwCompStrLen);
if (fShowString & IME_STR_ERROR) {
// red text for error
SetTextColor(hDC, RGB(0xFF, 0, 0));
// light gray background for error
SetBkColor(hDC, QIANHUI);
ExtTextOut(hDC, lpImeL->rcCompText.left +
lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2,
lpImeL->rcCompText.top,
ETO_CLIPPED, &lpImeL->rcCompText,
(LPSTR)lpCompStr + lpCompStr->dwCompStrOffset +
lpCompStr->dwCursorPos,
(UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL);
} else if (lpCompStr->dwCursorPos < lpCompStr->dwCompStrLen) {
// light gray background for cursor start
SetBkColor(hDC, QIANHUI);
ExtTextOut(hDC, lpImeL->rcCompText.left +
lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2,
lpImeL->rcCompText.top,
ETO_CLIPPED, &lpImeL->rcCompText,
(LPSTR)lpCompStr + lpCompStr->dwCompStrOffset +
lpCompStr->dwCursorPos,
(UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL);
} else {
}
} else {
ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
ETO_OPAQUE, &lpImeL->rcCompText,
(LPSTR)NULL, 0, NULL);
}
DeleteObject(SelectObject(hDC, hOldFont));
ImmUnlockIMCC(lpIMC->hGuideLine);
ImmUnlockIMCC(lpIMC->hCompStr);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* UpdateCompWindow() */
/**********************************************************************/
void PASCAL UpdateCompWindow(
HWND hUIWnd)
{
HWND hCompWnd;
HDC hDC;
hCompWnd = GetCompWnd(hUIWnd);
if (!hCompWnd) return ; //Modify 95/7.1
hDC = GetDC(hCompWnd);
UpdateCompWindow2(hUIWnd, hDC);
ReleaseDC(hCompWnd, hDC);
}
/**********************************************************************/
/* UpdateCompCur() */
/**********************************************************************/
void PASCAL UpdateCompCur(
HWND hCompWnd)
{
HDC hDC;
int yy,i;
HGDIOBJ hOldFont;
LOGFONT lfFont;
cur_hibit=1;
if (!hCompWnd) return ; //Modify 95/7.1
hDC = GetDC(hCompWnd);
hOldFont = GetCurrentObject(hDC, OBJ_FONT);
GetObject(hOldFont, sizeof(lfFont), &lfFont);
lfFont.lfWeight = FW_DONTCARE;
SelectObject(hDC, CreateFontIndirect(&lfFont));
SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));
for (i =43-cur_start_count; i>0; i--){
yy=GetText32(hDC, &InputBuffer[cur_start_count], i);
if ( yy < lpImeL->rcCompText.right-4)
break;
}
ExtTextOut(hDC,
lpImeL->rcCompText.left, lpImeL->rcCompText.top,
ETO_OPAQUE, &lpImeL->rcCompText,
&InputBuffer[cur_start_count],
i,
NULL);
DeleteObject(SelectObject(hDC, hOldFont));
ReleaseDC(hCompWnd, hDC);
cur_hibit=0,cur_flag=0;
return ;
}
/**********************************************************************/
/* PaintCompWindow() */
/**********************************************************************/
void PASCAL PaintCompWindow( // get WM_PAINT message
HWND hCompWnd)
{
HDC hDC;
PAINTSTRUCT ps;
RECT pt;
if(CompWndChange){
CompWndChange = 0;
SetCompWindow(GetWindow(hCompWnd,GW_OWNER));
};
cur_hibit=1;
hDC = BeginPaint(hCompWnd, &ps);
UpdateCompWindow2(GetWindow(hCompWnd, GW_OWNER), hDC);
EndPaint(hCompWnd, &ps);
cur_hibit=0,cur_flag=0;
return;
}
/**********************************************************************/
/* CompWndProc() */
/**********************************************************************/
LRESULT CALLBACK CompWndProc( // composition window proc
HWND hCompWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
HDC hDC;
switch (uMsg) {
case WM_CREATE:
hDC=GetDC(hCompWnd);
hMemoryDC=CreateCompatibleDC(hDC);
cur_h=LoadBitmap(hInst,CUR_HB);
ReleaseDC(hCompWnd,hDC);
SetTimer(hCompWnd ,1,400,(TIMERPROC)NULL);
ShowCandTimerCount=0;
break;
case WM_TIMER:
hInputWnd = hCompWnd;
TimerCounter++;
ShowCandTimerCount++;
if (TimerCounter==3){
TimerCounter=0;
}
if (!kb_flag) return(0);
if (cur_hibit||(cap_mode&&(!cur_flag))) return(0);
DrawInputCur();
break;
case WM_DESTROY:
KillTimer(hCompWnd,1);
DeleteObject(cur_h);
DeleteObject(hMemoryDC);
DestroyCompWindow(hCompWnd);
break;
case WM_SETCURSOR:
CompSetCursor(hCompWnd, lParam);
break;
case WM_MOUSEMOVE:
if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
if(lpImeL->wImeStyle == IME_APRS_AUTO){
POINT ptCursor;
DrawDragBorder(hCompWnd,
GetWindowLong(hCompWnd, UI_MOVE_XY),
GetWindowLong(hCompWnd, UI_MOVE_OFFSET));
GetCursorPos(&ptCursor);
SetWindowLong(hCompWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
DrawDragBorder(hCompWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hCompWnd, UI_MOVE_OFFSET));
}else MessageBeep(0);
} else {
return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
}
break;
case WM_LBUTTONUP:
if (!CompButtonUp(hCompWnd)) {
return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
}
break;
case WM_SHOWWINDOW:
if (wParam) cur_hibit = 0;
else cur_hibit = 1;
break;
case WM_PAINT:
if (wParam == 0xa )
UpdateCompCur(hCompWnd);
else
PaintCompWindow(hCompWnd);
break;
case WM_MOUSEACTIVATE:
return (MA_NOACTIVATE);
default:
return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
}
return (0L);
}
/**********************************************************************/
/* 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);
}
/**********************************************************************/
/* CalcCandPos */
/**********************************************************************/
void PASCAL CalcCandPos2(
LPPOINT lpptWnd) // the composition window position
{
POINT ptNew;
ptNew.x = lpptWnd->x + UI_MARGIN * 2;
if (ptNew.x + sImeG.xCandWi > sImeG.rcWorkArea.right) {
// exceed screen width
ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN * 2;
}
ptNew.y = lpptWnd->y;// + lpImeL->cyCompBorder - sImeG.cyCandBorder;
if (ptNew.y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) {
// exceed screen high
ptNew.y = sImeG.rcWorkArea.bottom - sImeG.yCandHi;
}
lpptWnd->x = ptNew.x;
lpptWnd->y = ptNew.y;
return;
}
/**********************************************************************/
/* CalcCandPos */
/**********************************************************************/
BOOL PASCAL CalcCandPos(
LPPOINT lpptWnd) // the composition window position
{
POINT ptNew;
ptNew.x = lpptWnd->x + lpImeL->xCompWi + UI_MARGIN * 2;
if (ptNew.x + sImeG.xCandWi > sImeG.rcWorkArea.right) {
// exceed screen width
ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN * 2;
}
ptNew.y = lpptWnd->y;// + lpImeL->cyCompBorder - sImeG.cyCandBorder;
if (ptNew.y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) {
// exceed screen high
ptNew.y = sImeG.rcWorkArea.bottom - sImeG.yCandHi;
}
lpptWnd->x = ptNew.x;
lpptWnd->y = ptNew.y;
return 0;
}
/**********************************************************************/
/* AdjustCandBoundry */
/**********************************************************************/
void PASCAL AdjustCandBoundry(
LPPOINT lpptCandWnd) // the position
{
if (lpptCandWnd->x < sImeG.rcWorkArea.left) {
lpptCandWnd->x = sImeG.rcWorkArea.left;
} else if (lpptCandWnd->x + sImeG.xCandWi > sImeG.rcWorkArea.right) {
lpptCandWnd->x = sImeG.rcWorkArea.right - sImeG.xCandWi;
}
if (lpptCandWnd->y < sImeG.rcWorkArea.top) {
lpptCandWnd->y = sImeG.rcWorkArea.top;
} else if (lpptCandWnd->y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) {
lpptCandWnd->y = sImeG.rcWorkArea.bottom - sImeG.yCandHi;
}
return;
}
/**********************************************************************/
/* GetCandPos() */
/**********************************************************************/
LRESULT PASCAL GetCandPos(
HWND hUIWnd,
LPCANDIDATEFORM lpCandForm)
{
HWND hCandWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
POINT ptNew;
//DebugShow("GetCand...%x",hUIWnd);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (1L);
}
if (!(hCandWnd = GetCandWnd(hUIWnd))) {
return (1L);
}
if (lpCandForm->dwStyle & CFS_FORCE_POSITION) {
ptNew.x = (int)lpCandForm->ptCurrentPos.x;
ptNew.y = (int)lpCandForm->ptCurrentPos.y;
} else if (lpCandForm->dwStyle & CFS_CANDIDATEPOS) {
ptNew.x = (int)lpCandForm->ptCurrentPos.x;
ptNew.y = (int)lpCandForm->ptCurrentPos.y;
} else if (lpCandForm->dwStyle & CFS_EXCLUDE) {
ptNew.x = (int)lpCandForm->ptCurrentPos.x;
ptNew.y = (int)lpCandForm->ptCurrentPos.y;
}
ImmUnlockIMC(hIMC);
return (0L);
}
/**********************************************************************/
/* SetCandPosition() */
/**********************************************************************/
LRESULT PASCAL SetCandPosition(
HWND hUIWnd,
LPCANDIDATEFORM lpCandForm)
{
HWND hCandWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
POINT ptNew;
// DebugShow("SetCand...%x",hUIWnd);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (1L);
}
if (!(hCandWnd = GetCandWnd(hUIWnd))) {
return (1L);
}
if (lpCandForm->dwStyle & CFS_FORCE_POSITION) {
ptNew.x = (int)lpCandForm->ptCurrentPos.x;
ptNew.y = (int)lpCandForm->ptCurrentPos.y;
ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
//##4
SetWindowPos(hCandWnd, NULL,
ptNew.x, ptNew.y,
sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
} else if (lpCandForm->dwStyle & CFS_CANDIDATEPOS) {
ptNew.x = (int)lpCandForm->ptCurrentPos.x;
ptNew.y = (int)lpCandForm->ptCurrentPos.y;
ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
AdjustCandBoundry(&ptNew);
// ##5
SetWindowPos(hCandWnd, NULL,
ptNew.x, ptNew.y,
sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
} else if (lpCandForm->dwStyle & CFS_EXCLUDE) {
ptNew.x = (int)lpCandForm->ptCurrentPos.x;
ptNew.y = (int)lpCandForm->ptCurrentPos.y;
ClientToScreen((HWND)lpIMC->hWnd, &ptNew);
AdjustCandBoundry(&ptNew);
// ##6
SetWindowPos(hCandWnd, NULL,
ptNew.x, ptNew.y,
sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
} else if (lpIMC->cfCandForm[0].dwStyle == CFS_DEFAULT) {
HWND hCompWnd;
if (hCompWnd = GetCompWnd(hUIWnd)) {
ptNew.x = 0;
ptNew.y = 0;
ClientToScreen(hCompWnd, &ptNew);
CalcCandPos(&ptNew);
} else {
AdjustCandBoundry(&ptNew);
}
SetWindowPos(hCandWnd, NULL,
ptNew.x, ptNew.y,
sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER);
}
ImmUnlockIMC(hIMC);
return (0L);
}
/**********************************************************************/
/* ShowCand() */
/**********************************************************************/
void PASCAL ShowCand( // Show the candidate window
HWND hUIWnd,
int nShowCandCmd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
// if (ShowCandTimerCount<5) {ShowCandTimerCount = 0; return 0;}
// ShowCandTimerCount = 0 ;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
if (!lpUIPrivate->hCandWnd) {
// not in show candidate window mode
} else if (lpUIPrivate->nShowCandCmd != nShowCandCmd) {
ShowWindow(lpUIPrivate->hCandWnd, nShowCandCmd);
lpUIPrivate->nShowCandCmd = nShowCandCmd;
} else {
}
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* OpenCand */
/**********************************************************************/
void PASCAL OpenCand(
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
POINT ptWnd;
int value;
// DebugShow("In Open Cand",0);
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
lpUIPrivate->fdwSetContext |= ISC_SHOWUICANDIDATEWINDOW;
ptWnd.x = 0;
ptWnd.y = 0;
// DebugShow("OpenCand ..->hCompWnd=%X",lpUIPrivate);
value = ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd);
// DebugShow("OpenCand ..value", value);
if (!value){ // if there no Comp wndows
GetCaretPos(&ptWnd);
ClientToScreen(GetFocus(),&ptWnd);
CalcCandPos2(&ptWnd);
} else {
ptWnd.x -= lpImeL->cxCompBorder;
// ptWnd.y -= lpImeL->cyCompBorder;
CalcCandPos(&ptWnd);
}
if (lpImeL->wImeStyle == IME_APRS_FIX) {
ptWnd.x = lpImeL->ptDefCand.x;
ptWnd.y = lpImeL->ptDefCand.y;
}
// ##7
if (lpUIPrivate->hCandWnd) {
SetWindowPos(lpUIPrivate->hCandWnd, NULL,
ptWnd.x, ptWnd.y,
sImeG.xCandWi, sImeG.yCandHi,
SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER);
} else {
lpUIPrivate->hCandWnd = CreateWindowEx(
/* WS_EX_TOPMOST*/ /*|*/ /* WS_EX_CLIENTEDGE|WS_EX_WINDOWEDGE/*|WS_EX_DLGMODALFRAME*/
0,
szCandClassName, NULL, WS_POPUP|WS_DISABLED, //|WS_BORDER,
ptWnd.x,
ptWnd.y,
sImeG.xCandWi, sImeG.yCandHi,
hUIWnd, (HMENU)NULL, hInst, NULL);
if ( lpUIPrivate->hCandWnd )
{
SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_OFFSET,
WINDOW_NOT_DRAG);
SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_XY, 0L);
}
}
ShowCand(hUIWnd, SW_SHOWNOACTIVATE);
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* CloseCand */
/**********************************************************************/
void PASCAL CloseCand(
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
ShowWindow(lpUIPrivate->hCandWnd, SW_HIDE);
lpUIPrivate->nShowCandCmd = SW_HIDE;
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* DestroyCandWindow */
/**********************************************************************/
void PASCAL DestroyCandWindow(
HWND hCandWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER),
IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw candidate window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw candidate window
return;
}
lpUIPrivate->nShowCandCmd = SW_HIDE;
lpUIPrivate->hCandWnd = (HWND)NULL;
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* MouseSelectCandStr() */
/**********************************************************************/
void PASCAL MouseSelectCandStr(
HWND hCandWnd,
LPPOINT lpCursor)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
DWORD dwValue, value = 0 ;
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (!lpIMC->hCandInfo) {
ImmUnlockIMC(hIMC);
return;
}
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
ImmUnlockIMC(hIMC);
return;
}
if (PtInRect(&sImeG.rcHome, *lpCursor))
value = VK_HOME*0x100;
if (PtInRect(&sImeG.rcEnd, *lpCursor))
value = VK_END*0x100;
if (PtInRect(&sImeG.rcPageUp, *lpCursor))
value = VK_PRIOR*0x100;
if (PtInRect(&sImeG.rcPageDown, *lpCursor))
value = VK_NEXT*0x100;
if (PtInRect(&sImeG.rcCandText, *lpCursor)){
if (lpImeL->wImeStyle == IME_APRS_AUTO )
value = 0x8030 + 1 + (lpCursor->y - sImeG.rcCandText.top) / sImeG.yChiCharHi;
else
value = 0x8030+1+ (lpCursor->x - sImeG.rcCandText.left)/
(sImeG.xChiCharWi*unit_length/2+ sImeG.Ajust);
}
if(value) {
LPPRIVCONTEXT lpImcP;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
lpImcP->fdwImeMsg =lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
ImmUnlockIMCC(lpIMC->hPrivate);
NotifyIME(hIMC, NI_SELECTCANDIDATESTR, 0, value);
}
ImmUnlockIMCC(lpIMC->hCandInfo);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* CandSetCursor() */
/**********************************************************************/
void PASCAL CandSetCursor(
HWND hCandWnd,
LPARAM lParam)
{
POINT ptCursor;
RECT rcWnd;
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
return;
}
if (HIWORD(lParam) == WM_LBUTTONDOWN) {
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
GetCursorPos(&ptCursor);
ScreenToClient(hCandWnd, &ptCursor);
if (PtInRect(&sImeG.rcCandText, ptCursor)||
PtInRect(&sImeG.rcHome, ptCursor)||
PtInRect(&sImeG.rcEnd, ptCursor)||
PtInRect(&sImeG.rcPageUp, ptCursor)||
PtInRect(&sImeG.rcPageDown, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
MouseSelectCandStr(hCandWnd, &ptCursor);
return;
} else {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
}
} else {
GetCursorPos(&ptCursor);
ScreenToClient(hCandWnd, &ptCursor);
if (PtInRect(&sImeG.rcCandText, ptCursor)||
PtInRect(&sImeG.rcHome, ptCursor)||
PtInRect(&sImeG.rcEnd, ptCursor)||
PtInRect(&sImeG.rcPageUp, ptCursor)||
PtInRect(&sImeG.rcPageDown, ptCursor)) {
SetCursor(LoadCursor(hInst, szHandCursor));
} else {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
}
return;
}
SetCapture(hCandWnd);
GetCursorPos(&ptCursor);
SetWindowLong(hCandWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
GetWindowRect(hCandWnd, &rcWnd);
SetWindowLong(hCandWnd, UI_MOVE_OFFSET,
MAKELONG(ptCursor.x - rcWnd.left, ptCursor.y - rcWnd.top));
DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
return;
}
/**********************************************************************/
/* CandButtonUp() */
/**********************************************************************/
BOOL PASCAL CandButtonUp(
HWND hCandWnd)
{
LONG lTmpCursor, lTmpOffset;
POINT pt;
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HWND hFocusWnd;
CANDIDATEFORM cfCandForm;
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) {
return (FALSE);
}
lTmpCursor = GetWindowLong(hCandWnd, UI_MOVE_XY);
pt.x = (*(LPPOINTS)&lTmpCursor).x;
pt.y = (*(LPPOINTS)&lTmpCursor).y;
// calculate the org by the offset
lTmpOffset = GetWindowLong(hCandWnd, UI_MOVE_OFFSET);
pt.x -= (*(LPPOINTS)&lTmpOffset).x;
pt.y -= (*(LPPOINTS)&lTmpOffset).y;
DrawDragBorder(hCandWnd, lTmpCursor, lTmpOffset);
SetWindowLong(hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
ReleaseCapture();
hUIWnd = GetWindow(hCandWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (FALSE);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
hFocusWnd = lpIMC->hWnd;
ImmUnlockIMC(hIMC);
AdjustCandBoundry(&pt);
ScreenToClient(hFocusWnd, &pt);
cfCandForm.dwStyle = CFS_CANDIDATEPOS;
cfCandForm.ptCurrentPos.x = pt.x;
cfCandForm.ptCurrentPos.y = pt.y;
SendMessage(hUIWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS,
(LPARAM)&cfCandForm);
return (TRUE);
}
/**********************************************************************/
/* PaintOP() */
/**********************************************************************/
void PASCAL PaintOP(
HDC hDC,
HWND hWnd)
{
RECT rcSunken;
int x1,y1,x2,y2;
rcSunken = sImeG.rcCandText;
x1=rcSunken.left-2;
y1=rcSunken.top-1;//2;
x2=rcSunken.right+7;
y2=rcSunken.bottom+5;
rcSunken.left =x1;
rcSunken.top =y1;
rcSunken.right =x2;
rcSunken.bottom = y2;
// ShowBitmap(hDC,x2-50,y2,49,20, szUpDown);
if(lpImeL->wImeStyle == IME_APRS_AUTO ){
DrawConvexRect(hDC,0,0,sImeG.xCandWi-1, sImeG.yCandHi-1);
// DrawConcaveRect(hDC ,x1,y1,x2,y2);
if(bx_inpt_on){
ShowBitmap2(hDC,
sImeG.xCandWi/2-25,
sImeG.rcHome.top,
50,
15,
sImeG.SnumbBmp);
}else {
ShowBitmap2(hDC,
sImeG.xCandWi/2-25,
sImeG.rcHome.top,
50,
15,
sImeG.NumbBmp);
}
ShowBitmap2(hDC,
sImeG.rcHome.left,
sImeG.rcHome.top,
14,
14,
sImeG.HomeBmp);
ShowBitmap2(hDC,
sImeG.rcEnd.left,
sImeG.rcEnd.top,
14,
14,
sImeG.EndBmp);
ShowBitmap2(hDC,
sImeG.rcPageUp.left,
sImeG.rcPageUp.top,
14,
14,
sImeG.PageUpBmp);
ShowBitmap2(hDC,
sImeG.rcPageDown.left,
sImeG.rcPageDown.top,
14,
14,
sImeG.PageDownBmp);
}else{
ShowBitmap2(hDC,
sImeG.rcHome.left,
sImeG.rcHome.top,
14,
14,
sImeG.Home2Bmp);
ShowBitmap2(hDC,
sImeG.rcEnd.left,
sImeG.rcEnd.top,
14,
14,
sImeG.End2Bmp);
ShowBitmap2(hDC,
sImeG.rcPageUp.left,
sImeG.rcPageUp.top,
14,
14,
sImeG.PageUp2Bmp);
ShowBitmap2(hDC,
sImeG.rcPageDown.left,
sImeG.rcPageDown.top,
14,
14,
sImeG.PgDown2Bmp);
}
return ;
}
int keep =9;
/**********************************************************************/
/* UpdateCandWindow() */
/**********************************************************************/
void PASCAL UpdateCandWindow2(
HWND hCandWnd,
HDC hDC)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
LPPRIVCONTEXT lpImcP;
DWORD dwStart, dwEnd;
TCHAR szStrBuf[30* sizeof(WCHAR) / sizeof(TCHAR)];
int i , LenOfAll;
HGDIOBJ hOldFont;
LOGFONT lfFont;
hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (!lpIMC->hCandInfo) {
ImmUnlockIMC(hIMC);
return ;
}
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
ImmUnlockIMC(hIMC);
return ;
}
if (!lpIMC->hPrivate) {
ImmUnlockIMCC(lpIMC->hCandInfo);
ImmUnlockIMC(hIMC);
return;
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
ImmUnlockIMCC(lpIMC->hCandInfo);
ImmUnlockIMC(hIMC);
return;
}
lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
lpCandInfo->dwOffset[0]);
if(lpImeL->wImeStyle == IME_APRS_FIX)
lpCandList->dwPageSize = now.fmt_group;
else
lpCandList->dwPageSize = CANDPERPAGE ;
if (!lpCandList->dwPageSize)
lpCandList->dwPageSize = keep;
keep = lpCandList->dwPageSize;
dwStart = lpCandList->dwSelection /
lpCandList->dwPageSize * lpCandList->dwPageSize;
dwEnd = dwStart + lpCandList->dwPageSize;
if (dwEnd > lpCandList->dwCount) {
dwEnd = lpCandList->dwCount;
}
hOldFont = GetCurrentObject(hDC, OBJ_FONT);
GetObject(hOldFont, sizeof(lfFont), &lfFont);
lfFont.lfWeight = FW_DONTCARE;
SelectObject(hDC, CreateFontIndirect(&lfFont));
if(lpImeL->wImeStyle != IME_APRS_FIX){
PaintOP(hDC,hCandWnd);
if (lpImcP->iImeState == CST_INIT) {
// phrase prediction
SetTextColor(hDC, RGB(0x00, 0x80, 0x00));
} else if (lpImcP->iImeState != CST_CHOOSE) {
// quick key
SetTextColor(hDC, RGB(0x80, 0x00, 0x80));
} else {
}
SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0));
sImeG.rcCandText.bottom+=3;
ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top,
ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL);
sImeG.rcCandText.bottom-=3;
szStrBuf[0] = '1';
szStrBuf[1] = ':';
for (i = 0; dwStart < dwEnd; dwStart++, i++) {
int iLen;
szStrBuf[0] = szDigit[i + CAND_START];
iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
lpCandList->dwOffset[dwStart]));
// according to init.c, 7 DBCS char
if (iLen > 6 * sizeof(WCHAR) / sizeof(TCHAR)) {
iLen = 6 * sizeof(WCHAR) / sizeof(TCHAR);
CopyMemory(&szStrBuf[2],
((LPBYTE)lpCandList+lpCandList->dwOffset[dwStart]),
iLen * sizeof(TCHAR) - sizeof(TCHAR) * 2);
// maybe not good for UNICODE
szStrBuf[iLen] = '.';
szStrBuf[iLen + 1] = '.';
} else {
CopyMemory(&szStrBuf[2],
((LPBYTE)lpCandList+lpCandList->dwOffset[dwStart]),
iLen);
}
ExtTextOut(hDC, sImeG.rcCandText.left,
sImeG.rcCandText.top + i * sImeG.yChiCharHi,
(UINT)0, NULL,
szStrBuf,
iLen + 2, NULL);
}
} else {
PaintOP(hDC,hCandWnd);
SetTextColor(hDC, RGB(0xa0, 0x00, 0x80));
SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0));
ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top,
ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL);
szStrBuf[0] = '1';
szStrBuf[1] = ':';
LenOfAll = 0;
for (i = 0; dwStart < dwEnd; dwStart++, i++) {
int iLen;
szStrBuf[LenOfAll++] = szDigit[i + CAND_START];
szStrBuf[LenOfAll++] = '.' ;
iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList +
lpCandList->dwOffset[dwStart]));
CopyMemory(&szStrBuf[LenOfAll],
((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]),
iLen);
LenOfAll += iLen;
szStrBuf[LenOfAll] = '.';
szStrBuf[LenOfAll] = '.';
}
DrawConvexRect(hDC,0,0,sImeG.xCandWi-1,sImeG.yCandHi-1); //zl
PaintOP(hDC,hCandWnd);
{
int TopOfText = 2;
if (sImeG.yChiCharHi >0x10)
TopOfText = 0;
ExtTextOut(hDC, sImeG.rcCandText.left,
sImeG.rcCandText.top + TopOfText,
(UINT)0, NULL,
szStrBuf,
LenOfAll, NULL);
}
}
DeleteObject(SelectObject(hDC, hOldFont));
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMCC(lpIMC->hCandInfo);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* PaintCandWindow() */
/**********************************************************************/
void PASCAL PaintCandWindow( // handle WM_PAINT message
HWND hCandWnd)
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hCandWnd, &ps);
UpdateCandWindow2(hCandWnd, hDC);
EndPaint(hCandWnd, &ps);
return;
}
/**********************************************************************/
/* CandWndProc() */
/**********************************************************************/
LRESULT CALLBACK CandWndProc(
HWND hCandWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_CREATE:
sImeG.HomeBmp = LoadBitmap(hInst, szHome); //zl
sImeG.EndBmp = LoadBitmap(hInst, szEnd);
sImeG.PageUpBmp = LoadBitmap(hInst, szPageUp);
sImeG.PageDownBmp = LoadBitmap(hInst, szPageDown);
sImeG.NumbBmp = LoadBitmap(hInst, szNumb);
sImeG.SnumbBmp = LoadBitmap(hInst, szSnumb);
sImeG.Home2Bmp = LoadBitmap(hInst, szHome2);
sImeG.End2Bmp = LoadBitmap(hInst, szEnd2);
sImeG.PageUp2Bmp = LoadBitmap(hInst, szPageUp2);
sImeG.PgDown2Bmp = LoadBitmap(hInst, szPgDown2);
break;
case WM_DESTROY:
DeleteObject(sImeG.HomeBmp);
DeleteObject(sImeG.EndBmp);
DeleteObject(sImeG.PageUpBmp);
DeleteObject(sImeG.PageDownBmp);
DeleteObject(sImeG.NumbBmp );
DeleteObject(sImeG.SnumbBmp );
DeleteObject(sImeG.Home2Bmp);
DeleteObject(sImeG.End2Bmp);
DeleteObject(sImeG.PageUp2Bmp);
DeleteObject(sImeG.PgDown2Bmp);
DestroyCandWindow(hCandWnd);
break;
case WM_SETCURSOR:
CandSetCursor(hCandWnd, lParam);
break;
case WM_MOUSEMOVE:
if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
POINT ptCursor;
if (lpImeL->wImeStyle == IME_APRS_AUTO){
DrawDragBorder(hCandWnd,
GetWindowLong(hCandWnd, UI_MOVE_XY),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
GetCursorPos(&ptCursor);
SetWindowLong(hCandWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hCandWnd, UI_MOVE_OFFSET));
}else MessageBeep(0);
} else {
return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
}
break;
case WM_LBUTTONUP:
if (!CandButtonUp(hCandWnd)) {
return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
}
break;
case WM_PAINT:
InvalidateRect(hCandWnd,0,1);
PaintCandWindow(hCandWnd);
break;
case WM_MOUSEACTIVATE:
return (MA_NOACTIVATE);
/* case WM_IME_NOTIFY:
if (wParam != IMN_SETCANDIDATEPOS) {
} else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) {
} else if (lParam & 0x0001) {
return SetCandPosition(hCandWnd);
} else {
}
break;*/
default:
return DefWindowProc(hCandWnd, uMsg, wParam, lParam);
}
return (0L);
}
/**********************************************************************/
/* ImeInquire() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeInquire( // initialized data structure of IME
LPIMEINFO lpImeInfo, // IME specific data report to IMM
LPTSTR lpszWndCls, // the class name of UI
DWORD dwSystemInfoFlags)
{
if (!lpImeInfo) {
return (FALSE);
}
lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT);
lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST|IME_PROP_IGNORE_UPKEYS|IME_PROP_CANDLIST_START_FROM_1;
lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE|
/* IME_CMODE_CHARCODE|*/IME_CMODE_SOFTKBD|IME_CMODE_NOCONVERSION/*|
IME_CMODE_EUDC*/;
lpImeInfo->fdwSentenceCaps = TRUE;
// IME will have different distance base multiple of 900 escapement
lpImeInfo->fdwUICaps = UI_CAP_ROT90|UI_CAP_SOFTKBD;
// composition string is the reading string for simple IME
lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR|SCS_CAP_MAKEREAD;
// IME want to decide conversion mode on ImeSelect
lpImeInfo->fdwSelectCaps = (DWORD)0;
lstrcpy(lpszWndCls, (LPSTR)szUIClassName);
if ( lpImeL )
{
if ( dwSystemInfoFlags & IME_SYSINFO_WINLOGON )
{
// the client app is running in logon mode.
lpImeL->fWinLogon = TRUE;
}
else
lpImeL->fWinLogon = FALSE;
}
return (TRUE);
}
BOOL FAR PASCAL ConfigDlgProc( // dialog procedure of configuration
HWND hDlg,
UINT uMessage,
WORD wParam,
LONG lParam)
{
return (TRUE);
}
/**********************************************************************/
/* ImeConfigure() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeConfigure( // configurate the IME setting
HKL hKL, // hKL of this IME
HWND hAppWnd, // the owner window
DWORD dwMode,
LPVOID lpData) // mode of dialog
{
switch (dwMode) {
case IME_CONFIG_GENERAL:
DoPropertySheet(hAppWnd,NULL);
ReInitIme(hAppWnd,lpImeL->wImeStyle); //#@1
break;
default:
return (FALSE);
break;
}
return (TRUE);
}
/**********************************************************************/
/* ImeConversionList() */
/**********************************************************************/
DWORD WINAPI ImeConversionList(
HIMC hIMC,
LPCTSTR lpszSrc,
LPCANDIDATELIST lpCandList,
DWORD uBufLen,
UINT uFlag)
{
return (UINT)0;
}
/**********************************************************************/
/* ImeDestroy() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeDestroy( // this dll is unloaded
UINT uReserved)
{
if (uReserved) {
return (FALSE);
}
// free the IME table or data base
// FreeTable();
return (TRUE);
}
/**********************************************************************/
/* SetPrivateSetting() */
/**********************************************************************/
void PASCAL SetPrivateFileSetting(
LPBYTE szBuf,
int cbBuf,
DWORD dwOffset,
LPCTSTR szSettingFile) // file for IME private related settings
{
TCHAR szSettingPath[MAX_PATH];
UINT uLen;
HANDLE hSettingFile;
DWORD dwWriteByte;
return;
}
/**********************************************************************/
/* Input2Sequence */
/* Return Value: */
/* LOWORD - Internal Code, HIWORD - sequence code */
/**********************************************************************/
LRESULT PASCAL Input2Sequence(
DWORD uVirtKey,
LPBYTE lpSeqCode)
{
return 0;
}
/**********************************************************************/
/* ImeEscape() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
#define IME_INPUTKEYTOSEQUENCE 0x22
LRESULT WINAPI ImeEscape( // escape function of IMEs
HIMC hIMC,
UINT uSubFunc,
LPVOID lpData)
{
LRESULT lRet;
switch (uSubFunc) {
case IME_ESC_QUERY_SUPPORT:
if ( lpData == NULL )
return FALSE;
switch (*(LPUINT)lpData) {
case IME_ESC_QUERY_SUPPORT:
case IME_ESC_SEQUENCE_TO_INTERNAL:
case IME_ESC_GET_EUDC_DICTIONARY:
case IME_ESC_SET_EUDC_DICTIONARY:
case IME_INPUTKEYTOSEQUENCE:
// will not supported in next version
// and not support 32 bit applications case IME_ESC_MAX_KEY:
case IME_ESC_IME_NAME:
case IME_ESC_GETHELPFILENAME:
return (TRUE);
default:
return (FALSE);
}
break;
case IME_ESC_SEQUENCE_TO_INTERNAL:
lRet = 0;
return (lRet);
case IME_ESC_GET_EUDC_DICTIONARY:
return (FALSE);
case IME_ESC_SET_EUDC_DICTIONARY:
return (FALSE);
case IME_INPUTKEYTOSEQUENCE:
return 0;
case IME_ESC_MAX_KEY:
return (lpImeL->nMaxKey);
case IME_ESC_IME_NAME:
{
TCHAR szIMEName[MAX_PATH];
if ( lpData == NULL )
return FALSE;
LoadString(hInst, IDS_IMENAME, szIMEName, sizeof(szIMEName) );
lstrcpy(lpData, szIMEName);
return (TRUE);
}
case IME_ESC_GETHELPFILENAME:
if ( lpData == NULL )
return FALSE;
lstrcpy(lpData, TEXT("winabc.hlp") );
return TRUE;
default:
return (FALSE);
}
return (lRet);
}
/**********************************************************************/
/* InitCompStr() */
/**********************************************************************/
void PASCAL InitCompStr( // init setting for composing string
LPCOMPOSITIONSTRING lpCompStr)
{
if (!lpCompStr) {
return;
}
lpCompStr->dwCompReadAttrLen = 0;
lpCompStr->dwCompReadClauseLen = 0;
lpCompStr->dwCompReadStrLen = 0;
lpCompStr->dwCompAttrLen = 0;
lpCompStr->dwCompClauseLen = 0;
lpCompStr->dwCompStrLen = 0;
lpCompStr->dwCursorPos = 0;
lpCompStr->dwDeltaStart = 0;
lpCompStr->dwResultReadClauseLen = 0;
lpCompStr->dwResultReadStrLen = 0;
lpCompStr->dwResultClauseLen = 0;
lpCompStr->dwResultStrLen = 0;
return;
}
/**********************************************************************/
/* ClearCompStr() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL PASCAL ClearCompStr(
LPINPUTCONTEXT lpIMC)
{
HIMCC hMem;
LPCOMPOSITIONSTRING lpCompStr;
DWORD dwSize =
// header length
sizeof(COMPOSITIONSTRING) +
// composition reading attribute plus NULL terminator
lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE) +
// composition reading clause
sizeof(DWORD) + sizeof(DWORD) +
// composition reading string plus NULL terminator
lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
// result reading clause
sizeof(DWORD) + sizeof(DWORD) +
// result reading string plus NULL terminateor
lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) +
// result clause
sizeof(DWORD) + sizeof(DWORD) +
// result string plus NULL terminateor
MAXSTRLEN * sizeof(WORD) + sizeof(WORD);
if (!lpIMC) {
return (FALSE);
}
if (!lpIMC->hCompStr) {
// it maybe free by other IME, init it
lpIMC->hCompStr = ImmCreateIMCC(dwSize);
} else if (hMem = ImmReSizeIMCC(lpIMC->hCompStr, dwSize)) {
lpIMC->hCompStr = hMem;
} else {
ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = ImmCreateIMCC(dwSize);
return (FALSE);
}
if (!lpIMC->hCompStr) {
return (FALSE);
}
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
if (!lpCompStr) {
ImmDestroyIMCC(lpIMC->hCompStr);
lpIMC->hCompStr = ImmCreateIMCC(dwSize);
return (FALSE);
}
lpCompStr->dwSize = dwSize;
// 1. composition (reading) string - simple IME
// 2. result reading string
// 3. result string
lpCompStr->dwCompReadAttrLen = 0;
lpCompStr->dwCompReadAttrOffset = sizeof(COMPOSITIONSTRING);
lpCompStr->dwCompReadClauseLen = 0;
lpCompStr->dwCompReadClauseOffset = lpCompStr->dwCompReadAttrOffset +
lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE);
lpCompStr->dwCompReadStrLen = 0;
lpCompStr->dwCompReadStrOffset = lpCompStr->dwCompReadClauseOffset +
sizeof(DWORD) + sizeof(DWORD);
// composition string is the same with composition reading string
// for simple IMEs
lpCompStr->dwCompAttrLen = 0;
lpCompStr->dwCompAttrOffset = lpCompStr->dwCompReadAttrOffset;
lpCompStr->dwCompClauseLen = 0;
lpCompStr->dwCompClauseOffset = lpCompStr->dwCompReadClauseOffset;
lpCompStr->dwCompStrLen = 0;
lpCompStr->dwCompStrOffset = lpCompStr->dwCompReadStrOffset;
lpCompStr->dwCursorPos = 0;
lpCompStr->dwDeltaStart = 0;
lpCompStr->dwResultReadClauseLen = 0;
lpCompStr->dwResultReadClauseOffset = lpCompStr->dwCompStrOffset +
lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
lpCompStr->dwResultReadStrLen = 0;
lpCompStr->dwResultReadStrOffset = lpCompStr->dwResultReadClauseOffset +
sizeof(DWORD) + sizeof(DWORD);
lpCompStr->dwResultClauseLen = 0;
lpCompStr->dwResultClauseOffset = lpCompStr->dwResultReadStrOffset +
lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD);
lpCompStr->dwResultStrOffset = 0;
lpCompStr->dwResultStrOffset = lpCompStr->dwResultClauseOffset +
sizeof(DWORD) + sizeof(DWORD);
GlobalUnlock((HGLOBAL)lpIMC->hCompStr);
return (TRUE);
}
/**********************************************************************/
/* ClearCand() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL PASCAL ClearCand(
LPINPUTCONTEXT lpIMC)
{
HIMCC hMem;
LPCANDIDATEINFO lpCandInfo;
LPCANDIDATELIST lpCandList;
DWORD dwSize =
// header length
sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST) +
// candidate string pointers
sizeof(DWORD) * (MAXCAND) +
// string plus NULL terminator
(sizeof(WORD) + sizeof(WORD)) * MAXCAND;
if (!lpIMC) {
return (FALSE);
}
if (!lpIMC->hCandInfo) {
// it maybe free by other IME, init it
lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
} else if (hMem = ImmReSizeIMCC(lpIMC->hCandInfo, dwSize)) {
lpIMC->hCandInfo = hMem;
} else {
ImmDestroyIMCC(lpIMC->hCandInfo);
lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
return (FALSE);
}
if (!lpIMC->hCandInfo) {
return (FALSE);
}
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
if (!lpCandInfo) {
ImmDestroyIMCC(lpIMC->hCandInfo);
lpIMC->hCandInfo = ImmCreateIMCC(dwSize);
return (FALSE);
}
// ordering of strings are
// buffer size
lpCandInfo->dwSize = dwSize;
lpCandInfo->dwCount = 0;
lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO);
lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo +
lpCandInfo->dwOffset[0]);
// whole candidate info size - header
lpCandList->dwSize = lpCandInfo->dwSize - sizeof(CANDIDATEINFO);
lpCandList->dwStyle = IME_CAND_READ;
lpCandList->dwCount = 0;
lpCandList->dwSelection = 0;
lpCandList->dwPageSize = CANDPERPAGE;
lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) +
sizeof(DWORD) * (MAXCAND - 1);
ImmUnlockIMCC(lpIMC->hCandInfo);
return (TRUE);
}
/**********************************************************************/
/* ClearGuideLine() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL PASCAL ClearGuideLine(
LPINPUTCONTEXT lpIMC)
{
HIMCC hMem;
LPGUIDELINE lpGuideLine;
DWORD dwSize = sizeof(GUIDELINE) + sImeG.cbStatusErr;
if (!lpIMC->hGuideLine) {
// it maybe free by IME
lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
} else if (hMem = ImmReSizeIMCC(lpIMC->hGuideLine, dwSize)) {
lpIMC->hGuideLine = hMem;
} else {
ImmDestroyIMCC(lpIMC->hGuideLine);
lpIMC->hGuideLine = ImmCreateIMCC(dwSize);
}
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
if (!lpGuideLine) {
return (FALSE);
}
lpGuideLine->dwSize = dwSize;
lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
lpGuideLine->dwIndex = GL_ID_UNKNOWN;
lpGuideLine->dwStrLen = 0;
lpGuideLine->dwStrOffset = sizeof(GUIDELINE);
CopyMemory((LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset,
sImeG.szStatusErr, sImeG.cbStatusErr);
ImmUnlockIMCC(lpIMC->hGuideLine);
return (TRUE);
}
/**********************************************************************/
/* InitContext() */
/**********************************************************************/
void PASCAL InitContext(
LPINPUTCONTEXT lpIMC,
LPPRIVCONTEXT lpImcP)
{
//if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
//} else if (!lpIMC->hWnd) {
//} else if (lpImcP->fdwInit & INIT_STATUSWNDPOS) {
//} else {
if (lpIMC->fdwInit & INIT_STATUSWNDPOS) {
} else if (!lpIMC->hWnd) {
} else {
POINT ptWnd;
ptWnd.x = 0;
ptWnd.y = 0;
ClientToScreen(lpIMC->hWnd, &ptWnd);
if (ptWnd.x < sImeG.rcWorkArea.left) {
lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
} else if (ptWnd.x + sImeG.xStatusWi > sImeG.rcWorkArea.right) {
lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
sImeG.xStatusWi;
} else {
lpIMC->ptStatusWndPos.x = ptWnd.x;
}
// DebugShow2 ("ptst.y,", lpIMC->ptStatusWndPos.y, "bottom" , sImeG.rcWorkArea.bottom);
if(!lpIMC->ptStatusWndPos.y) // == sImeG.rcWorkArea.bottom)
lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
sImeG.yStatusHi;// - 2 * UI_MARGIN;// - 20;
else
lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
sImeG.yStatusHi;// - 2 * UI_MARGIN;
//lpImcP->fdwInit |= INIT_STATUSWNDPOS;
lpIMC->fdwInit |= INIT_STATUSWNDPOS;
}
if (!(lpIMC->fdwInit & INIT_COMPFORM)) {
lpIMC->cfCompForm.dwStyle = CFS_DEFAULT;
}
if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) {
} else if (!lpIMC->hWnd) {
} else if (lpImcP->fdwInit & INIT_COMPFORM) {
} else {
if (0/*lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI*/) {
// lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x +
// lpImeL->rcStatusText.right + lpImeL->cxCompBorder * 2 +
// UI_MARGIN;
// if (lpIMC->cfCompForm.ptCurrentPos.x + (lpImeL->nRevMaxKey *
// sImeG.xChiCharWi) > sImeG.rcWorkArea.right) {
// lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x -
// lpImeL->nRevMaxKey * sImeG.xChiCharWi -
// lpImeL->cxCompBorder * 3;
// }
} else {
lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x +
sImeG.xStatusWi + UI_MARGIN;
if (lpIMC->cfCompForm.ptCurrentPos.x + lpImeL->xCompWi >
sImeG.rcWorkArea.right) {
lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x -
lpImeL->xCompWi - lpImeL->cxCompBorder * 2 -
UI_MARGIN;
}
}
lpIMC->cfCompForm.ptCurrentPos.y = sImeG.rcWorkArea.bottom -
lpImeL->yCompHi;// - 2 * UI_MARGIN;
ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);
lpImcP->fdwInit |= INIT_COMPFORM;
}
return;
}
/**********************************************************************/
/* Select() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL PASCAL Select(
HIMC hIMC,
LPINPUTCONTEXT lpIMC,
BOOL fSelect)
{
LPPRIVCONTEXT lpImcP;
sImeG.First = 0;
if (fSelect) { // init "every" fields of hPrivate, please!!!
if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT) {
} else {
}
if (!ClearCompStr(lpIMC)) {
return (FALSE);
}
if (!ClearCand(lpIMC)) {
return (FALSE);
}
ClearGuideLine(lpIMC);
}
if (!lpIMC->hPrivate) {
return (FALSE);
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
return (FALSE);
}
if (fSelect) { // init "every" fields of hPrivate, please!!!
static bFirstTimeCallHere = TRUE;
InterlockedIncrement( &lLock );
if ( bFirstTimeCallHere == TRUE ) {
// we move the following code here from the DLL_ATTACH_PROCESS to
// avoid application hang.
// With static variable bFirstTimeCallHere, we ensure the following
// code will be called only when the ImeSelect( ) is first called.
GetCurrentUserEMBPath( );
data_init( );
bFirstTimeCallHere = FALSE;
}
InterlockedDecrement( &lLock );
lpImcP->iImeState = CST_INIT; // init the IME state machine
lpImcP->fdwImeMsg = (DWORD)0; // no UI windpws show
lpImcP->dwCompChar = (DWORD)0;
lpImcP->fdwGcsFlag = (DWORD)0;
lpImcP->hSoftKbdWnd = NULL; // soft keyboard window
lpImcP->nShowSoftKbdCmd = 0;
lpIMC->fOpen = TRUE;
if (!(lpIMC->fdwInit & INIT_CONVERSION)) {
if(GetKeyState(VK_CAPITAL)&1)
lpIMC->fdwConversion = IME_CMODE_NOCONVERSION;
else
lpIMC->fdwConversion = IME_CMODE_NATIVE;
kb_mode = CIN_STD;
DispMode(hIMC);
lpIMC->fdwConversion |= IME_CMODE_SYMBOL;
lpIMC->fdwInit |= INIT_CONVERSION;
}else {
if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD)
{
sImeG.First = 1;
}
}
if (lpIMC->fdwInit & INIT_SENTENCE) {
} else if (lpImeL->fModeConfig & MODE_CONFIG_PREDICT) {
lpIMC->fdwSentence = IME_SMODE_PHRASEPREDICT;
lpIMC->fdwInit |= INIT_SENTENCE;
} else {
}
if (!(lpIMC->fdwInit & INIT_LOGFONT)) {
HDC hDC;
HGDIOBJ hSysFont;
hDC = GetDC(NULL);
hSysFont = GetStockObject(SYSTEM_FONT);
GetObject(hSysFont, sizeof(LOGFONT), &lpIMC->lfFont.A);
ReleaseDC(NULL, hDC);
lpIMC->fdwInit |= INIT_LOGFONT;
}
// Get Current User's specific phrase table path
InitContext(lpIMC,lpImcP);
}
else
{
if(hCrtDlg) {
SendMessage(hCrtDlg, WM_CLOSE, (WPARAM)NULL, (LPARAM)NULL);
hCrtDlg = NULL;
}
}
ImmUnlockIMCC(lpIMC->hPrivate);
return (TRUE);
}
/**********************************************************************/
/* ImeSelect() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeSelect(
HIMC hIMC,
BOOL fSelect)
{
LPINPUTCONTEXT lpIMC;
BOOL fRet;
// to load/free IME table
if (fSelect) {
InitCvtPara();
if (!lpImeL->cRefCount++) {
/* zst LoadTable() */ ;
}
} else {
if (!lpImeL->cRefCount) {
/* zst FreeTable() */ ;
}
}
if (!hIMC) {
return (FALSE);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
fRet = Select(hIMC, lpIMC, fSelect);
ImmUnlockIMC(hIMC);
return (fRet);
}
/**********************************************************************/
/* ImeSetActiveContext() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeSetActiveContext(
HIMC hIMC,
BOOL fOn)
{
if (!fOn) {
} else if (!hIMC) {
} else {
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP; //zl
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
if(lpIMC->hPrivate){
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); //zl
if (!lpImcP){ //zl
return (FALSE); //zl
} //zl
}else return(FALSE);
InitContext(lpIMC,lpImcP); //zl
// DispModeEx(0);
ImmUnlockIMCC(lpIMC->hPrivate); //zl
ImmUnlockIMC(hIMC);
}
return (TRUE);
}
/**********************************************************************/
/* ReInitIme() */
/**********************************************************************/
void PASCAL ReInitIme(
HWND hWnd ,
WORD WhatStyle)
{
HWND hStatusWnd,MainWnd;
POINT ptPos;
RECT rcStatusWnd,TempRect;
int cxBorder, cyBorder;
if (sImeG.unchanged)
return ;
// border + raising edge + sunken edge
cxBorder = GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXEDGE) * 2;
cyBorder = GetSystemMetrics(SM_CYBORDER) +
GetSystemMetrics(SM_CYEDGE) * 2;
//if (!WhatStyle){
if (WhatStyle==IME_APRS_AUTO){
lpImeL->rcCompText.left = 4;
lpImeL->rcCompText.top =4;
lpImeL->rcCompText.right = sImeG.TextLen+5;
lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;
lpImeL->cxCompBorder = cxBorder;
lpImeL->cyCompBorder = cyBorder;
// set the width & height for composition window
lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
//lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
lpImeL->yCompHi = sImeG.yStatusHi;//lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
} else {
// text position relative to the composition window
lpImeL->rcCompText.left = 4;
lpImeL->rcCompText.top = 4;
lpImeL->rcCompText.right = sImeG.TextLen+5;
lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;/*cyBorder;*/
lpImeL->cxCompBorder = cxBorder;
lpImeL->cyCompBorder = cyBorder;
// set the width & height for composition window
lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
lpImeL->yCompHi = sImeG.yStatusHi; //zl
}
// border + raising edge + sunken edge
cxBorder = GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXEDGE) /* 2*/;
cyBorder = GetSystemMetrics(SM_CYBORDER) +
GetSystemMetrics(SM_CYEDGE) /* 2*/;
//if (!WhatStyle){
if (WhatStyle==IME_APRS_AUTO){
sImeG.rcCandText.left = 4;
sImeG.rcCandText.top = 4;
sImeG.rcCandText.right = sImeG.xChiCharWi * 7;
sImeG.rcCandText.bottom = sImeG.yChiCharHi * CANDPERPAGE+1;//zl
sImeG.cxCandBorder = cxBorder+3;
sImeG.cyCandBorder = cyBorder+3;
sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2+3;//zl
sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder *2+12;
sImeG.rcHome.left = 4 ;
sImeG.rcHome.top = sImeG.rcCandText.bottom+6 ;
sImeG.rcHome.right = sImeG.rcHome.left + 14 ;
sImeG.rcHome.bottom = sImeG.rcHome.top +14 ;
sImeG.rcEnd.left = sImeG.rcHome.right ;
sImeG.rcEnd.top = sImeG.rcHome.top ;
sImeG.rcEnd.right = sImeG.rcEnd.left + 14 ;
sImeG.rcEnd.bottom = sImeG.rcHome.bottom ;
sImeG.rcPageDown.top = sImeG.rcHome.top ;
sImeG.rcPageDown.right = sImeG.xCandWi-4;
sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
sImeG.rcPageDown.bottom = sImeG.rcHome.bottom ;
sImeG.rcPageUp.top = sImeG.rcHome.top ;
sImeG.rcPageUp.right = sImeG.rcPageDown.left ;
sImeG.rcPageUp.left = sImeG.rcPageUp.right -14 ;
sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
}else{
sImeG.cxCandBorder = cxBorder;
sImeG.cyCandBorder = cyBorder;
sImeG.xCandWi = lpImeL->xCompWi + sImeG.xStatusWi - cxBorder+1;
sImeG.yCandHi = sImeG.yStatusHi; //sImeG.yChiCharHi+3 + sImeG.cyCandBorder *2;
sImeG.rcHome.left = 3; //2;
sImeG.rcHome.top = 4;//7;
sImeG.rcHome.right = sImeG.rcHome.left + 10; //14;
sImeG.rcHome.bottom = sImeG.rcHome.top +8; //14 ;
sImeG.rcEnd.left =sImeG.rcHome.left; //sImeG.rcHome.right ;
sImeG.rcEnd.top = sImeG.rcHome.top+9; //14 ;
sImeG.rcEnd.right =sImeG.rcHome.right; //sImeG.rcEnd.left + 14 ;
sImeG.rcEnd.bottom = sImeG.rcHome.bottom+10; //14 ;
sImeG.rcPageDown.top = sImeG.rcEnd.top;//sImeG.rcHome.top ;
sImeG.rcPageDown.right = sImeG.xCandWi-1;//2;
sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
sImeG.rcPageDown.bottom = sImeG.rcEnd.bottom ;//sImeG.rcHome.bottom ;
sImeG.rcPageUp.top = sImeG.rcHome.top -1; //zl
sImeG.rcPageUp.right = sImeG.rcPageDown.right+1;//zl;sImeG.rcPageDown.left ;
sImeG.rcPageUp.left = sImeG.rcPageDown.left;//sImeG.rcPageUp.right -14 ;
sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
sImeG.rcCandText.left = sImeG.rcEnd.right+2;//1;//4;//sImeG.rcEnd.right;
sImeG.rcCandText.top = 4;
sImeG.rcCandText.right = sImeG.rcPageUp.left-4;//2;//sImeG.rcPageUp.left-2;
sImeG.rcCandText.bottom = sImeG.yChiCharHi+7;//6;//3;
}
/* ptPos.x = 0 ;
ptPos.y = 0 ;
ClientToScreen(hWnd, &ptPos);
lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2;
lpImeL->ptDefComp.y = ptPos.y - cyBorder;
lpImeL->ptDefCand.x = ptPos.x - cxBorder;
lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2;
if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10)
{lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;}
if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi; //sImeG.yCandHi+2;
*/
if (hWnd){
ptPos.x = 0 ;
ptPos.y = 0 ;
ClientToScreen(hWnd, &ptPos);
CountDefaultComp(ptPos.x,ptPos.y,sImeG.rcWorkArea);
lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2+4;//zl
lpImeL->ptDefComp.y = ptPos.y - cyBorder+3;//2;//3; //zl
lpImeL->ptDefCand.x = ptPos.x - cxBorder+3; //zl
lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2+2;//zl
if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10){
lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;
}
if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi-4; //sImeG.yCandHi+2;
}else{
ptPos.x = lpImeL->Ox ;
ptPos.y = lpImeL->Oy ;
lpImeL->ptDefComp.x = sImeG.xStatusWi - cxBorder*2;
lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
lpImeL->ptDefCand.x = lpImeL->ptDefComp.x + lpImeL->xCompWi;
lpImeL->ptDefCand.y = lpImeL->ptDefComp.y ;
/*
if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10)
{lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;}
if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
lpImeL->ptDefCand.y = ptPos.y + sImeG.yCandHi+2;
*/
}
fmt_transfer();
CandWndChange = 1;
CompWndChange = 1;
return ;
}
void PASCAL ReInitIme2(
HWND hWnd ,
WORD WhatStyle)
{
HWND hStatusWnd,MainWnd;
POINT ptPos;
RECT rcStatusWnd,TempRect;
int cxBorder, cyBorder;
if (sImeG.unchanged)
return ;
// border + raising edge + sunken edge
cxBorder = GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXEDGE) * 2;
cyBorder = GetSystemMetrics(SM_CYBORDER) +
GetSystemMetrics(SM_CYEDGE) * 2;
if (!WhatStyle){
lpImeL->rcCompText.left = 4;
lpImeL->rcCompText.top =4;
lpImeL->rcCompText.right = sImeG.TextLen+5;
lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;
lpImeL->cxCompBorder = cxBorder;
lpImeL->cyCompBorder = cyBorder;
// set the width & height for composition window
lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
//lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
lpImeL->yCompHi = sImeG.yStatusHi;//lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl
} else {
// text position relative to the composition window
lpImeL->rcCompText.left = 4;
lpImeL->rcCompText.top = 4;
lpImeL->rcCompText.right = sImeG.TextLen+5;
lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;/*cyBorder;*/
lpImeL->cxCompBorder = cxBorder;
lpImeL->cyCompBorder = cyBorder;
// set the width & height for composition window
lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
lpImeL->yCompHi = sImeG.yStatusHi; //zl
}
// border + raising edge + sunken edge
cxBorder = GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXEDGE) /* 2*/;
cyBorder = GetSystemMetrics(SM_CYBORDER) +
GetSystemMetrics(SM_CYEDGE) /* 2*/;
if (!WhatStyle){
sImeG.rcCandText.left = 4;
sImeG.rcCandText.top = 4;
sImeG.rcCandText.right = sImeG.xChiCharWi * 7;
sImeG.rcCandText.bottom = sImeG.yChiCharHi * CANDPERPAGE+1;//zl
sImeG.cxCandBorder = cxBorder+3;
sImeG.cyCandBorder = cyBorder+3;
sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2+3;//zl
sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder *2+12;
sImeG.rcHome.left = 4 ;
sImeG.rcHome.top = sImeG.rcCandText.bottom+6 ;
sImeG.rcHome.right = sImeG.rcHome.left + 14 ;
sImeG.rcHome.bottom = sImeG.rcHome.top +14 ;
sImeG.rcEnd.left = sImeG.rcHome.right ;
sImeG.rcEnd.top = sImeG.rcHome.top ;
sImeG.rcEnd.right = sImeG.rcEnd.left + 14 ;
sImeG.rcEnd.bottom = sImeG.rcHome.bottom ;
sImeG.rcPageDown.top = sImeG.rcHome.top ;
sImeG.rcPageDown.right = sImeG.xCandWi-4;
sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
sImeG.rcPageDown.bottom = sImeG.rcHome.bottom ;
sImeG.rcPageUp.top = sImeG.rcHome.top ;
sImeG.rcPageUp.right = sImeG.rcPageDown.left ;
sImeG.rcPageUp.left = sImeG.rcPageUp.right -14 ;
sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
}else{
sImeG.cxCandBorder = cxBorder;
sImeG.cyCandBorder = cyBorder;
sImeG.xCandWi = lpImeL->xCompWi + sImeG.xStatusWi - cxBorder+1;
sImeG.yCandHi = sImeG.yStatusHi; //sImeG.yChiCharHi+3 + sImeG.cyCandBorder *2;
sImeG.rcHome.left = 3; //2;
sImeG.rcHome.top = 4;//7;
sImeG.rcHome.right = sImeG.rcHome.left + 10; //14;
sImeG.rcHome.bottom = sImeG.rcHome.top +8; //14 ;
sImeG.rcEnd.left =sImeG.rcHome.left; //sImeG.rcHome.right ;
sImeG.rcEnd.top = sImeG.rcHome.top+9; //14 ;
sImeG.rcEnd.right =sImeG.rcHome.right; //sImeG.rcEnd.left + 14 ;
sImeG.rcEnd.bottom = sImeG.rcHome.bottom+10; //14 ;
sImeG.rcPageDown.top = sImeG.rcEnd.top;//sImeG.rcHome.top ;
sImeG.rcPageDown.right = sImeG.xCandWi-1;//2;
sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ;
sImeG.rcPageDown.bottom = sImeG.rcEnd.bottom ;//sImeG.rcHome.bottom ;
sImeG.rcPageUp.top = sImeG.rcHome.top -1; //zl
sImeG.rcPageUp.right = sImeG.rcPageDown.right+1;//zl;sImeG.rcPageDown.left ;
sImeG.rcPageUp.left = sImeG.rcPageDown.left;//sImeG.rcPageUp.right -14 ;
sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ;
sImeG.rcCandText.left = sImeG.rcEnd.right+2;//1;//4;//sImeG.rcEnd.right;
sImeG.rcCandText.top = 4;
sImeG.rcCandText.right = sImeG.rcPageUp.left-4;//2;//sImeG.rcPageUp.left-2;
sImeG.rcCandText.bottom = sImeG.yChiCharHi+7;//6;//3;
}
if (hWnd){
ptPos.x = 0 ;
ptPos.y = 0 ;
ClientToScreen(hWnd, &ptPos);
lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2+4;//zl
lpImeL->ptDefComp.y = ptPos.y - cyBorder+3;//2;//3; //zl
lpImeL->ptDefCand.x = ptPos.x - cxBorder+3; //zl
lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2+2;//zl
if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10){
lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi;
lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;
}
if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5))
lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi-4; //sImeG.yCandHi+2;
}else{
ptPos.x = lpImeL->Ox ;
ptPos.y = lpImeL->Oy ;
lpImeL->ptDefComp.x = sImeG.xStatusWi - cxBorder*2;
lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
lpImeL->ptDefCand.x = lpImeL->ptDefComp.x + lpImeL->xCompWi;
lpImeL->ptDefCand.y = lpImeL->ptDefComp.y ;
}
return ;
}
/**********************************************************************/
/* InitUserSetting() */
/**********************************************************************/
int InitUserSetting(void)
{
HKEY hKey,hFirstKey;
DWORD dwSize, dx;
int lRet;
RegCreateKey(HKEY_CURRENT_USER, szRegNearCaret, &hFirstKey);
RegCreateKey(hFirstKey, szAIABC, &hKey);
RegCloseKey(hFirstKey);
//1 KeyType
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey, szKeyType, NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey,szKeyType , 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
sImeG.KbType =(BYTE)dx ;
}
// 2 ImeStyle
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey,szImeStyle , NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey,szImeStyle, 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
lpImeL->wImeStyle = (WORD)dx ;
}
// 3 AutoCp
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey, szCpAuto, NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey,szCpAuto, 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
sImeG.auto_mode =(BYTE)dx ;
}
// 4 BxFlag
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey, szBxFlag , NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey, szBxFlag , 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
sImeG.cbx_flag =(BYTE)dx ;
}
// 5 TuneFlag
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey, szTuneFlag , NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey, szTuneFlag , 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
sImeG.tune_flag=(BYTE)dx ;
}
// 6 AutoCvt
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey, szAutoCvt , NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey, szAutoCvt, 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
sImeG.auto_cvt_flag=(BYTE)dx ;
}
// 7 SdaHelp
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKey, szSdaHelp , NULL, NULL,
(LPBYTE)&dx, &dwSize);
if (lRet != ERROR_SUCCESS) {
dx = 0;
RegSetValueEx(hKey, szSdaHelp, 0, REG_DWORD,
(LPBYTE)&dx, sizeof(int));
}else {
sImeG.SdOpenFlag=(BYTE)dx ;
}
RegCloseKey(hKey);
//ReInitIme2(NULL, lpImeL->wImeStyle);
return 0;
}
/**********************************************************************/
/* ChangeUserSetting() */
/**********************************************************************/
ChangeUserSetting()
{
HKEY hKey,hFirstKey;
DWORD dwSize, dx;
int lRet;
RegCreateKey(HKEY_CURRENT_USER, szRegNearCaret, &hFirstKey);
RegCreateKey(hFirstKey, szAIABC, &hKey);
RegCloseKey(hFirstKey);
RegSetValueEx(hKey, szKeyType, 0, REG_DWORD,
(LPBYTE)&sImeG.KbType, sizeof(int));
RegSetValueEx(hKey, szImeStyle, 0, REG_DWORD,
(LPBYTE)&lpImeL->wImeStyle, sizeof(int));
RegSetValueEx(hKey, szCpAuto, 0, REG_DWORD,
(LPBYTE)&sImeG.auto_mode, sizeof(int));
RegSetValueEx(hKey, szBxFlag, 0, REG_DWORD,
(LPBYTE)&sImeG.cbx_flag, sizeof(int));
RegSetValueEx(hKey, szTuneFlag, 0, REG_DWORD,
(LPBYTE)&sImeG.tune_flag, sizeof(int));
RegSetValueEx(hKey, szAutoCvt, 0, REG_DWORD,
(LPBYTE)&sImeG.auto_cvt_flag, sizeof(int));
RegSetValueEx(hKey, szSdaHelp, 0, REG_DWORD,
(LPBYTE)&sImeG.SdOpenFlag, sizeof(int));
RegCloseKey(hKey);
return 0;
}
/**********************************************************************/
/* InitImeGlobalData() */
/**********************************************************************/
void PASCAL InitImeGlobalData(
HINSTANCE hInstance)
{
int cxBorder, cyBorder;
HDC hDC;
BYTE szChiChar[4];
SIZE lTextSize;
HGLOBAL hResData;
int i;
DWORD dwSize;
HKEY hKeyIMESetting;
LONG lRet;
BYTE NumChar[]="1.2.3.4.5.6.7.8.9.";
BYTE CNumChar[]="<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD>ϲ<EFBFBD>һ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
SIZE hSize;
sImeG.WhitePen = GetStockObject(WHITE_PEN);
sImeG.BlackPen = GetStockObject(BLACK_PEN);
sImeG.GrayPen = CreatePen(PS_SOLID, 1, 0x00808080);
sImeG.LightGrayPen = CreatePen(PS_SOLID, 1, 0x00c0c0c0);
hInst = hInstance;
// get the UI class name
LoadString(hInst, IDS_IMEUICLASS, szUIClassName, sizeof(szUIClassName));
// get the composition class name
LoadString(hInst, IDS_IMECOMPCLASS, szCompClassName, sizeof(szCompClassName));
// get the candidate class name
LoadString(hInst, IDS_IMECANDCLASS, szCandClassName, sizeof(szCandClassName));
// get the status class name
LoadString(hInst, IDS_IMESTATUSCLASS, szStatusClassName, sizeof(szStatusClassName));
// work area
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
// border + raising edge + sunken edge
cxBorder = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE) /* 2*/;
cyBorder = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE) /* 2*/;
// get the Chinese char
LoadString(hInst, IDS_CHICHAR, szChiChar, sizeof(szChiChar));
// get size of Chinese char
hDC = GetDC(NULL);
GetTextExtentPoint32(hDC, "<EFBFBD><EFBFBD>", 2, &lTextSize);
if (sImeG.rcWorkArea.right < 2 * UI_MARGIN) {
sImeG.rcWorkArea.left = 0;
sImeG.rcWorkArea.right = GetDeviceCaps(hDC, HORZRES);
}
if (sImeG.rcWorkArea.bottom < 2 * UI_MARGIN) {
sImeG.rcWorkArea.top = 0;
sImeG.rcWorkArea.bottom = GetDeviceCaps(hDC, VERTRES);
}
GetTextExtentPoint32(hDC,(LPCTSTR)"2.", 2, &hSize);
sImeG.Ajust = hSize.cx;
// get text metrics to decide the width & height of composition window
// these IMEs always use system font to show
GetTextExtentPoint32(hDC,(LPCTSTR)&CNumChar, 20, &hSize);
sImeG.TextLen = hSize.cx +2;//zl
sImeG.xChiCharWi = lTextSize.cx;
sImeG.yChiCharHi = lTextSize.cy;
// the width/high and status position relative to status window
sImeG.rcStatusText.left = 0;
sImeG.rcStatusText.top = 0;
sImeG.rcStatusText.right = STATUS_DIM_X * 5+6+20;//4; // chg
sImeG.rcStatusText.bottom = STATUS_DIM_Y;
sImeG.xStatusWi = STATUS_DIM_X * 5 + cxBorder * 2+3+18 ; //chg
if(sImeG.yChiCharHi==0x10)
sImeG.yStatusHi = STATUS_DIM_Y + cyBorder * 2-1; //zl
else
sImeG.yStatusHi = STATUS_DIM_Y + cyBorder * 2-1+2;
// left bottom of status
sImeG.rcInputText.left = sImeG.rcStatusText.left+3;//2; //zl
sImeG.rcInputText.top = sImeG.rcStatusText.top ; //zl
sImeG.rcInputText.right = sImeG.rcInputText.left + STATUS_DIM_X; //z
sImeG.rcInputText.bottom = sImeG.rcStatusText.bottom;
// no. 2 bottom of status
sImeG.rcCmdText.left = sImeG.rcInputText.right+1;//95.9.23+1;
sImeG.rcCmdText.top = sImeG.rcStatusText.top -1; //zl
sImeG.rcCmdText.right = sImeG.rcCmdText.left + STATUS_DIM_X+20; //zl
sImeG.rcCmdText.bottom = sImeG.rcStatusText.bottom;
// no. 3 bottom of status
sImeG.rcShapeText.left =sImeG.rcCmdText.right;//+1;
sImeG.rcShapeText.top = sImeG.rcStatusText.top - 1; //zl
sImeG.rcShapeText.right = sImeG.rcShapeText.left + STATUS_DIM_X; //zl
sImeG.rcShapeText.bottom = sImeG.rcStatusText.bottom;
// no 4 bottom of status
sImeG.rcPctText.left =sImeG.rcShapeText.right;
sImeG.rcPctText.top = sImeG.rcStatusText.top -1; //zl
sImeG.rcPctText.right = sImeG.rcPctText.left + STATUS_DIM_X; //zl
sImeG.rcPctText.bottom = sImeG.rcStatusText.bottom;
// 5
// right bottom of status
sImeG.rcSKText.left = sImeG.rcPctText.right;
sImeG.rcSKText.top = sImeG.rcStatusText.top - 1;
sImeG.rcSKText.right = sImeG.rcSKText.left + STATUS_DIM_X; //zl
sImeG.rcSKText.bottom = sImeG.rcStatusText.bottom;
// full shape space
sImeG.wFullSpace = sImeG.wFullABC[0];
// reverse internal code to internal code, NT don't need it
for (i = 0; i < (sizeof(sImeG.wFullABC) / 2); i++) {
sImeG.wFullABC[i] = (sImeG.wFullABC[i] << 8) |
(sImeG.wFullABC[i] >> 8);
}
LoadString(hInst, IDS_STATUSERR, sImeG.szStatusErr,
sizeof(sImeG.szStatusErr));
sImeG.cbStatusErr = lstrlen(sImeG.szStatusErr);
sImeG.iCandStart = CAND_START;
sImeG.Prop = 0;
// get the UI offset for near caret operation
RegCreateKey(HKEY_CURRENT_USER, szRegIMESetting, &hKeyIMESetting);
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKeyIMESetting, szPara, NULL, NULL,
(LPBYTE)&sImeG.iPara, &dwSize);
if (lRet != ERROR_SUCCESS) {
sImeG.iPara = 0;
RegSetValueEx(hKeyIMESetting, szPara, (DWORD)0, REG_BINARY,
(LPBYTE)&sImeG.iPara, sizeof(int));
}
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKeyIMESetting, szPerp, NULL, NULL,
(LPBYTE)&sImeG.iPerp, &dwSize);
if (lRet != ERROR_SUCCESS) {
sImeG.iPerp = sImeG.yChiCharHi;
RegSetValueEx(hKeyIMESetting, szPerp, (DWORD)0, REG_BINARY,
(LPBYTE)&sImeG.iPerp, sizeof(int));
}
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKeyIMESetting, szParaTol, NULL, NULL,
(LPBYTE)&sImeG.iParaTol, &dwSize);
if (lRet != ERROR_SUCCESS) {
sImeG.iParaTol = sImeG.xChiCharWi * 4;
RegSetValueEx(hKeyIMESetting, szParaTol, (DWORD)0, REG_BINARY,
(LPBYTE)&sImeG.iParaTol, sizeof(int));
}
dwSize = sizeof(dwSize);
lRet = RegQueryValueEx(hKeyIMESetting, szPerpTol, NULL, NULL,
(LPBYTE)&sImeG.iPerpTol, &dwSize);
if (lRet != ERROR_SUCCESS) {
sImeG.iPerpTol = lTextSize.cy;
RegSetValueEx(hKeyIMESetting,
szPerpTol,
(DWORD)0,
REG_BINARY,
(LPBYTE)&sImeG.iPerpTol,
sizeof(int));
}
RegCloseKey(hKeyIMESetting);
ReleaseDC(NULL, hDC);
return;
}
/**********************************************************************/
/* InitImeLocalData() */
/**********************************************************************/
BOOL PASCAL InitImeLocalData(
HINSTANCE hInstL)
{
HGLOBAL hResData;
int cxBorder, cyBorder;
register int i;
register WORD nSeqCode;
lpImeL->hInst = hInstL;
// load valid char in choose/input state
lpImeL->nMaxKey = 20 ;
// border + raising edge + sunken edge
cxBorder = GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXEDGE) * 2;
cyBorder = GetSystemMetrics(SM_CYBORDER) +
GetSystemMetrics(SM_CYEDGE) * 2;
// text position relative to the composition window
lpImeL->rcCompText.left = 3;
lpImeL->rcCompText.top = 3;
lpImeL->rcCompText.right = sImeG.xChiCharWi * lpImeL->nMaxKey/2+3;
lpImeL->rcCompText.bottom = sImeG.yChiCharHi+3;
lpImeL->cxCompBorder = cxBorder;
lpImeL->cyCompBorder = cyBorder;
// set the width & height for composition window
lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2;
lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2;
// default position of composition window
lpImeL->ptDefComp.x = sImeG.rcWorkArea.right -
lpImeL->yCompHi - cxBorder;
lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom -
lpImeL->xCompWi - cyBorder;
lpImeL->Ox = lpImeL->ptDefComp.x;
lpImeL->Oy = lpImeL->ptDefComp.y;
return (TRUE);
}
/**********************************************************************/
/* RegisterImeClass() */
/**********************************************************************/
void PASCAL RegisterImeClass(
HINSTANCE hInstance,
HINSTANCE hInstL)
{
WNDCLASSEX wcWndCls;
// IME UI class
wcWndCls.cbSize = sizeof(WNDCLASSEX);
wcWndCls.cbClsExtra = 0;
wcWndCls.cbWndExtra = sizeof(LONG) * 2;
wcWndCls.hIcon = LoadImage(hInstL, MAKEINTRESOURCE(IDI_IME),
IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
wcWndCls.hInstance = hInstance;
wcWndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
wcWndCls.hbrBackground = GetStockObject(LTGRAY_BRUSH/*NULL_BRUSH*/);
wcWndCls.lpszMenuName = (LPSTR)NULL;
wcWndCls.hIconSm = LoadImage(hInstL, MAKEINTRESOURCE(IDI_IME),
IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
// IME UI class
if (!GetClassInfoEx(hInstance, szUIClassName, &wcWndCls)) {
wcWndCls.style = CS_IME;
wcWndCls.lpfnWndProc = UIWndProc;
wcWndCls.lpszClassName = (LPSTR)szUIClassName;
RegisterClassEx(&wcWndCls);
}
wcWndCls.style = CS_IME|CS_HREDRAW|CS_VREDRAW;
// IME composition class
if (!GetClassInfoEx(hInstance, szCompClassName, &wcWndCls)) {
wcWndCls.lpfnWndProc = CompWndProc;
wcWndCls.lpszClassName = (LPSTR)szCompClassName;
RegisterClassEx(&wcWndCls);
}
// IME candidate class
if (!GetClassInfoEx(hInstance, szCandClassName, &wcWndCls)) {
wcWndCls.lpfnWndProc = CandWndProc;
wcWndCls.hbrBackground = GetStockObject(LTGRAY_BRUSH);
wcWndCls.lpszClassName = (LPSTR)szCandClassName;
RegisterClassEx(&wcWndCls);
}
// IME status class
if (!GetClassInfoEx(hInstance, szStatusClassName, &wcWndCls)) {
wcWndCls.lpfnWndProc = StatusWndProc;
wcWndCls.lpszClassName = (LPSTR)szStatusClassName;
RegisterClassEx(&wcWndCls);
}
if (!GetClassInfoEx(hInstance, "Abc95Menu", &wcWndCls)) {
wcWndCls.style = 0;
wcWndCls.cbWndExtra = WND_EXTRA_SIZE;
wcWndCls.hbrBackground = GetStockObject(NULL_BRUSH);
wcWndCls.lpfnWndProc = ContextMenuWndProc;
wcWndCls.lpszClassName = "Abc95Menu";
RegisterClassEx(&wcWndCls);
}
return;
}
/**********************************************************************/
/* QuitBefore() */
/* Return Value: */
/* TRUE - successful */
/* FALSE - failure */
/**********************************************************************/
int WINAPI QuitBefore()
{
GlobalUnlock(cisu_hd);
if(cisu_hd)
GlobalFree(cisu_hd);
return 0;
}
/**********************************************************************/
/* ImeDllInit() */
/* Return Value: */
/* TRUE - successful */
/* FALSE - failure */
/**********************************************************************/
BOOL CALLBACK ImeDllInit(
HINSTANCE hInstance, // instance handle of this library
DWORD fdwReason, // reason called
LPVOID lpvReserve) // reserve pointer
{
// DebugShow("Init Stat",NULL);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
if (!hInst) {
InitImeGlobalData(hInstance);
// data_init(); /* move to the Select( ) to avoid app hang */
}
if (!lpImeL) {
lpImeL = &sImeL;
InitImeLocalData(hInstance);
}
InitUserSetting();
RegisterImeClass(hInstance, hInstance);
break;
case DLL_PROCESS_DETACH:
{
WNDCLASSEX wcWndCls;
DeleteObject (sImeG.WhitePen);
DeleteObject (sImeG.BlackPen);
DeleteObject (sImeG.GrayPen);
DeleteObject (sImeG.LightGrayPen);
QuitBefore();
if (GetClassInfoEx(hInstance, szStatusClassName, &wcWndCls)) {
UnregisterClass(szStatusClassName, hInstance);
}
if (GetClassInfoEx(hInstance, szCandClassName, &wcWndCls)) {
UnregisterClass(szCandClassName, hInstance);
}
if (GetClassInfoEx(hInstance, szCompClassName, &wcWndCls)) {
UnregisterClass(szCompClassName, hInstance);
}
if (!GetClassInfoEx(hInstance, szUIClassName, &wcWndCls)) {
} else if (!UnregisterClass(szUIClassName, hInstance)) {
} else {
DestroyIcon(wcWndCls.hIcon);
DestroyIcon(wcWndCls.hIconSm);
}
break;
}
default:
break;
}
return (TRUE);
}
/**********************************************************************/
/* GenerateMessage2() */
/**********************************************************************/
void PASCAL GenerateMessage2(
HIMC hIMC,
LPINPUTCONTEXT lpIMC,
LPPRIVCONTEXT lpImcP)
{
LPTRANSMSG lpMsgBuf;
HIMCC hMem;
BOOL bCantReSize;
if (!hIMC) {
return;
} else if (!lpIMC) {
return;
} else if (!lpImcP) {
return;
} else if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
return;
} else {
}
bCantReSize = FALSE;
if (!lpIMC->hMsgBuf) {
// it maybe free by IME, up to GEN_MSG_MAX messages for max case
lpIMC->hMsgBuf = ImmCreateIMCC(GEN_MSG_MAX * sizeof(TRANSMSG));
} else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf
+ GEN_MSG_MAX) * sizeof(TRANSMSG))) {
lpIMC->hMsgBuf = hMem;
} else {
bCantReSize = TRUE;
}
if (!lpIMC->hMsgBuf) {
lpIMC->dwNumMsgBuf = 0;
return;
}
lpMsgBuf = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
if (!lpMsgBuf) {
return;
}
if (bCantReSize) {
LPTRANSMSG lpNewBuf;
hMem = ImmCreateIMCC((lpIMC->dwNumMsgBuf + GEN_MSG_MAX) *
sizeof(TRANSMSG));
if (!hMem) {
ImmUnlockIMCC(lpIMC->hMsgBuf);
return;
}
lpNewBuf = (LPTRANSMSG)ImmLockIMCC(hMem);
if (!lpMsgBuf) {
ImmUnlockIMCC(lpIMC->hMsgBuf);
return;
}
CopyMemory(lpNewBuf, lpMsgBuf, lpIMC->dwNumMsgBuf *
sizeof(TRANSMSG));
ImmUnlockIMCC(lpIMC->hMsgBuf);
ImmDestroyIMCC(lpIMC->hMsgBuf);
lpIMC->hMsgBuf = hMem;
lpMsgBuf = lpNewBuf;
}
if(TypeOfOutMsg){
lpIMC->dwNumMsgBuf += TransAbcMsg2(lpMsgBuf, lpImcP);
}else{
lpIMC->dwNumMsgBuf += TranslateImeMessage(NULL, lpIMC, lpImcP);
}
// lpIMC->dwNumMsgBuf += TransAbcMsg(lpMsgBuf, lpImcP,lpIMC,0,0,0);
ImmUnlockIMCC(lpIMC->hMsgBuf);
lpImcP->fdwImeMsg &= (MSG_ALREADY_OPEN|MSG_ALREADY_START);
lpImcP->fdwGcsFlag &= (GCS_RESULTREAD|GCS_RESULT); // ?
ImmGenerateMessage(hIMC);
return;
}
/**********************************************************************/
/* GenerateMessage() */
/**********************************************************************/
void PASCAL GenerateMessage(
HIMC hIMC,
LPINPUTCONTEXT lpIMC,
LPPRIVCONTEXT lpImcP)
{
LPTRANSMSG lpMsgBuf;
HIMCC hMem;
BOOL bCantReSize;
if (!hIMC) {
return;
} else if (!lpIMC) {
return;
} else if (!lpImcP) {
return;
} else if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
return;
} else {
}
bCantReSize = FALSE;
if (!lpIMC->hMsgBuf) {
// it maybe free by IME, up to GEN_MSG_MAX messages for max case
lpIMC->hMsgBuf = ImmCreateIMCC(GEN_MSG_MAX * sizeof(TRANSMSG));
} else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf, (lpIMC->dwNumMsgBuf
+ GEN_MSG_MAX) * sizeof(TRANSMSG))) {
lpIMC->hMsgBuf = hMem;
} else {
bCantReSize = TRUE;
}
if (!lpIMC->hMsgBuf) {
lpIMC->dwNumMsgBuf = 0;
return;
}
lpMsgBuf = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
if (!lpMsgBuf) {
return;
}
if (bCantReSize) {
LPTRANSMSG lpNewBuf;
hMem = ImmCreateIMCC((lpIMC->dwNumMsgBuf + GEN_MSG_MAX) *
sizeof(TRANSMSG));
if (!hMem) {
ImmUnlockIMCC(lpIMC->hMsgBuf);
return;
}
lpNewBuf = (LPTRANSMSG)ImmLockIMCC(hMem);
if (!lpMsgBuf) {
ImmUnlockIMCC(lpIMC->hMsgBuf);
return;
}
CopyMemory(lpNewBuf, lpMsgBuf, lpIMC->dwNumMsgBuf *
sizeof(TRANSMSG));
ImmUnlockIMCC(lpIMC->hMsgBuf);
ImmDestroyIMCC(lpIMC->hMsgBuf);
lpIMC->hMsgBuf = hMem;
lpMsgBuf = lpNewBuf;
}
lpIMC->dwNumMsgBuf += TranslateImeMessage(NULL, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hMsgBuf);
lpImcP->fdwImeMsg &= (MSG_ALREADY_OPEN|MSG_ALREADY_START);
lpImcP->fdwGcsFlag &= (GCS_RESULTREAD|GCS_RESULT); // ?
ImmGenerateMessage(hIMC);
return;
}
/**********************************************************************/
/* SetString() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL PASCAL SetString(
HIMC hIMC,
LPINPUTCONTEXT lpIMC,
LPCOMPOSITIONSTRING lpCompStr,
LPPRIVCONTEXT lpImcP,
LPSTR lpszRead,
DWORD dwReadLen)
{
DWORD dwPattern;
DWORD i;
if (dwReadLen > (lpImeL->nMaxKey * sizeof(WORD)+20)) {
return (FALSE);
}
// compoition/reading attribute
lpCompStr->dwCompReadAttrLen = dwReadLen;
lpCompStr->dwCompAttrLen = lpCompStr->dwCompReadAttrLen;
for (i = 0; i < dwReadLen; i++) { // The IME has converted these chars
*((LPBYTE)lpCompStr + lpCompStr->dwCompReadAttrOffset + i) =
ATTR_TARGET_CONVERTED;
}
// composition/reading clause, 1 clause only
lpCompStr->dwCompReadClauseLen = 2 * sizeof(DWORD);
lpCompStr->dwCompClauseLen = lpCompStr->dwCompReadClauseLen;
*(LPUNADWORD)((LPBYTE)lpCompStr + lpCompStr->dwCompReadClauseOffset +
sizeof(DWORD)) = dwReadLen;
lpCompStr->dwCompReadStrLen = dwReadLen;
lpCompStr->dwCompStrLen = lpCompStr->dwCompReadStrLen;
CopyMemory((LPBYTE)lpCompStr + lpCompStr->dwCompReadStrOffset, lpszRead,
dwReadLen);
// dlta start from 0;
lpCompStr->dwDeltaStart = 0;
// cursor is next to composition string
lpCompStr->dwCursorPos = lpCompStr->dwCompStrLen;
lpCompStr->dwResultReadClauseLen = 0;
lpCompStr->dwResultReadStrLen = 0;
lpCompStr->dwResultClauseLen = 0;
lpCompStr->dwResultStrLen = 0;
// set private input context
lpImcP->iImeState = CST_INPUT;
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
~(MSG_OPEN_CANDIDATE);
}
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_START_COMPOSITION) &
~(MSG_END_COMPOSITION);
}
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
//zst lpImcP->dwCompChar = (DWORD)lpImeL->wSeq2CompTbl[
//zst lpImcP->bSeq[lpCompStr->dwCompReadStrLen / 2 - 1]];
lpImcP->dwCompChar = HIBYTE(lpImcP->dwCompChar) |
(LOBYTE(lpImcP->dwCompChar) << 8);
lpImcP->fdwGcsFlag = GCS_COMPREAD|GCS_COMP|
GCS_DELTASTART|GCS_CURSORPOS;
if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
if (lpCompStr->dwCompReadStrLen >= sizeof(WORD) * lpImeL->nMaxKey) {
lpImcP->fdwImeMsg |= MSG_COMPOSITION;
lpImcP->fdwGcsFlag |= GCS_RESULTREAD|GCS_RESULTSTR;
}
} else {
if (dwReadLen < sizeof(WORD) * lpImeL->nMaxKey) {
// quick key
if (lpImeL->fModeConfig & MODE_CONFIG_QUICK_KEY) {
//zst Finalize(lpIMC, lpCompStr, lpImcP, FALSE);
}
} else {
UINT nCand;
LPGUIDELINE lpGuideLine;
//zst nCand = Finalize(lpIMC, lpCompStr, lpImcP, TRUE);
if (!lpIMC->hGuideLine) {
goto SeStGenMsg;
}
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
if (!lpGuideLine) {
goto SeStGenMsg;
/*
} else if (nCand == 1) {
} else if (nCand > 1) {
*/
} else {
// nothing found, end user, you have an error now
lpGuideLine->dwLevel = GL_LEVEL_ERROR;
lpGuideLine->dwIndex = GL_ID_TYPINGERROR;
lpImcP->fdwImeMsg |= MSG_GUIDELINE;
}
ImmUnlockIMCC(lpIMC->hGuideLine);
}
}
SeStGenMsg:
GenerateMessage(hIMC, lpIMC, lpImcP);
return (TRUE);
}
/**********************************************************************/
/* CompEscapeKey() */
/**********************************************************************/
void PASCAL CompEscapeKey(
LPINPUTCONTEXT lpIMC,
LPCOMPOSITIONSTRING lpCompStr,
LPGUIDELINE lpGuideLine,
LPPRIVCONTEXT lpImcP)
{
if (!lpGuideLine) {
MessageBeep((UINT)-1);
} else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) {
} else {
lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE;
lpGuideLine->dwIndex = GL_ID_UNKNOWN;
lpGuideLine->dwStrLen = 0;
lpImcP->fdwImeMsg |= MSG_GUIDELINE;
}
if (lpImcP->iImeState != CST_INIT) {
} else if (lpCompStr->dwCompStrLen) {
// clean the compose string
} else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_END_COMPOSITION) &
~(MSG_START_COMPOSITION);
} else {
}
lpImcP->iImeState = CST_INIT;
// *(LPDWORD)lpImcP->bSeq = 0;
// lpImcP->wPhraseNextOffset = lpImcP->wWordNextOffset = 0;
InitCvtPara();
if (lpCompStr) {
InitCompStr(lpCompStr);
lpImcP->fdwImeMsg |= MSG_END_COMPOSITION;
lpImcP->dwCompChar = VK_ESCAPE;
lpImcP->fdwGcsFlag |= (GCS_COMPREAD|GCS_COMP|GCS_CURSORPOS|
GCS_DELTASTART);
}
return;
}
/**********************************************************************/
/* CandEscapeKey() */
/**********************************************************************/
void PASCAL CandEscapeKey(
LPINPUTCONTEXT lpIMC,
LPPRIVCONTEXT lpImcP)
{
LPCOMPOSITIONSTRING lpCompStr;
LPGUIDELINE lpGuideLine;
// clean all candidate information
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
ClearCand(lpIMC);
lpImcP->fdwImeMsg = (lpImcP->fdwImeMsg | MSG_CLOSE_CANDIDATE) &
~(MSG_OPEN_CANDIDATE);
}
lpImcP->iImeState = CST_INPUT;
// if it start composition, we need to clean composition
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
return;
}
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
ImmUnlockIMCC(lpIMC->hGuideLine);
ImmUnlockIMCC(lpIMC->hCompStr);
return;
}
/**********************************************************************/
/* CompCancel() */
/**********************************************************************/
void PASCAL CompCancel(
HIMC hIMC,
LPINPUTCONTEXT lpIMC)
{
LPPRIVCONTEXT lpImcP;
if (!lpIMC->hPrivate) {
return;
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
return;
}
lpImcP->fdwGcsFlag = (DWORD)0;
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
CandEscapeKey(lpIMC, lpImcP);
} else if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
LPCOMPOSITIONSTRING lpCompStr;
LPGUIDELINE lpGuideLine;
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
if ( lpCompStr && lpGuideLine )
CompEscapeKey(lpIMC, lpCompStr, lpGuideLine, lpImcP);
ImmUnlockIMCC(lpIMC->hGuideLine);
ImmUnlockIMCC(lpIMC->hCompStr);
} else {
ImmUnlockIMCC(lpIMC->hPrivate);
return;
}
lpImcP->fdwImeMsg |= MSG_COMPOSITION; //#52224
GenerateMessage(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
InitCvtPara();
return;
}
/**********************************************************************/
/* ImeSetCompositionString() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeSetCompositionString(
HIMC hIMC,
DWORD dwIndex,
LPVOID lpComp,
DWORD dwCompLen,
LPVOID lpRead,
DWORD dwReadLen)
{
LPINPUTCONTEXT lpIMC;
LPCOMPOSITIONSTRING lpCompStr;
LPPRIVCONTEXT lpImcP;
BOOL fRet;
if (!hIMC) {
return (FALSE);
}
// composition string must == reading string
// reading is more important
if (!dwReadLen) {
dwReadLen = dwCompLen;
}
// composition string must == reading string
// reading is more important
if (!lpRead) {
lpRead = lpComp;
}
if (!dwReadLen) {
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
CompCancel(hIMC, lpIMC);
ImmUnlockIMC(hIMC);
return (TRUE);
} else if (!lpRead) {
return (FALSE);
} else if (!dwCompLen) {
} else if (!lpComp) {
} else if (dwReadLen != dwCompLen) {
return (FALSE);
} else if (lpRead == lpComp) {
} else if (!lstrcmp(lpRead, lpComp)) {
// composition string must == reading string
} else {
// composition string != reading string
return (FALSE);
}
if (dwIndex != SCS_SETSTR) {
return (FALSE);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
if (!lpIMC->hCompStr) {
ImmUnlockIMC(hIMC);
return (FALSE);
}
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
if (!lpCompStr) {
ImmUnlockIMC(hIMC);
return (FALSE);
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
fRet = SetString(hIMC, lpIMC, lpCompStr, lpImcP, lpRead, dwReadLen);
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMCC(lpIMC->hCompStr);
ImmUnlockIMC(hIMC);
return (fRet);
}
/**********************************************************************/
/* ToggleSoftKbd() */
/**********************************************************************/
void PASCAL ToggleSoftKbd(
HIMC hIMC,
LPINPUTCONTEXT lpIMC)
{
LPPRIVCONTEXT lpImcP;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
return;
}
lpImcP->fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
GenerateMessage(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
return;
}
/**********************************************************************/
/* NotifySelectCand() */
/**********************************************************************/
void PASCAL NotifySelectCand( // app tell IME that one candidate string is
// selected (by mouse or non keyboard action
// - for example sound)
HIMC hIMC,
LPINPUTCONTEXT lpIMC,
LPCANDIDATEINFO lpCandInfo,
DWORD dwIndex,
DWORD dwValue)
{
LPPRIVCONTEXT lpImcP;
if (!lpCandInfo) {
return;
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
CharProc((WORD)dwValue,0,0,hIMC,lpIMC,lpImcP);
GenerateMessage2(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMCC(lpIMC->hCompStr);
return;
}
/**********************************************************************/
/* NotifySetMode() */
/**********************************************************************/
void PASCAL NotifySetMode(
HIMC hIMC)
{
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if(!lpIMC) return ;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP){
ImmUnlockIMC(hIMC);
return ;
}
GenerateMessage(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* GenerateImeMessage() */
/**********************************************************************/
void PASCAL GenerateImeMessage(
HIMC hIMC,
LPINPUTCONTEXT lpIMC,
DWORD fdwImeMsg)
{
LPPRIVCONTEXT lpImcP;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
return;
}
lpImcP->fdwImeMsg |= fdwImeMsg;
if (fdwImeMsg & MSG_CLOSE_CANDIDATE) {
lpImcP->fdwImeMsg &= ~(MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE);
} else if (fdwImeMsg & (MSG_OPEN_CANDIDATE|MSG_CHANGE_CANDIDATE)) {
lpImcP->fdwImeMsg &= ~(MSG_CLOSE_CANDIDATE);
} else {
}
if (fdwImeMsg & MSG_END_COMPOSITION) {
lpImcP->fdwImeMsg &= ~(MSG_START_COMPOSITION);
} else if (fdwImeMsg & MSG_START_COMPOSITION) {
lpImcP->fdwImeMsg &= ~(MSG_END_COMPOSITION);
} else {
}
GenerateMessage(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
return;
}
/**********************************************************************/
/* NotifyIME() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI NotifyIME(
HIMC hIMC,
DWORD dwAction,
DWORD dwIndex,
DWORD dwValue)
{
LPINPUTCONTEXT lpIMC;
DWORD fdwImeMsg;
LPPRIVCONTEXT lpImcP;
if (!hIMC) {
return (TRUE);
}
switch (dwAction) {
case NI_OPENCANDIDATE: // after a composition string is determined
// if an IME can open candidate, it will.
// if it can not, app also can not open it.
case NI_CLOSECANDIDATE:
return (FALSE);
case NI_SELECTCANDIDATESTR:
break; // need to handle it
case NI_CHANGECANDIDATELIST:
return (TRUE); // not important to the IME
case NI_CONTEXTUPDATED:
switch (dwValue) {
case IMC_SETCONVERSIONMODE:
case IMC_SETSENTENCEMODE:
case IMC_SETOPENSTATUS:
break; // need to handle it
case IMC_SETCANDIDATEPOS:
case IMC_SETCOMPOSITIONFONT:
case IMC_SETCOMPOSITIONWINDOW:
return (TRUE); // not important to the IME
default:
return (FALSE); // not supported
}
break;
case NI_COMPOSITIONSTR:
switch (dwIndex) {
case CPS_CONVERT: // all composition string can not be convert
case CPS_REVERT: // any more, it maybe work for some
// intelligent phonetic IMEs
return (FALSE);
case CPS_CANCEL:
break; // need to handle it
default:
return (FALSE); // not supported
}
break; // need to handle it
default:
return (FALSE); // not supported
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
switch (dwAction) {
case NI_CONTEXTUPDATED:
switch (dwValue) {
case IMC_SETCONVERSIONMODE:
if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_FULLSHAPE) {
break;
}
if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SOFTKBD) {
ToggleSoftKbd(hIMC, lpIMC);
if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_SOFTKBD) {
break;
}
}
if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_NATIVE) {
lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
IME_CMODE_NOCONVERSION|IME_CMODE_EUDC);
}
// if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_CHARCODE) {
// lpIMC->fdwConversion &= ~(IME_CMODE_EUDC);
// }
CompCancel(hIMC, lpIMC);
break;
/*
if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_CHARCODE) {
// reject CHARCODE
lpIMC->fdwConversion &= ~IME_CMODE_CHARCODE;
MessageBeep((UINT)-1);
break;
}
fdwImeMsg = 0;
if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_NOCONVERSION) {
lpIMC->fdwConversion |= IME_CMODE_NATIVE;
lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
IME_CMODE_EUDC|IME_CMODE_SYMBOL);
}
if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_EUDC) {
lpIMC->fdwConversion |= IME_CMODE_NATIVE;
lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
IME_CMODE_NOCONVERSION|IME_CMODE_SYMBOL);
}
if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SOFTKBD) {
LPPRIVCONTEXT lpImcP;
if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
MessageBeep((UINT)-1);
break;
}
fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
} else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
} else {
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
goto NotifySKOvr;
}
if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
// now we already in soft keyboard state by
// this change
// even end user finish the symbol, we should not
// turn off soft keyboard
lpImcP->fdwImeMsg |= MSG_ALREADY_SOFTKBD;
} else {
// now we are not in soft keyboard state by
// this change
// after end user finish the symbol, we should
// turn off soft keyboard
lpImcP->fdwImeMsg &= ~(MSG_ALREADY_SOFTKBD);
}
ImmUnlockIMCC(lpIMC->hPrivate);
NotifySKOvr:
; // NULL statement for goto
}
if ((lpIMC->fdwConversion ^ dwIndex) == IME_CMODE_NATIVE) {
lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
IME_CMODE_NOCONVERSION|IME_CMODE_EUDC|IME_CMODE_SYMBOL);
fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
}
if ((lpIMC->fdwConversion ^ dwIndex) & IME_CMODE_SYMBOL) {
LPCOMPOSITIONSTRING lpCompStr;
LPPRIVCONTEXT lpImcP;
if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
MessageBeep((UINT)-1);
break;
}
if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
lpIMC->fdwConversion |= (dwIndex & IME_CMODE_SYMBOL);
MessageBeep((UINT)-1);
break;
}
lpCompStr = ImmLockIMCC(lpIMC->hCompStr);
if (lpCompStr) {
if (!lpCompStr->dwCompStrLen) {
} else if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
// if there is a string we could not change
// to symbol mode
lpIMC->fdwConversion &= ~(IME_CMODE_SYMBOL);
MessageBeep((UINT)-1);
break;
} else {
}
ImmUnlockIMCC(lpIMC->hCompStr);
}
lpIMC->fdwConversion &= ~(IME_CMODE_CHARCODE|
IME_CMODE_NOCONVERSION|IME_CMODE_EUDC);
if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
lpIMC->fdwConversion |= IME_CMODE_SOFTKBD;
} else if (lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate)) {
// we borrow the bit for this usage
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_SOFTKBD)) {
lpIMC->fdwConversion &= ~(IME_CMODE_SOFTKBD);
}
ImmUnlockIMCC(lpIMC->hPrivate);
} else {
}
fdwImeMsg |= MSG_IMN_UPDATE_SOFTKBD;
}
if (fdwImeMsg) {
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if(!lpImcP){
lpImcP->fdwImeMsg = lpImcP->fdwImeMsg &~(MSG_IN_IMETOASCIIEX);
}
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
GenerateImeMessage(hIMC, lpIMC, fdwImeMsg);
}
if ((lpIMC->fdwConversion ^ dwIndex) & ~(IME_CMODE_FULLSHAPE|
IME_CMODE_SOFTKBD)) {
} else {
break;
}
CompCancel(hIMC, lpIMC);
break;
*/
case IMC_SETOPENSTATUS:
CompCancel(hIMC, lpIMC);
break;
default:
break;
}
break;
case NI_SELECTCANDIDATESTR:
if (!lpIMC->fOpen) {
break;
} else if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
break;
} else if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
break;
} else if (!lpIMC->hCandInfo) {
break;
} else {
LPCANDIDATEINFO lpCandInfo;
lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo);
NotifySelectCand(hIMC, lpIMC, lpCandInfo, dwIndex, dwValue);
ImmUnlockIMCC(lpIMC->hCandInfo);
}
break;
case NI_COMPOSITIONSTR:
switch (dwIndex) {
case CPS_CANCEL:
CompCancel(hIMC, lpIMC);
break;
default:
break;
}
break;
default:
break;
}
ImmUnlockIMC(hIMC);
return (TRUE);
}
/**********************************************************************/
/* ImeRegsisterWord */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeRegisterWord(
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString)
{
return (0);
}
/**********************************************************************/
/* ImeUnregsisterWord */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeUnregisterWord(
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString)
{
return (0);
}
/**********************************************************************/
/* ImeGetRegsisterWordStyle */
/* Return Value: */
/* number of styles copied/required */
/**********************************************************************/
UINT WINAPI ImeGetRegisterWordStyle(
UINT nItem,
LPSTYLEBUF lpStyleBuf)
{
return (1);
}
/**********************************************************************/
/* ImeEnumRegisterWord */
/* Return Value: */
/* the last value return by the callback function */
/**********************************************************************/
UINT WINAPI ImeEnumRegisterWord(
REGISTERWORDENUMPROC lpfnRegisterWordEnumProc,
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString,
LPVOID lpData)
{
return (0);
}
/**********************************************************************/
/* GetStatusWnd */
/* Return Value : */
/* window handle of status window */
/**********************************************************************/
HWND PASCAL GetStatusWnd(
HWND hUIWnd) // UI window
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HWND hStatusWnd;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw status window
return (HWND)NULL;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw status window
return (HWND)NULL;
}
hStatusWnd = lpUIPrivate->hStatusWnd;
GlobalUnlock(hUIPrivate);
return (hStatusWnd);
}
/**********************************************************************/
/* SetStatusWindowPos() */
/**********************************************************************/
LRESULT PASCAL SetStatusWindowPos(
HWND hStatusWnd)
{
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
RECT rcStatusWnd;
POINT ptPos;
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return (1L);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) { // Oh! Oh!
return (1L);
}
GetWindowRect(hStatusWnd, &rcStatusWnd);
//DebugShow2( "ptPos=",lpIMC->ptStatusWndPos.x,"ptPos.y", rcStatusWnd.left);
if (lpIMC->ptStatusWndPos.x != rcStatusWnd.left) {
} else if (lpIMC->ptStatusWndPos.y != rcStatusWnd.top) {
} else {
ImmUnlockIMC(hIMC);
return (0L);
}
//DebugShow2( "ptPos111=",NULL,"ptPos.y",NULL);
// ptPos = lpIMC->ptStatusWndPos;
// display boundary adjust
ptPos.x = lpIMC->ptStatusWndPos.x;
ptPos.y = lpIMC->ptStatusWndPos.y;
AdjustStatusBoundary(&ptPos);
SetWindowPos(hStatusWnd, NULL,
ptPos.x, ptPos.y,
0, 0, /*SWP_SHOWWINDOW|*/SWP_NOACTIVATE/*|SWP_NOCOPYBITS*/|SWP_NOSIZE|SWP_NOZORDER);
CountDefaultComp(ptPos.x,ptPos.y,sImeG.rcWorkArea);
ImmUnlockIMC(hIMC);
return (0L);
}
/**********************************************************************/
/* CountDefaultComp() */
/**********************************************************************/
int CountDefaultComp(int x, int y, RECT Area)
{
POINT Comp,Cand;
Comp.x = lpImeL->ptZLComp.x;
Comp.y = lpImeL->ptZLComp.y;
Cand.x = lpImeL->ptZLCand.x;
Cand.y = lpImeL->ptZLCand.y;
lpImeL->ptZLComp.x = x + sImeG.xStatusWi+4;
lpImeL->ptZLComp.y = y;
if ((Area.right-lpImeL->ptZLComp.x -lpImeL->xCompWi)<10){
lpImeL->ptZLComp.x = x - lpImeL->xCompWi-4;
}
// lpImeL->ptZLCand.x = lpImeL->ptZLComp.x - lpImeL->xCandWi -4;}
return 0;
}
/**********************************************************************/
/* ShowStatus() */
/**********************************************************************/
void PASCAL ShowStatus( // Show the status window - shape / soft KBD
// alphanumeric ...
HWND hUIWnd,
int nShowStatusCmd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw status window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw status window
return;
}
if (!lpUIPrivate->hStatusWnd) {
// not in show status window mode
} else if (lpUIPrivate->nShowStatusCmd != nShowStatusCmd) {
RECT Area;
SystemParametersInfo(SPI_GETWORKAREA, 0, &Area, 0);
if((sImeG.rcWorkArea.bottom != Area.bottom)
||(sImeG.rcWorkArea.top != Area.top)
||(sImeG.rcWorkArea.left != Area.left)
||(sImeG.rcWorkArea.right != Area.right))
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if(hIMC){
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (lpIMC){
if (((lpIMC->ptStatusWndPos.y + sImeG.yStatusHi)==sImeG.rcWorkArea.bottom)
||((lpIMC->ptStatusWndPos.y + sImeG.yStatusHi)>Area.bottom)){
lpIMC->ptStatusWndPos.y = Area.bottom - sImeG.yStatusHi;
} else if ((lpIMC->ptStatusWndPos.y ==sImeG.rcWorkArea.top)
||(lpIMC->ptStatusWndPos.y < Area.top)){
lpIMC->ptStatusWndPos.y = Area.top;
}
if ((lpIMC->ptStatusWndPos.x==sImeG.rcWorkArea.left)
||(lpIMC->ptStatusWndPos.x<Area.left)){
lpIMC->ptStatusWndPos.x = Area.left;
}else if (((lpIMC->ptStatusWndPos.x + sImeG.xStatusWi)==sImeG.rcWorkArea.right)
||((lpIMC->ptStatusWndPos.x + sImeG.xStatusWi)>Area.right)){
lpIMC->ptStatusWndPos.x = Area.right - sImeG.xStatusWi;
}
SetWindowPos(lpUIPrivate->hStatusWnd, NULL,
lpIMC->ptStatusWndPos.x,
lpIMC->ptStatusWndPos.y,
0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
CountDefaultComp(lpIMC->ptStatusWndPos.x,lpIMC->ptStatusWndPos.y,Area);
ImmUnlockIMC(hIMC);
sImeG.rcWorkArea.bottom = Area.bottom;
sImeG.rcWorkArea.top = Area.top;
sImeG.rcWorkArea.left = Area.left;
sImeG.rcWorkArea.right = Area.right;
}
}
}
ShowWindow(lpUIPrivate->hStatusWnd, nShowStatusCmd);
lpUIPrivate->nShowStatusCmd = nShowStatusCmd;
} else {
}
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* OpenStatus() */
/**********************************************************************/
void PASCAL OpenStatus( // open status window
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
POINT ptPos;
int nShowStatusCmd;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw status window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw status window
return;
}
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
ptPos.x = sImeG.rcWorkArea.left;
ptPos.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
nShowStatusCmd = SW_HIDE;
} else if (lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC)) {
if (lpIMC->ptStatusWndPos.x < sImeG.rcWorkArea.left) {
lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left;
} else if (lpIMC->ptStatusWndPos.x + sImeG.xStatusWi >
sImeG.rcWorkArea.right) {
lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right -
sImeG.xStatusWi;
}
if (lpIMC->ptStatusWndPos.y < sImeG.rcWorkArea.top) {
lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.top;
} else if (lpIMC->ptStatusWndPos.y + sImeG.yStatusHi >
sImeG.rcWorkArea.right) {
lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom -
sImeG.yStatusHi;
}
ptPos.x = lpIMC->ptStatusWndPos.x;
ptPos.y = lpIMC->ptStatusWndPos.y,
ImmUnlockIMC(hIMC);
nShowStatusCmd = SW_SHOWNOACTIVATE;
} else {
ptPos.x = sImeG.rcWorkArea.left;
ptPos.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;
nShowStatusCmd = SW_HIDE;
}
if (lpUIPrivate->hStatusWnd) {
SetWindowPos(lpUIPrivate->hStatusWnd, NULL,
ptPos.x, ptPos.y,
0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
} else { // create status window
lpUIPrivate->hStatusWnd = CreateWindowEx(
0,
szStatusClassName, NULL, WS_POPUP|WS_DISABLED/*|WS_BORDER*/,
ptPos.x, ptPos.y,
sImeG.xStatusWi, sImeG.yStatusHi,
hUIWnd, (HMENU)NULL, hInst, NULL);
if ( lpUIPrivate->hStatusWnd )
{
ReInitIme(lpUIPrivate->hStatusWnd, lpImeL->wImeStyle); //#@2
SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_OFFSET,
WINDOW_NOT_DRAG);
SetWindowLong(lpUIPrivate->hStatusWnd, UI_MOVE_XY, 0L);
}
}
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* DestroyStatusWindow() */
/**********************************************************************/
void PASCAL DestroyStatusWindow(
HWND hStatusWnd)
{
HWND hUIWnd;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // can not darw status window
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // can not draw status window
return;
}
lpUIPrivate->nShowStatusCmd = SW_HIDE;
lpUIPrivate->hStatusWnd = (HWND)NULL;
GlobalUnlock(hUIPrivate);
return;
}
/**********************************************************************/
/* SetStatus */
/**********************************************************************/
void PASCAL SetStatus(
HWND hStatusWnd,
LPPOINT lpptCursor)
{
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
if (!lpIMC->fOpen) {
ImmSetOpenStatus(hIMC, TRUE);
} else if (PtInRect(&sImeG.rcInputText, *lpptCursor)) {
DWORD fdwConversion;
if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
// change to alphanumeric mode
fdwConversion = lpIMC->fdwConversion & ~(IME_CMODE_NATIVE );
{
LPPRIVCONTEXT lpImcP;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
ghIMC=hIMC;
glpIMCP=lpImcP;
glpIMC=lpIMC;
lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
cls_prompt();
InitCvtPara();
GenerateMessage(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
}
} else {
if(lpIMC->fdwConversion & IME_CMODE_NOCONVERSION){
// Simulate a key press
keybd_event( VK_CAPITAL,
0x3A,
KEYEVENTF_EXTENDEDKEY | 0,
0 );
// Simulate a key release
keybd_event( VK_CAPITAL,
0x3A,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
cap_mode = 0;
fdwConversion = (lpIMC->fdwConversion | IME_CMODE_NATIVE) &
~(IME_CMODE_NOCONVERSION);
}else
fdwConversion = lpIMC->fdwConversion |IME_CMODE_NATIVE;
}
ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
}
if (PtInRect(&sImeG.rcShapeText, *lpptCursor)) {
DWORD dwConvMode;
dwConvMode = lpIMC->fdwConversion ^ IME_CMODE_FULLSHAPE;
ImmSetConversionStatus(hIMC, dwConvMode, lpIMC->fdwSentence);
}
if (PtInRect(&sImeG.rcSKText, *lpptCursor)) {
DWORD fdwConversion;
KeyBoardState = ~KeyBoardState ;
fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SOFTKBD;
ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
}
if (PtInRect(&sImeG.rcPctText, *lpptCursor)) {
DWORD fdwConversion;
fdwConversion = lpIMC->fdwConversion ^ IME_CMODE_SYMBOL;
ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
}
if (PtInRect(&sImeG.rcCmdText, *lpptCursor)) {
if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
DWORD fdc;
if (kb_mode==CIN_STD){
kb_mode = CIN_SDA;
fdc = lpIMC->fdwConversion|IME_CMODE_SDA;
}else{
kb_mode = CIN_STD;
fdc = lpIMC->fdwConversion&~IME_CMODE_SDA;
}
ImmSetConversionStatus(hIMC, fdc, lpIMC->fdwSentence);
{
LPPRIVCONTEXT lpImcP;
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
ghIMC=hIMC;
glpIMCP=lpImcP;
glpIMC=lpIMC;
lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
cls_prompt();
InitCvtPara();
GenerateMessage(hIMC, lpIMC, lpImcP);
ImmUnlockIMCC(lpIMC->hPrivate);
}
DispMode(hIMC);
}else
MessageBeep((UINT)-1);
}
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* PaintStatusWindow() */
/**********************************************************************/
void PASCAL PaintStatusWindow(
HDC hDC,
HWND hStatusWnd)
{
HWND hUIWnd;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
HBITMAP hInputBmp, hShapeBmp, hSKBmp, hCmdBmp, hPctBmp;
HBITMAP hOldBmp;
HDC hMemDC;
int TopOfBmp = 2;
if (sImeG.yChiCharHi > 0x10)
TopOfBmp = 3;
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
MessageBeep((UINT)-1);
return;
}
if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
MessageBeep((UINT)-1);
return;
}
hInputBmp = (HBITMAP)NULL;
hShapeBmp = (HBITMAP)NULL;
hSKBmp = (HBITMAP)NULL;
hCmdBmp = (HBITMAP)NULL;
hPctBmp = (HBITMAP)NULL;
if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
hInputBmp = LoadBitmap(hInst, szChinese);
} else {
hInputBmp = LoadBitmap(hInst, szEnglish);
}
if (!lpIMC->fOpen) {
hShapeBmp = LoadBitmap(hInst, szNone);
hPctBmp = LoadBitmap(hInst, szNone);
hSKBmp = LoadBitmap(hInst, szNone);
if (kb_mode == CIN_SDA){
hCmdBmp = LoadBitmap(hInst, szNoSDA);
}else{
hCmdBmp = LoadBitmap(hInst, szNoSTD);
}
}else{
if (lpIMC->fdwConversion & IME_CMODE_FULLSHAPE) {
hShapeBmp = LoadBitmap(hInst, szFullShape);
} else {
hShapeBmp = LoadBitmap(hInst, szHalfShape);
}
if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
hSKBmp = LoadBitmap(hInst, szSoftKBD);
if (sImeG.First){
DWORD fdw;
fdw = lpIMC->fdwConversion;
ImmSetConversionStatus(hIMC,lpIMC->fdwConversion^IME_CMODE_SOFTKBD, lpIMC->fdwSentence);
ImmSetConversionStatus(hIMC, fdw, lpIMC->fdwSentence);
sImeG.First = 0;
}
} else {
hSKBmp = LoadBitmap(hInst, szNoSoftKBD);
}
if (lpIMC->fdwConversion & IME_CMODE_SYMBOL)
hPctBmp = LoadBitmap(hInst, szCPCT);
else
hPctBmp = LoadBitmap(hInst, szEPCT);
if (kb_mode == CIN_SDA){
hCmdBmp = LoadBitmap(hInst, szSDA);
}else{
hCmdBmp = LoadBitmap(hInst, szSTD);
}
}
ImmUnlockIMC(hIMC);
DrawStatusRect(hDC, 0,0,sImeG.xStatusWi-1, sImeG.yStatusHi-1);
hMemDC = CreateCompatibleDC(hDC);
if ( hMemDC )
{
hOldBmp = SelectObject(hMemDC, hInputBmp);
BitBlt(hDC, sImeG.rcInputText.left,TopOfBmp,
sImeG.rcInputText.right,
sImeG.yStatusHi,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hCmdBmp);
BitBlt(hDC, sImeG.rcCmdText.left, TopOfBmp,
sImeG.rcCmdText.right - sImeG.rcCmdText.left,
sImeG.yStatusHi,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hPctBmp);
BitBlt(hDC, sImeG.rcPctText.left, TopOfBmp,
sImeG.rcPctText.right - sImeG.rcPctText.left,
sImeG.yStatusHi,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hShapeBmp);
BitBlt(hDC, sImeG.rcShapeText.left, TopOfBmp,
sImeG.rcShapeText.right - sImeG.rcShapeText.left,
sImeG.yStatusHi,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hSKBmp);
BitBlt(hDC, sImeG.rcSKText.left, TopOfBmp,
sImeG.rcSKText.right - sImeG.rcSKText.left, //zl 95.8.25
sImeG.yStatusHi,
hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, hOldBmp);
DeleteDC(hMemDC);
}
DeleteObject(hInputBmp);
DeleteObject(hShapeBmp);
DeleteObject(hSKBmp);
DeleteObject(hCmdBmp);
DeleteObject(hPctBmp);
return;
}
/**********************************************************************/
/* NeedsKey() */
/* Function: Sub route for Proccesskey proc */
/* Return Value: */
/* The converted key value or 0 for not needs. */
/**********************************************************************/
WORD
NeedsKey(kv)
WORD kv;
{
WORD ascnum;
if((kv>='0')&&(kv<='9'))
return(kv);
if((kv>='A')&&(kv<='Z'))
if (cap_mode)
return(kv);
else
return(kv|0x20);
switch(kv){
case VK_RETURN:
case VK_SPACE:
case VK_ESCAPE:
case VK_BACK:
return(kv);
case VK_NUMPAD0: // 0x60
return('0');
case VK_NUMPAD1: // 0x61
case VK_NUMPAD2: // 0x62
case VK_NUMPAD3: // 0x63
case VK_NUMPAD4: // 0x64
case VK_NUMPAD5: // 0x65
case VK_NUMPAD6: // 0x66
case VK_NUMPAD7: // 0x67
case VK_NUMPAD8: // 0x68
case VK_NUMPAD9: // 0x69
ascnum = kv - VK_NUMPAD1 + '1';
break;
// case VK_MULTIPLY: // 0x6A
// return '*';
// case VK_ADD : // 0x6B
// return '+';
// case VK_SEPARATOR: // 0x6C
// case VK_SUBTRACT: // 0x6D
// case VK_DECIMAL : // 0x6E
// case VK_DIVIDE : // 0x6F
// ascnum = kv - 0x40;
// break;
case VK_DANYINHAO: // 0xc0 // [,] char = // 0x60
ascnum = 0x60;
break;
case VK_JIANHAO : // 0xbd // [-] char = // 0x2d
ascnum = 0x2d;
break;
case VK_DENGHAO : // 0xbb // [=] char = // 0x3d
ascnum = 0x3d;
break;
case VK_ZUOFANG : // 0xdb // "[" char = // 0x5b
ascnum = 0x5b;
break;
case VK_YOUFANG : // 0xdd // "]" char = // 0x5d
ascnum = 0x5d;
break;
case VK_FENHAO : // 0xba // [;] char = // 0x3b
ascnum = 0x3B;
break;
case VK_ZUODAN : // 0xde // ['] char = // 0x27
ascnum = 0x27;
break;
case VK_DOUHAO : // 0xbc // [,] char = // 0x2c
ascnum = 0x2c;
break;
case VK_JUHAO : // 0xbe // [.] char = // 0x2d
ascnum = '.';
break;
case VK_SHANGXIE : // 0xbf // [/] char = // 0x2f
ascnum = 0x2f;
break;
case VK_XIAXIE : // 0xdc // [\] char = // 0x5c
ascnum = 0x5c;
break;
case VK_SHIFT:
return(2);
default:
return(0);
}
return(ascnum);
}
/**********************************************************************/
/* NeedsKeyShift() */
/* Function: Deels with the case of Shift key Down */
/* Return Value: */
/* The converted key value. */
/**********************************************************************/
WORD
NeedsKeyShift(kv)
WORD kv;
{
WORD xx=0;
if((kv>='A')&&(kv<='Z'))
if (cap_mode)
return(kv|0x20);
else
return(kv);
switch(kv){
case '1':
xx='!';
break;
case '2':
xx='@';
break;
case '3':
xx='#';
break;
case '4':
xx='$';
break;
case '5':
xx='%';
break;
case '6':
xx='^';
break;
case '7':
xx='&';
break;
case '8':
xx='*';
break;
case '9':
xx='(';
break;
case '0':
xx=')';
break;
case VK_DANYINHAO: // 0xc0 // [,] char = // 0x60
xx = '~';
break;
case VK_JIANHAO : // 0xbd // [-] char = // 0x2d
xx = '_';
break;
case VK_DENGHAO : // 0xbb // [=] char = // 0x3d
xx = '+';
break;
case VK_ZUOFANG : // 0xdb // "[" char = // 0x5b
xx = '{';
break;
case VK_YOUFANG : // 0xdd // "]" char = // 0x5d
xx = '}';
break;
case VK_FENHAO : // 0xba // [;] char = // 0x3b
xx = ':';
break;
case VK_ZUODAN : // 0xde // ['] char = // 0x27
xx = '"';
break;
case VK_DOUHAO : // 0xbc // [,] char = // 0x2c
xx = '<';
break;
case VK_JUHAO : // 0xbe // [.] char = // 0x2d
xx = '>';
break;
case VK_SHANGXIE : // 0xbf // [/] char = // 0x2f
xx = '?';
break;
case VK_XIAXIE : // 0xdc // [\] char = // 0x5c
xx = '|';
break;
}
return xx;
}
/**********************************************************************/
/* ProcessKey() */
/* Function: Check a key if needs for the current processing */
/* Return Value: */
/* different state which input key will change IME to */
/**********************************************************************/
UINT PASCAL ProcessKey( // this key will cause the IME go to what state
WORD nCode,
UINT wParam, //uVirtKey,
UINT uScanCode,
LPBYTE lpbKeyState,
LPINPUTCONTEXT lpIMC,
LPPRIVCONTEXT lpImcP,
HIMC hIMC)
{
int x;
WORD w,op;
if (!lpIMC) {
return (CST_INVALID);
}
if (!lpImcP) {
return (CST_INVALID);
}
if (wParam == VK_MENU) { // no ALT key
return (CST_INVALID);
} else if (uScanCode & KF_ALTDOWN) { // no ALT-xx key
return (CST_INVALID);
} else if (!lpIMC->fOpen) {
return (CST_INVALID);
}
if (wParam == VK_CAPITAL){
x=cap_mode;
// Change to comply with NT 3.51 VK_CAPITAL check style 6
#ifdef LATER
if (!GetKeyState(VK_CAPITAL)&1){ //if the Caps Lock status
#else
if (GetKeyState(VK_CAPITAL)&1){ //if the Caps Lock status
#endif //LATER
DWORD fdwConversion;
cap_mode=1;
if (lpIMC->fdwConversion & IME_CMODE_NATIVE) {
// change to alphanumeric mode
fdwConversion = (lpIMC->fdwConversion|IME_CMODE_NOCONVERSION)
& ~(IME_CMODE_NATIVE);
ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
{
BOOL hbool;
hbool = ImmGetOpenStatus(hIMC);
//ImmSetOpenStatus(hIMC, !hbool);
ImmSetOpenStatus(hIMC, hbool);
ghIMC=hIMC;
glpIMCP=lpImcP;
glpIMC=lpIMC;
lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
cls_prompt();
lpImcP->fdwImeMsg=lpImcP->fdwImeMsg|MSG_END_COMPOSITION;
GenerateMessage(ghIMC, glpIMC,glpIMCP);
V_Flag = 0;
bx_inpt_on = 0;
}
step_mode = 0;
}
}else{
DWORD fdwConversion;
cap_mode=0;
if (lpIMC->fdwConversion & IME_CMODE_NOCONVERSION) {
// change to alphanumeric mode
fdwConversion = (lpIMC->fdwConversion |IME_CMODE_NATIVE)
& ~(IME_CMODE_NOCONVERSION);
ImmSetConversionStatus(hIMC, fdwConversion, lpIMC->fdwSentence);
{
BOOL hbool;
hbool = ImmGetOpenStatus(hIMC);
//ImmSetOpenStatus(hIMC, !hbool);
ImmSetOpenStatus(hIMC, hbool);
ghIMC=hIMC;
glpIMCP=lpImcP;
glpIMC=lpIMC;
lpImcP->fdwImeMsg=lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
cls_prompt();
lpImcP->fdwImeMsg=lpImcP->fdwImeMsg|MSG_END_COMPOSITION;
GenerateMessage(ghIMC, glpIMC,glpIMCP);
}
}
}
return (CST_INVALID);
}
if (lpbKeyState[VK_CONTROL]&0x80) // If CTRL pressed
// if (!((HIBYTE(HIWORD(lParam)))&0x80))
{
// DebugShow("In ProcessKey Keystate %X",*lpbKeyState);
op=0xffff;
if (nCode==VK_F2){
return TRUE;
}
if (!(lpIMC->fdwConversion &IME_CMODE_NOCONVERSION))
switch(nCode){
case '1':
op=SC_METHOD1;
break;
case '2':
op=SC_METHOD2;
break;
case '3':
op=SC_METHOD3;
break;
case '4':
op=SC_METHOD4;
break;
case '5':
op=SC_METHOD5;
break;
case '6':
op=SC_METHOD6;
break;
case '7':
op=SC_METHOD7;
break;
case '8':
op=SC_METHOD8;
break;
case '9':
op=SC_METHOD9;
break;
case '0':
op=SC_METHOD10;
break;
case 0xbd:
op='-'|0x8000;
break;
case 0xbb:
op='='|0x8000;
break;
//case 0xdb:
// op='['|0x8000;
// break;
//case 0xdd:
// op=']'|0x8000;
// break;
default:
op=0xffff;
}//switch
if(op!=0xffff){
return(TRUE);
}
return(CST_INVALID);
}
// if((nCode == VK_TAB)&&SdaPromptOpen) return 0;
if(!step_mode&&!(lpIMC->fdwConversion&IME_CMODE_FULLSHAPE))
if(nCode == ' ') return(CST_INVALID);
switch(wParam){
case VK_END:
case VK_HOME:
case VK_PRIOR:
case VK_NEXT:
if (step_mode == SELECT)
return(TRUE);
// case VK_SHIFT:
case VK_CONTROL:
// case VK_PRIOR:
// case VK_NEXT:
case VK_TAB:
// case VK_DELETE:
case VK_INSERT:
case VK_F1:
case VK_F2:
case VK_F3:
case VK_F4:
case VK_F5:
case VK_F6:
case VK_F7:
case VK_F8:
case VK_F9:
case VK_F10:
case VK_F11:
case VK_F12:
case VK_F13:
case VK_F14:
case VK_F15:
case VK_F16:
case VK_F17:
case VK_F18:
case VK_F19:
case VK_F20:
case VK_F21:
case VK_F22:
case VK_F23:
case VK_F24:
case VK_NUMLOCK:
case VK_SCROLL:
return(CST_INVALID);
}
// if ((cap_mode)&&(lpIMC->fdwConversion & IME_CMODE_FULLSHAPE)) //zl
// return(CST_INVALID);
switch(nCode){
case VK_LEFT:
case VK_UP:
case VK_RIGHT:
case VK_DOWN:
case VK_DELETE:
if (step_mode!=ONINPUT)
return(CST_INVALID);
else
return(TRUE);
}
if((step_mode==START)||(step_mode==RESELECT))
switch(nCode){
case VK_SHIFT:
case VK_RETURN:
case VK_CANCEL:
case VK_BACK:
case VK_ESCAPE:
return(CST_INVALID);
}
if (lpbKeyState[VK_SHIFT]&0x80){
// If candidate windows is already opened, stop further process.
// Keep 'shift' for stroke input mode 4/17
if (sImeG.cbx_flag) {}
else
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)return(CST_INVALID);
if ((w=NeedsKeyShift(nCode))!=0)
return(TRUE);
else
return(CST_INVALID);
} else{
w=NeedsKey(nCode);
if( w != 0)
return(TRUE);
}
return(CST_INVALID);
}
/**********************************************************************/
/* ImeProcessKey() */
/* Return Value: */
/* TRUE - successful, FALSE - failure */
/**********************************************************************/
BOOL WINAPI ImeProcessKey( // if this key is need by IME?
HIMC hIMC,
UINT uVirtKey,
LPARAM lParam,
CONST LPBYTE lpbKeyState)
{
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
BYTE szAscii[4];
int nChars;
BOOL fRet;
// can't compose in NULL hIMC
if (!hIMC) {
return (FALSE);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return (FALSE);
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
ImmUnlockIMC(hIMC);
return (FALSE);
}
nChars = ToAscii(uVirtKey, HIWORD(lParam), lpbKeyState,
(LPVOID)szAscii, 0);
if (!nChars) {
szAscii[0] = 0;
}
if (ProcessKey((WORD)uVirtKey, uVirtKey, HIWORD(lParam), lpbKeyState,
lpIMC, lpImcP, hIMC) == CST_INVALID) {
fRet = FALSE;
} else {
fRet = TRUE;
}
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return (fRet);
}
/**********************************************************************/
/* TranslateFullChar() */
/* Return Value: */
/* the number of translated chars */
/**********************************************************************/
UINT PASCAL TranslateFullChar( // convert to Double Byte Char
LPTRANSMSGLIST lpTransBuf,
WORD wCharCode)
{
LPTRANSMSG lpTransMsg;
// if your IME is possible to generate over ? messages,
// you need to take care about it
wCharCode = sImeG.wFullABC[wCharCode - ' '];
lpTransMsg = lpTransBuf->TransMsg;
// NT need to modify this!
lpTransMsg->message = WM_CHAR;
lpTransMsg->wParam = (DWORD)HIBYTE(wCharCode);
lpTransMsg->lParam = 1UL;
lpTransMsg++;
lpTransMsg->message = WM_CHAR;
lpTransMsg->wParam = (DWORD)LOBYTE(wCharCode);
lpTransMsg->lParam = 1UL;
return (2); // generate two messages
}
/**********************************************************************/
/* TranslateTo () */
/* Return Value: */
/* the number of translated chars */
/**********************************************************************/
UINT PASCAL TranslateToAscii( // translate the key to WM_CHAR
// as keyboard driver
UINT uVirtKey,
UINT uScanCode,
LPTRANSMSGLIST lpTransBuf,
WORD wCharCode)
{
LPTRANSMSG lpTransMsg;
lpTransMsg = lpTransBuf->TransMsg;
if (wCharCode) { // one char code
lpTransMsg->message = WM_CHAR;
lpTransMsg->wParam = wCharCode;
lpTransMsg->lParam = (uScanCode << 16) | 1UL;
return (1);
}
// no char code case
return (0);
}
/**********************************************************************/
/* TranslateImeMessage() */
/* Return Value: */
/* the number of translated messages */
/**********************************************************************/
UINT PASCAL TranslateImeMessage(
LPTRANSMSGLIST lpTransBuf,
LPINPUTCONTEXT lpIMC,
LPPRIVCONTEXT lpImcP)
{
UINT uNumMsg;
UINT i;
BOOL bLockMsgBuf;
LPTRANSMSG lpTransMsg;
uNumMsg = 0;
bLockMsgBuf = FALSE;
for (i = 0; i < 2; i++) {
if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONSIZE) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_PRIVATE;
lpTransMsg->lParam = IMN_PRIVATE_COMPOSITION_SIZE;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_START_COMPOSITION) {
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_START)) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_STARTCOMPOSITION;
lpTransMsg->wParam = 0;
lpTransMsg->lParam = 0;
lpTransMsg++;
lpImcP->fdwImeMsg |= MSG_ALREADY_START;
}
}
}
if (lpImcP->fdwImeMsg & MSG_IMN_COMPOSITIONPOS) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_SETCOMPOSITIONWINDOW;
lpTransMsg->lParam = 0;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_COMPOSITION;
lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_GUIDELINE) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_GUIDELINE;
lpTransMsg->lParam = 0;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_IMN_PAGEUP) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_PRIVATE;
lpTransMsg->lParam = IMN_PRIVATE_PAGEUP;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_OPEN_CANDIDATE) {
if (!(lpImcP->fdwImeMsg & MSG_ALREADY_OPEN)) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_OPENCANDIDATE;
lpTransMsg->lParam = 0x0001;
lpTransMsg++;
lpImcP->fdwImeMsg |= MSG_ALREADY_OPEN;
}
}
}
if (lpImcP->fdwImeMsg & MSG_CHANGE_CANDIDATE) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_CHANGECANDIDATE;
lpTransMsg->lParam = 0x0001;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_IMN_UPDATE_PREDICT) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_PRIVATE;
lpTransMsg->lParam = IMN_PRIVATE_UPDATE_PREDICT;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_IMN_UPDATE_SOFTKBD) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_PRIVATE;
lpTransMsg->lParam = IMN_PRIVATE_UPDATE_SOFTKBD;
lpTransMsg++;
}
}
if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_CLOSECANDIDATE;
lpTransMsg->lParam = 0x0001;
lpTransMsg++;
lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
}
}
}
if (lpImcP->fdwImeMsg & MSG_END_COMPOSITION) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_START) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_ENDCOMPOSITION;
lpTransMsg->wParam = 0;
lpTransMsg->lParam = 0;
lpTransMsg++;
lpImcP->fdwImeMsg &= ~(MSG_ALREADY_START);
}
}
}
if (lpImcP->fdwImeMsg & MSG_IMN_TOGGLE_UI) {
if (!i) {
uNumMsg++;
} else {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_PRIVATE;
lpTransMsg->lParam = IMN_PRIVATE_TOGGLE_UI;
lpTransMsg++;
}
}
if (!i) {
HIMCC hMem;
if (!uNumMsg) {
return (uNumMsg);
}
if (lpImcP->fdwImeMsg & MSG_IN_IMETOASCIIEX) {
UINT uNumMsgLimit;
// ++ for the start position of buffer to strore the messages
uNumMsgLimit = lpTransBuf->uMsgCount;
if (uNumMsg <= uNumMsgLimit) {
lpTransMsg = lpTransBuf->TransMsg;
continue;
}
}
// we need to use message buffer
if (!lpIMC->hMsgBuf) {
lpIMC->hMsgBuf = ImmCreateIMCC(uNumMsg * sizeof(TRANSMSG));
lpIMC->dwNumMsgBuf = 0;
} else if (hMem = ImmReSizeIMCC(lpIMC->hMsgBuf,
(lpIMC->dwNumMsgBuf + uNumMsg) * sizeof(TRANSMSG))) {
if (hMem != lpIMC->hMsgBuf) {
ImmDestroyIMCC(lpIMC->hMsgBuf);
lpIMC->hMsgBuf = hMem;
}
} else {
return (0);
}
lpTransMsg = (LPTRANSMSG)ImmLockIMCC(lpIMC->hMsgBuf);
if (!lpTransMsg) {
return (0);
}
lpTransMsg += lpIMC->dwNumMsgBuf;
bLockMsgBuf = TRUE;
} else {
if (bLockMsgBuf) {
ImmUnlockIMCC(lpIMC->hMsgBuf);
}
}
}
return (uNumMsg);
}
/**********************************************************************/
/* TransAbcMsg2() */
/* Return Value: */
/* the number of translated messages */
/**********************************************************************/
UINT PASCAL TransAbcMsg2(
LPTRANSMSG lpTransMsg,
LPPRIVCONTEXT lpImcP)
{
UINT uNumMsg;
uNumMsg = 0;
if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
lpTransMsg->message = WM_IME_COMPOSITION;
lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
lpTransMsg++;
uNumMsg++;
}
if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_CLOSECANDIDATE;
lpTransMsg->lParam = 0x0001;
lpTransMsg++;
uNumMsg++;
lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
}
}
lpTransMsg->message = WM_IME_ENDCOMPOSITION;
lpTransMsg->wParam = 0;
lpTransMsg->lParam = 0;
uNumMsg++;
lpImcP->fdwImeMsg = 0;
return (uNumMsg);
}
/**********************************************************************/
/* TransAbcMsg() */
/* Return Value: */
/* the number of translated messages */
/**********************************************************************/
UINT PASCAL TransAbcMsg(
LPTRANSMSGLIST lpTransBuf,
LPPRIVCONTEXT lpImcP,
LPINPUTCONTEXT lpIMC,
UINT uVirtKey,
UINT uScanCode,
WORD wCharCode)
{
LPCOMPOSITIONSTRING lpCompStr ;
UINT uNumMsg;
int i;
int MsgCount;
LPSTR pp;
LPTRANSMSG lpTransMsg;
lpTransMsg = lpTransBuf->TransMsg;
uNumMsg = 0;
if (TypeOfOutMsg&ABC_OUT_ONE){
uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,wCharCode);
lpTransMsg++;
return (uNumMsg);
}else{
if (TypeOfOutMsg&ABC_OUT_ASCII){
lpTransMsg = lpTransBuf->TransMsg;
lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
if (!lpCompStr)
uNumMsg = 0;
else{
MsgCount = lpCompStr->dwResultStrLen;
pp = (LPSTR)lpCompStr + lpCompStr->dwResultStrOffset;
for (i = 0; i < MsgCount; i++){
if((BYTE)pp[i]<0x80){
WORD x;
x =(WORD)VkKeyScan((TCHAR)(BYTE)pp[i]);
lpTransMsg->message = WM_KEYUP;
lpTransMsg->wParam = (DWORD)(BYTE)x;//(DWORD)(BYTE)pp[i];
lpTransMsg->lParam = 1UL;
lpTransMsg++;
uNumMsg++;
}else{
lpTransMsg->message = WM_CHAR;
lpTransMsg->wParam = (DWORD)(BYTE)pp[i];
lpTransMsg->lParam = 1UL;
lpTransMsg++;
uNumMsg++;
}
}
ImmUnlockIMCC(lpIMC->hCompStr);
}
}else{
lpTransMsg = lpTransBuf->TransMsg;
}
}
if (lpImcP->fdwImeMsg & MSG_COMPOSITION) {
lpTransMsg->message = WM_IME_COMPOSITION;
lpTransMsg->wParam = (DWORD)lpImcP->dwCompChar;
lpTransMsg->lParam = (DWORD)lpImcP->fdwGcsFlag;
lpTransMsg++;
uNumMsg++;
}
if (lpImcP->fdwImeMsg & MSG_CLOSE_CANDIDATE) {
if (lpImcP->fdwImeMsg & MSG_ALREADY_OPEN) {
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_CLOSECANDIDATE;
lpTransMsg->lParam = 0x0001;
lpTransMsg++;
uNumMsg++;
lpImcP->fdwImeMsg &= ~(MSG_ALREADY_OPEN);
}
}
lpTransMsg->message = WM_IME_ENDCOMPOSITION;
lpTransMsg->wParam = 0;
lpTransMsg->lParam = 0;
lpTransMsg++;
uNumMsg++;
lpImcP->fdwImeMsg = 0;
TypeOfOutMsg = TypeOfOutMsg | COMP_NEEDS_END;
if (wait_flag||waitzl_flag){ //waitzl 2
lpTransMsg->message = WM_IME_NOTIFY;
lpTransMsg->wParam = IMN_SETCOMPOSITIONWINDOW;
lpTransMsg->lParam = 0;
lpTransMsg++;
uNumMsg++;
lpTransMsg->message = WM_IME_STARTCOMPOSITION;
lpTransMsg->wParam = 0;
lpTransMsg->lParam = 0x6699;
lpTransMsg++;
uNumMsg++;
lpImcP->fdwImeMsg |= MSG_ALREADY_START;
}
return (uNumMsg);
}
/**********************************************************************/
/* KeyFilter() */
/* Return Value: */
/* the number of translated message */
/**********************************************************************/
WORD KeyFilter(nCode,wParam,lParam,lpImcP , lpbKeyState )
WORD nCode;
WORD wParam;
DWORD lParam;
LPPRIVCONTEXT lpImcP;
LPBYTE lpbKeyState;
{
int x;
WORD w,op;
if (lpbKeyState[VK_CONTROL]&0x80) // If CTRL pressed
{
op=0xffff;
if (nCode==VK_F2){
//zst futur PostMessage(hMenuWnd,WM_COMMAND,SC_METHODA,0);
return 0;
}
switch(nCode){
case '1':
op=SC_METHOD1;
break;
case '2':
op=SC_METHOD2;
break;
case '3':
op=SC_METHOD3;
break;
case '4':
op=SC_METHOD4;
break;
case '5':
op=SC_METHOD5;
break;
case '6':
op=SC_METHOD6;
break;
case '7':
op=SC_METHOD7;
break;
case '8':
op=SC_METHOD8;
break;
case '9':
op=SC_METHOD9;
break;
case '0':
op=SC_METHOD10;
break;
case 0xbd:
op='-'|0x8000;
break;
case 0xbb:
op='='|0x8000;
break;
//case 0xdb:
// op='['|0x8000;
// break;
//case 0xdd:
// op=']'|0x8000;
// break;
default:
op=0xffff;
}//switch
if(op!=0xffff){
if(op&(WORD)0x8000)
return op;
else{
//zst future PostMessage(hMenuWnd,WM_COMMAND,op,0);
//zst future EventFrom = 1;
}
return(0);
}
return(0);
}
switch(nCode){
case VK_PRIOR:
case VK_NEXT:
case VK_HOME:
case VK_END:
if(step_mode == SELECT)
return(nCode*0x100);
else return(0);
case VK_LEFT:
case VK_UP:
case VK_RIGHT:
case VK_DOWN:
case VK_DELETE:
if (step_mode!=ONINPUT)
return(0);
else
return(nCode+0x100);
}
if (lpbKeyState/*GetKeyState*/[VK_SHIFT]&0x80){
if ((w=NeedsKeyShift(nCode))!=0)
return (w);
else
return (0);
} else{
if((w=NeedsKey(nCode)) != 0)
return (w);
}
return(0);
}
/**********************************************************************/
/* TranslateSymbolChar() */
/* Return Value: */
/* the number of translated chars */
/**********************************************************************/
UINT PASCAL TranslateSymbolChar(
LPTRANSMSGLIST lpTransBuf,
WORD wSymbolCharCode)
{
UINT uRet;
LPTRANSMSG lpTransMsg;
uRet = 0;
lpTransMsg = lpTransBuf->TransMsg;
// NT need to modify this!
lpTransMsg->message = WM_CHAR;
lpTransMsg->wParam = (DWORD)HIBYTE(wSymbolCharCode);
lpTransMsg->lParam = 1UL;
lpTransMsg++;
uRet++;
lpTransMsg->message = WM_CHAR;
lpTransMsg->wParam = (DWORD)LOBYTE(wSymbolCharCode);
lpTransMsg->lParam = 1UL;
lpTransMsg++;
uRet++;
return (uRet); // generate two messages
}
/**********************************************************************/
/* ImeToAsciiEx() */
/* Return Value: */
/* the number of translated message */
/**********************************************************************/
UINT WINAPI ImeToAsciiEx(
UINT uVirtKey,
UINT uScanCode,
CONST LPBYTE lpbKeyState,
LPTRANSMSGLIST lpTransBuf,
UINT fuState,
HIMC hIMC)
{
WORD wCharCode;
WORD wCharZl;
LPINPUTCONTEXT lpIMC;
LPCOMPOSITIONSTRING lpCompStr;
LPPRIVCONTEXT lpImcP;
UINT uNumMsg;
int iRet;
wCharCode = HIBYTE(uVirtKey);
uVirtKey = LOBYTE(uVirtKey);
if (!hIMC) {
uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
wCharCode);
return (uNumMsg);
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
wCharCode);
return (uNumMsg);
}
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if (!lpImcP) {
ImmUnlockIMC(hIMC);
uNumMsg = TranslateToAscii(uVirtKey, uScanCode, lpTransBuf,
wCharCode);
return (uNumMsg);
}
lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & (MSG_ALREADY_OPEN|
MSG_ALREADY_START) | MSG_IN_IMETOASCIIEX;
// deal with softkbd
if ((lpIMC->fdwConversion & IME_CMODE_SOFTKBD)
&& (lpImeL->dwSKWant != 0) &&
(wCharCode >= ' ' && wCharCode <= '~')) {
WORD wSymbolCharCode;
WORD CHIByte, CLOByte;
int SKDataIndex;
// Mapping VK
if(uVirtKey == 0x20) {
SKDataIndex = 0;
} else if(uVirtKey >= 0x30 && uVirtKey <= 0x39) {
SKDataIndex = uVirtKey - 0x30 + 1;
} else if (uVirtKey >= 0x41 && uVirtKey <= 0x5a) {
SKDataIndex = uVirtKey - 0x41 + 0x0b;
} else if (uVirtKey >= 0xba && uVirtKey <= 0xbf) {
SKDataIndex = uVirtKey - 0xba + 0x25;
} else if (uVirtKey >= 0xdb && uVirtKey <= 0xde) {
SKDataIndex = uVirtKey - 0xdb + 0x2c;
} else if (uVirtKey == 0xc0) {
SKDataIndex = 0x2b;
} else {
SKDataIndex = 0;
}
//
if (lpbKeyState[VK_SHIFT] & 0x80) {
CHIByte = SKLayoutS[lpImeL->dwSKWant][SKDataIndex*2] & 0x00ff;
CLOByte = SKLayoutS[lpImeL->dwSKWant][SKDataIndex*2 + 1] & 0x00ff;
} else {
CHIByte = SKLayout[lpImeL->dwSKWant][SKDataIndex*2] & 0x00ff;
CLOByte = SKLayout[lpImeL->dwSKWant][SKDataIndex*2 + 1] & 0x00ff;
}
wSymbolCharCode = (CHIByte << 8) | CLOByte;
if(wSymbolCharCode == 0x2020) {
MessageBeep((UINT) -1);
uNumMsg = 0;
} else {
uNumMsg = TranslateSymbolChar(lpTransBuf, wSymbolCharCode);
}
lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return (uNumMsg);
}
sImeG.KeepKey = 0;
if(wCharZl=KeyFilter(/*wCharCode*/uVirtKey,uVirtKey,uScanCode,lpImcP , lpbKeyState )){
if(wCharZl<0x100)
wCharZl = wCharCode;
CharProc(wCharZl,/*wCharCode*/uVirtKey,uScanCode,hIMC,lpIMC,lpImcP);
}
if(TypeOfOutMsg){
uNumMsg = TransAbcMsg(lpTransBuf, lpImcP,lpIMC,uVirtKey,uScanCode, wCharCode);
}else {
uNumMsg = TranslateImeMessage(lpTransBuf, lpIMC, lpImcP);
}
lpImcP->fdwImeMsg = lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX;
ImmUnlockIMCC(lpIMC->hPrivate);
ImmUnlockIMC(hIMC);
return (uNumMsg);
}
/**********************************************************************/
/* CancelCompCandWindow() */
/**********************************************************************/
void PASCAL CancelCompCandWindow( // destroy composition window
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) return ;
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) return;
if (lpUIPrivate->hCompWnd) {
// DestroyWindow(lpUIPrivate->hCompWnd);
ShowWindow(lpUIPrivate->hCompWnd,SW_HIDE);
}
if (lpUIPrivate->hCandWnd) {
DestroyWindow(lpUIPrivate->hCandWnd);
// ShowWindow(lpUIPrivate->hCandWnd,SW_HIDE);
}
GlobalUnlock(hUIPrivate);
// SendMessage(hUIWnd,WM_IME_ENDCOMPOSITION,0,0L);
return;
}
int DoPropertySheet(HWND hwndOwner,HWND hWnd)
{
PROPSHEETPAGE psp[3];
PROPSHEETHEADER psh;
BYTE KbType;
BYTE cp_ajust_flag;
BYTE auto_mode ;
BYTE cbx_flag;
BYTE tune_flag;
BYTE auto_cvt_flag;
BYTE SdOpenFlag ;
WORD wImeStyle ;
HIMC hIMC;
HWND hUIWnd;
if (sImeG.Prop) return 0;
//Fill out the PROPSHEETPAGE data structure for the Background Color
//sheet
sImeG.Prop = 1;
if(hWnd){
hUIWnd = GetWindow(hWnd,GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
}else
hIMC = 0;
wImeStyle = lpImeL->wImeStyle;
KbType = sImeG.KbType;
cp_ajust_flag=sImeG.cp_ajust_flag;
auto_mode=sImeG.auto_mode;
cbx_flag=sImeG.cbx_flag;
tune_flag=sImeG.tune_flag;
auto_cvt_flag=sImeG.auto_cvt_flag;
SdOpenFlag=sImeG.SdOpenFlag;
sImeG.unchanged = 0;
if(hIMC)
ImmSetOpenStatus(hIMC,FALSE);
if(hIMC)
{
LPINPUTCONTEXT lpIMC;
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) { // Oh! Oh!
return (0L);
}
DialogBox(hInst,(LPCTSTR)ImeStyleDlg, lpIMC->hWnd, ImeStyleProc);
ImmUnlockIMC(hIMC);
}else{
DialogBox(hInst,(LPCTSTR)ImeStyleDlg, hwndOwner, ImeStyleProc);
}
if(hIMC)
ImmSetOpenStatus(hIMC,TRUE);
if (sImeG.unchanged){
lpImeL->wImeStyle = wImeStyle ;
sImeG.KbType = KbType;
sImeG.cp_ajust_flag = cp_ajust_flag;
sImeG.auto_mode = auto_mode;
sImeG.cbx_flag = cbx_flag;
sImeG.tune_flag = tune_flag;
sImeG.auto_cvt_flag = auto_cvt_flag;
sImeG.SdOpenFlag = SdOpenFlag;
}else{
ChangeUserSetting();
}
sImeG.Prop = 0;
return (!sImeG.unchanged);
}
void WINAPI CenterWindow(HWND hWnd)
{
RECT WorkArea;
RECT rcRect;
int x,y,mx,my;
SystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
GetWindowRect(hWnd,&rcRect);
mx = WorkArea.left + (WorkArea.right - WorkArea.left)/2;
my = WorkArea.top + (WorkArea.bottom - WorkArea.top)/2;
x = mx - (rcRect.right - rcRect.left)/2;
y = my - (rcRect.bottom - rcRect.top)/2;
SetWindowPos (hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
return;
}
INT_PTR CALLBACK ImeStyleProc(HWND hdlg,
UINT uMessage,
WPARAM wparam,
LPARAM lparam)
{
switch (uMessage) {
case WM_INITDIALOG: /* message: initialize dialog box */
hCrtDlg = hdlg;
CenterWindow(hdlg);
if (lpImeL->wImeStyle == IME_APRS_FIX)
SendMessage(GetDlgItem(hdlg, IDC_FIX),
BM_SETCHECK,
TRUE,
0L);
else
SendMessage(GetDlgItem(hdlg, IDC_NEAR),
BM_SETCHECK,
TRUE,
0L);
if(sImeG.auto_mode)
SendMessage(GetDlgItem(hdlg, IDC_CP),
BM_SETCHECK,
TRUE,
0L);
if(sImeG.cbx_flag)
SendMessage(GetDlgItem(hdlg, IDC_CBX),
BM_SETCHECK,
TRUE,
0L);
return (TRUE);
case WM_PAINT:
{
RECT Rect;
HDC hDC;
PAINTSTRUCT ps;
GetClientRect(hdlg, &Rect); //get the whole window area
InvalidateRect(hdlg, &Rect, 1);
hDC=BeginPaint(hdlg, &ps);
Rect.left+=10;//5;
Rect.top+=8;//5;
Rect.right-=10;//5;
Rect.bottom-=52;//5;
DrawEdge(hDC, &Rect, EDGE_RAISED,/*EDGE_SUNKEN,*/ BF_RECT);
EndPaint(hdlg, &ps);
break;
}
case WM_CLOSE:
EndDialog(hdlg, FALSE);
return (TRUE);
case WM_COMMAND:
switch (wparam){
case IDC_BUTTON_OK:
EndDialog(hdlg, TRUE);
return (TRUE);
case IDC_BUTTON_ESC:
sImeG.unchanged = 1;
EndDialog(hdlg, TRUE);
return (TRUE);
case IDC_NEAR:
lpImeL->wImeStyle = IME_APRS_AUTO;
break;
case IDC_FIX:
lpImeL->wImeStyle = IME_APRS_FIX;
break;
case IDC_CP:
if (sImeG.auto_mode ==0){
sImeG.auto_mode = 1;
break;
} else
sImeG.auto_mode = 0;
break;
case IDC_CBX:
if (sImeG.cbx_flag==0)
sImeG.cbx_flag = 1;
else
sImeG.cbx_flag = 0;
break;
}
}
return (FALSE); /* Didn't process a message */
}
INT_PTR CALLBACK KbSelectProc(HWND hdlg,
UINT uMessage,
WPARAM wparam,
LPARAM lparam)
{
HWND hWndApp;
WORD wID;
LPNMHDR lpnmhdr;
return FALSE;
}
INT_PTR CALLBACK CvtCtrlProc(HWND hdlg,
UINT uMessage,
WPARAM wparam,
LPARAM lparam)
{
return FALSE;
}
/**********************************************************************/
/* ContextMenu() */
/**********************************************************************/
void PASCAL ContextMenu(
HWND hStatusWnd,
int x,
int y)
{
HWND hUIWnd;
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPPRIVCONTEXT lpImcP;
HMENU hMenu, hCMenu;
POINT ptCursor; //zl #2
ptCursor.x = x;
ptCursor.y = y;
// DebugShow2("ptCursor.x", x, "ptCursor.y" ,y);
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
if (!hIMC) {
return;
}
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) {
return;
}
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) {
goto ContextMenuUnlockIMC;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) {
goto ContextMenuUnlockIMC;
}
if (!lpUIPrivate->hCMenuWnd) {
// this is important to assign owner window, otherwise the focus
// will be gone
// When UI terminate, it need to destroy this window
lpUIPrivate->hCMenuWnd = CreateWindowEx(CS_HREDRAW|CS_VREDRAW,
"Abc95Menu",
/*lpImeL->szCMenuClassName,*/ "Context Menu",
WS_POPUP|WS_DISABLED, 0, 0, 0, 0,
lpIMC->hWnd, (HMENU)NULL, lpImeL->hInst, NULL);
if (!lpUIPrivate->hCMenuWnd) {
goto ContextMenuUnlockIMC;
}
}
ScreenToClient(hStatusWnd , &ptCursor);
if (PtInRect(&sImeG.rcSKText, ptCursor)){
hMenu = LoadMenu(hInst,"SKMenu");
lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
if(lpImcP){
CheckMenuItem(hMenu,lpImeL->dwSKWant+IDM_SKL1,MF_CHECKED);
ImmUnlockIMCC(lpIMC->hPrivate);
}
}
else hMenu = LoadMenu(hInst,"MMenu");
hCMenu = GetSubMenu(hMenu, 0);
if ( lpImeL->fWinLogon == TRUE )
{
// In Logon Mode, we don't want to show help and configuration dialog
EnableMenuItem(hCMenu, 107, MF_BYCOMMAND | MF_GRAYED );
EnableMenuItem(hCMenu, 110, MF_BYCOMMAND | MF_GRAYED );
EnableMenuItem(hCMenu, 109, MF_BYCOMMAND | MF_GRAYED );
}
SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_HUIWND, (LONG_PTR)hUIWnd);
SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_MENU, (LONG_PTR)hMenu);
/*
if (!(lpIMC->fdwConversion & IME_CMODE_NATIVE)) {
// EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
// EnableMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_GRAYED);
} else if (lpIMC->fOpen) {
// can not go into symbol mode
if (lpIMC->fdwConversion & IME_CMODE_EUDC) {
// EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
} else {
if (lpIMC->fdwConversion & IME_CMODE_SYMBOL) {
// CheckMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_CHECKED);
}
}
if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) {
// CheckMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_CHECKED);
}
} else {
// EnableMenuItem(hCMenu, IDM_SYMBOL, MF_BYCOMMAND|MF_GRAYED);
// EnableMenuItem(hCMenu, IDM_SOFTKBD, MF_BYCOMMAND|MF_GRAYED);
}
*/
TrackPopupMenu(hCMenu, TPM_LEFTBUTTON,
lpIMC->ptStatusWndPos.x ,
lpIMC->ptStatusWndPos.y ,
0,
lpUIPrivate->hCMenuWnd, NULL);
hMenu = (HMENU)GetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_MENU);
if (hMenu) {
SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
DestroyMenu(hMenu);
}
GlobalUnlock(hUIPrivate);
ContextMenuUnlockIMC:
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* StatusSetCursor() */
/**********************************************************************/
void PASCAL StatusSetCursor(
HWND hStatusWnd,
LPARAM lParam)
{
POINT ptCursor, ptSavCursor;
RECT rcWnd;
RECT rcSt;
rcSt.left = sImeG.rcStatusText.left+3;
rcSt.top = sImeG.rcStatusText.top + 3;
rcSt.right = sImeG.rcStatusText.right-3;
rcSt.bottom = sImeG.rcStatusText.bottom;
if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
return;
}
GetCursorPos(&ptCursor);
ptSavCursor = ptCursor;
ScreenToClient(hStatusWnd, &ptCursor);
if (PtInRect(&rcSt, ptCursor)) {
SetCursor(LoadCursor(hInst,szHandCursor ));
if (HIWORD(lParam) == WM_LBUTTONDOWN) {
SetStatus(hStatusWnd, &ptCursor);
} else if (HIWORD(lParam) == WM_RBUTTONUP) {
static BOOL fImeConfigure = FALSE;
// prevent recursive
if (fImeConfigure) {
// configuration already bring up
return;
}
fImeConfigure = TRUE;
// PopStMenu(hStatusWnd, lpIMC->ptStatusWndPos.x + sImeG.xStatusWi,
// lpIMC->ptStatusWndPos.y);
ContextMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
fImeConfigure = FALSE;
} else {
}
return;
} else {
SetCursor(LoadCursor(NULL, IDC_SIZEALL));
if (HIWORD(lParam) == WM_LBUTTONDOWN) {
// start drag
SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);
} else {
return;
}
}
SetCapture(hStatusWnd);
SetWindowLong(hStatusWnd, UI_MOVE_XY,
MAKELONG(ptSavCursor.x, ptSavCursor.y));
GetWindowRect(hStatusWnd, &rcWnd);
SetWindowLong(hStatusWnd, UI_MOVE_OFFSET,
MAKELONG(ptSavCursor.x - rcWnd.left, ptSavCursor.y - rcWnd.top));
DrawDragBorder(hStatusWnd, MAKELONG(ptSavCursor.x, ptSavCursor.y),
GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
return;
}
/**********************************************************************/
/* StatusWndProc() */
/**********************************************************************/
//#if defined(UNIIME)
//LRESULT CALLBACK UniStatusWndProc(
// LPINSTDATAL lpInstL,
// LPIMEL lpImeL,
//#else
LRESULT CALLBACK StatusWndProc(
//#endif
HWND hStatusWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_DESTROY:
if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
LONG lTmpCursor, lTmpOffset;
POINT ptCursor;
HWND hUIWnd;
lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
// calculate the org by the offset
lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
ReleaseCapture();
}
DestroyStatusWindow(hStatusWnd);
break;
case WM_SETCURSOR:
StatusSetCursor(
hStatusWnd, lParam);
break;
case WM_MOUSEMOVE:
if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
POINT ptCursor;
DrawDragBorder(hStatusWnd,
GetWindowLong(hStatusWnd, UI_MOVE_XY),
GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
GetCursorPos(&ptCursor);
SetWindowLong(hStatusWnd, UI_MOVE_XY,
MAKELONG(ptCursor.x, ptCursor.y));
DrawDragBorder(hStatusWnd, MAKELONG(ptCursor.x, ptCursor.y),
GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
} else {
return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
}
break;
case WM_LBUTTONUP:
if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
LONG lTmpCursor, lTmpOffset;
POINT ptCursor;
HWND hUIWnd;
lTmpCursor = GetWindowLong(hStatusWnd, UI_MOVE_XY);
// calculate the org by the offset
lTmpOffset = GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
ptCursor.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x;
ptCursor.y = (*(LPPOINTS)&lTmpCursor).y - (*(LPPOINTS)&lTmpOffset).y;
SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
ReleaseCapture();
AdjustStatusBoundary(&ptCursor);
hUIWnd = GetWindow(hStatusWnd, GW_OWNER);
/* SendMessage(GetWindow(hStatusWnd, GW_OWNER), WM_IME_CONTROL,
IMC_SETSTATUSWINDOWPOS, NULL); */
ImmSetStatusWindowPos((HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC),
&ptCursor);
if (lpImeL->wImeStyle == IME_APRS_FIX){ //003
ReInitIme(hStatusWnd,lpImeL->wImeStyle); //#@3
MoveCompCand(GetWindow(hStatusWnd, GW_OWNER));
}
} else {
return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
}
break;
case WM_IME_NOTIFY:
if (wParam == IMN_SETSTATUSWINDOWPOS) {
SetStatusWindowPos(hStatusWnd);
}
break;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hStatusWnd, &ps);
PaintStatusWindow(
hDC,hStatusWnd); //zl
EndPaint(hStatusWnd, &ps);
}
break;
case WM_MOUSEACTIVATE:
return (MA_NOACTIVATE);
default:
return DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
}
return (0L);
}
/**********************************************************************/
/* DrawDragBorder() */
/**********************************************************************/
void PASCAL DrawDragBorder(
HWND hWnd, // window of IME is dragged
LONG lCursorPos, // the cursor position
LONG lCursorOffset) // the offset form cursor to window org
{
HDC hDC;
int cxBorder, cyBorder;
int x, y;
RECT rcWnd;
cxBorder = GetSystemMetrics(SM_CXBORDER); // width of border
cyBorder = GetSystemMetrics(SM_CYBORDER); // height of border
// get cursor position
x = (*(LPPOINTS)&lCursorPos).x;
y = (*(LPPOINTS)&lCursorPos).y;
// calculate the org by the offset
x -= (*(LPPOINTS)&lCursorOffset).x;
y -= (*(LPPOINTS)&lCursorOffset).y;
// check for the min boundary of the display
if (x < sImeG.rcWorkArea.left) {
x = sImeG.rcWorkArea.left;
}
if (y < sImeG.rcWorkArea.top) {
y = sImeG.rcWorkArea.top;
}
// check for the max boundary of the display
GetWindowRect(hWnd, &rcWnd);
if (x + rcWnd.right - rcWnd.left > sImeG.rcWorkArea.right) {
x = sImeG.rcWorkArea.right - (rcWnd.right - rcWnd.left);
}
if (y + rcWnd.bottom - rcWnd.top > sImeG.rcWorkArea.bottom) {
y = sImeG.rcWorkArea.bottom - (rcWnd.bottom - rcWnd.top);
}
// draw the moving track
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
if ( hDC == NULL )
return;
SelectObject(hDC, GetStockObject(GRAY_BRUSH));
// ->
PatBlt(hDC, x, y, rcWnd.right - rcWnd.left - cxBorder, cyBorder,
PATINVERT);
// v
PatBlt(hDC, x, y + cyBorder, cxBorder, rcWnd.bottom - rcWnd.top -
cyBorder, PATINVERT);
// _>
PatBlt(hDC, x + cxBorder, y + rcWnd.bottom - rcWnd.top,
rcWnd.right - rcWnd.left - cxBorder, -cyBorder, PATINVERT);
// v
PatBlt(hDC, x + rcWnd.right - rcWnd.left, y,
- cxBorder, rcWnd.bottom - rcWnd.top - cyBorder, PATINVERT);
DeleteDC(hDC);
return;
}
/**********************************************************************/
/* AdjustStatusBoundary() */
/**********************************************************************/
void PASCAL AdjustStatusBoundary(
LPPOINT lppt)
{
// display boundary check
if (lppt->x < sImeG.rcWorkArea.left) {
lppt->x = sImeG.rcWorkArea.left;
} else if (lppt->x + sImeG.xStatusWi > sImeG.rcWorkArea.right) {
lppt->x = (sImeG.rcWorkArea.right - sImeG.xStatusWi);
}
if (lppt->y < sImeG.rcWorkArea.top) {
lppt->y = sImeG.rcWorkArea.top;
} else if (lppt->y + sImeG.yStatusHi > sImeG.rcWorkArea.bottom) {
lppt->y = (sImeG.rcWorkArea.bottom - sImeG.yStatusHi);
}
return;
}
/**********************************************************************/
/* ContextMenuWndProc() */
/**********************************************************************/
LRESULT CALLBACK ContextMenuWndProc(
HWND hCMenuWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg) {
case WM_DESTROY:
{
HWND hUIWnd;
hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
if (hUIWnd) {
SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE,
IMN_PRIVATE_CMENUDESTROYED);
}
break;
}
case WM_USER_DESTROY:
{
SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
DestroyWindow(hCMenuWnd);
break;
}
case WM_COMMAND:
{
HWND hUIWnd;
hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
CommandProc(wParam , GetStatusWnd(hUIWnd));
break;
}
// switch (wParam) {
/*
case IDM_SOFTKBD:
case IDM_SYMBOL:
{
HWND hUIWnd;
HIMC hIMC;
DWORD fdwConversion;
DWORD fdwSentence;
hUIWnd = (HWND)GetWindowLongPtr(hCMenuWnd, CMENU_HUIWND);
hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
ImmGetConversionStatus(hIMC, &fdwConversion,
&fdwSentence);
if (wParam == IDM_SOFTKBD) {
ImmSetConversionStatus(hIMC, fdwConversion ^
IME_CMODE_SOFTKBD, fdwSentence);
}
if (wParam == IDM_SYMBOL) {
ImmSetConversionStatus(hIMC, fdwConversion ^
IME_CMODE_SYMBOL, fdwSentence);
}
SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
}
break;
case IDM_PROPERTIES:
ImeConfigure(GetKeyboardLayout(0), hCMenuWnd,
IME_CONFIG_GENERAL, NULL);
SendMessage(hCMenuWnd, WM_CLOSE, 0, 0);
break; */
// default:
// return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
// }
// break;
case WM_CLOSE:
{
HMENU hMenu;
GetMenu(hCMenuWnd);
hMenu = (HMENU)GetWindowLongPtr(hCMenuWnd, CMENU_MENU);
if (hMenu) {
SetWindowLongPtr(hCMenuWnd, CMENU_MENU, (LONG_PTR)NULL);
DestroyMenu(hMenu);
}
}
return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
default:
return DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
}
return (0L);
}
/**********************************************************************/
/* DestroyUIWindow() */
/**********************************************************************/
void PASCAL DestroyUIWindow( // destroy composition window
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // Oh! Oh!
return;
}
if (lpUIPrivate->hCMenuWnd) {
SetWindowLongPtr(lpUIPrivate->hCMenuWnd, CMENU_HUIWND,(LONG_PTR)0);
PostMessage(lpUIPrivate->hCMenuWnd, WM_USER_DESTROY, 0, 0);
}
// composition window need to be destroyed
if (lpUIPrivate->hCompWnd) {
DestroyWindow(lpUIPrivate->hCompWnd);
}
// candidate window need to be destroyed
if (lpUIPrivate->hCandWnd) {
DestroyWindow(lpUIPrivate->hCandWnd);
}
// status window need to be destroyed
if (lpUIPrivate->hStatusWnd) {
DestroyWindow(lpUIPrivate->hStatusWnd);
}
// soft keyboard window need to be destroyed
if (lpUIPrivate->hSoftKbdWnd) {
ImmDestroySoftKeyboard(lpUIPrivate->hSoftKbdWnd);
}
GlobalUnlock(hUIPrivate);
// free storage for UI settings
GlobalFree(hUIPrivate);
return;
}
/**********************************************************************/
/* CMenuDestryed() */
/**********************************************************************/
void PASCAL CMenuDestroyed( // context menu window
// already destroyed
HWND hUIWnd)
{
HGLOBAL hUIPrivate;
LPUIPRIV lpUIPrivate;
hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE);
if (!hUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate);
if (!lpUIPrivate) { // Oh! Oh!
return;
}
lpUIPrivate->hCMenuWnd = NULL;
GlobalUnlock(hUIPrivate);
}