You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
9733 lines
312 KiB
9733 lines
312 KiB
|
|
/*************************************************
|
|
* 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);
|
|
}
|
|
|
|
INT_PTR CALLBACK 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[]="离离原上草一岁一枯荣";
|
|
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, "离", 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);
|
|
}
|