/************************************************* * abc95ui.c * * * * Copyright (C) 1995-1999 Microsoft Inc. * * * *************************************************/ #include #include #include #include #include #include #include #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 | * //* ||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; i0xa0){ for (i =0; i0; i=i-2) { //xx =sImeG.xChiCharWi*i/2; xx=GetText32(hDC,&InputBuffer[0],i); if ( xx <= lpImeL->rcCompText.right-4) break; } i=0; cur_start_ps=0; cur_start_count=0; }else { for (i =now_cs; i>0; i--){ yy=GetText32(hDC, &InputBuffer[i-1], 1); if ( (xx+yy) >= (lpImeL->rcCompText.right-4)) break; else xx+=yy; } cur_start_count=(WORD)i; cur_start_ps=(WORD)GetText32(hDC, &InputBuffer[0], i); // true_len = StrLen-cur_start_count ; } for(i=StrLen-cur_start_count; i>0; i--){ yy=GetText32(hDC,&InputBuffer[cur_start_count],i); if (yy <= lpImeL->rcCompText.right-4) break; } { LOGFONT lfFont; HGDIOBJ hOldFont; int Top = 2; if (sImeG.yChiCharHi > 0x10) Top = 0; hOldFont = GetCurrentObject(hDC, OBJ_FONT); GetObject(hOldFont, sizeof(lfFont), &lfFont); lfFont.lfWeight = FW_DONTCARE; SelectObject(hDC, CreateFontIndirect(&lfFont)); ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top + Top, ETO_OPAQUE, &lpImeL->rcCompText, &InputBuffer[cur_start_count], i, NULL); DeleteObject(SelectObject(hDC, hOldFont)); } // TextOut(hDC,0,0,&InputBuffer[cur_start_count], // (sizeof InputBuffer)-cur_start_count); now_cs_dot = xx; cur_hibit=0,cur_flag=0; return; } /**********************************************************************/ /* UpdateCompWindow2() */ /**********************************************************************/ void PASCAL UpdateCompWindow2( HWND hUIWnd, HDC hDC) { HIMC hIMC; LPINPUTCONTEXT lpIMC; LPCOMPOSITIONSTRING lpCompStr; LPGUIDELINE lpGuideLine; BOOL fShowString; LOGFONT lfFont; HGDIOBJ hOldFont; hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { return; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine); hOldFont = GetCurrentObject(hDC, OBJ_FONT); GetObject(hOldFont, sizeof(lfFont), &lfFont); lfFont.lfWeight = FW_DONTCARE; SelectObject(hDC, CreateFontIndirect(&lfFont)); SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0)); fShowString = (BOOL)0; if (lpImeL->wImeStyle == IME_APRS_FIX){ RECT rcSunken; DrawConvexRect(hDC, 0, 0, lpImeL->xCompWi-1, lpImeL->yCompHi-1); rcSunken.left =0; rcSunken.top =0; rcSunken.right =lpImeL->xCompWi-1; rcSunken.bottom = lpImeL->yCompHi-1; // DrawEdge(hDC, &rcSunken, EDGE_RAISED,/*EDGE_SUNKEN,*/ BF_RECT); }else DrawConvexRect(hDC, 0, 0, lpImeL->xCompWi-1, lpImeL->yCompHi-1); /* DrawConvexRect(hDC, lpImeL->rcCompText.left-4, lpImeL->rcCompText.top-4, lpImeL->rcCompText.right+4, lpImeL->rcCompText.bottom+4); */ /* DrawConcaveRect(hDC, lpImeL->rcCompText.left-1, lpImeL->rcCompText.top-1, lpImeL->rcCompText.right+1, lpImeL->rcCompText.bottom+1); */ if (!lpGuideLine) { } else if (lpGuideLine->dwLevel == GL_LEVEL_NOGUIDELINE) { } else if (!lpGuideLine->dwStrLen) { if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) { fShowString |= IME_STR_ERROR; } } else { // if there is information string, we will show the information // string if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) { // red text for error SetTextColor(hDC, RGB(0xFF, 0, 0)); // light gray background for error SetBkColor(hDC, QIANHUI); } ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top, ETO_OPAQUE, &lpImeL->rcCompText, (LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset, (UINT)lpGuideLine->dwStrLen, NULL); fShowString |= IME_STR_SHOWED; } if (fShowString & IME_STR_SHOWED) { // already show it, don't need to show } else if (lpCompStr) { // ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top, // ETO_OPAQUE, &lpImeL->rcCompText, // (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset, // (UINT)lpCompStr->dwCompStrLen, NULL); CurMovePaint(hDC, (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset, (UINT)lpCompStr->dwCompStrLen); if (fShowString & IME_STR_ERROR) { // red text for error SetTextColor(hDC, RGB(0xFF, 0, 0)); // light gray background for error SetBkColor(hDC, QIANHUI); ExtTextOut(hDC, lpImeL->rcCompText.left + lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2, lpImeL->rcCompText.top, ETO_CLIPPED, &lpImeL->rcCompText, (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + lpCompStr->dwCursorPos, (UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL); } else if (lpCompStr->dwCursorPos < lpCompStr->dwCompStrLen) { // light gray background for cursor start SetBkColor(hDC, QIANHUI); ExtTextOut(hDC, lpImeL->rcCompText.left + lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2, lpImeL->rcCompText.top, ETO_CLIPPED, &lpImeL->rcCompText, (LPSTR)lpCompStr + lpCompStr->dwCompStrOffset + lpCompStr->dwCursorPos, (UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL); } else { } } else { ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top, ETO_OPAQUE, &lpImeL->rcCompText, (LPSTR)NULL, 0, NULL); } DeleteObject(SelectObject(hDC, hOldFont)); ImmUnlockIMCC(lpIMC->hGuideLine); ImmUnlockIMCC(lpIMC->hCompStr); ImmUnlockIMC(hIMC); return; } /**********************************************************************/ /* UpdateCompWindow() */ /**********************************************************************/ void PASCAL UpdateCompWindow( HWND hUIWnd) { HWND hCompWnd; HDC hDC; hCompWnd = GetCompWnd(hUIWnd); if (!hCompWnd) return ; //Modify 95/7.1 hDC = GetDC(hCompWnd); UpdateCompWindow2(hUIWnd, hDC); ReleaseDC(hCompWnd, hDC); } /**********************************************************************/ /* UpdateCompCur() */ /**********************************************************************/ void PASCAL UpdateCompCur( HWND hCompWnd) { HDC hDC; int yy,i; HGDIOBJ hOldFont; LOGFONT lfFont; cur_hibit=1; if (!hCompWnd) return ; //Modify 95/7.1 hDC = GetDC(hCompWnd); hOldFont = GetCurrentObject(hDC, OBJ_FONT); GetObject(hOldFont, sizeof(lfFont), &lfFont); lfFont.lfWeight = FW_DONTCARE; SelectObject(hDC, CreateFontIndirect(&lfFont)); SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0)); for (i =43-cur_start_count; i>0; i--){ yy=GetText32(hDC, &InputBuffer[cur_start_count], i); if ( yy < lpImeL->rcCompText.right-4) break; } ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top, ETO_OPAQUE, &lpImeL->rcCompText, &InputBuffer[cur_start_count], i, NULL); DeleteObject(SelectObject(hDC, hOldFont)); ReleaseDC(hCompWnd, hDC); cur_hibit=0,cur_flag=0; return ; } /**********************************************************************/ /* PaintCompWindow() */ /**********************************************************************/ void PASCAL PaintCompWindow( // get WM_PAINT message HWND hCompWnd) { HDC hDC; PAINTSTRUCT ps; RECT pt; if(CompWndChange){ CompWndChange = 0; SetCompWindow(GetWindow(hCompWnd,GW_OWNER)); }; cur_hibit=1; hDC = BeginPaint(hCompWnd, &ps); UpdateCompWindow2(GetWindow(hCompWnd, GW_OWNER), hDC); EndPaint(hCompWnd, &ps); cur_hibit=0,cur_flag=0; return; } /**********************************************************************/ /* CompWndProc() */ /**********************************************************************/ LRESULT CALLBACK CompWndProc( // composition window proc HWND hCompWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HDC hDC; switch (uMsg) { case WM_CREATE: hDC=GetDC(hCompWnd); hMemoryDC=CreateCompatibleDC(hDC); cur_h=LoadBitmap(hInst,CUR_HB); ReleaseDC(hCompWnd,hDC); SetTimer(hCompWnd ,1,400,(TIMERPROC)NULL); ShowCandTimerCount=0; break; case WM_TIMER: hInputWnd = hCompWnd; TimerCounter++; ShowCandTimerCount++; if (TimerCounter==3){ TimerCounter=0; } if (!kb_flag) return(0); if (cur_hibit||(cap_mode&&(!cur_flag))) return(0); DrawInputCur(); break; case WM_DESTROY: KillTimer(hCompWnd,1); DeleteObject(cur_h); DeleteObject(hMemoryDC); DestroyCompWindow(hCompWnd); break; case WM_SETCURSOR: CompSetCursor(hCompWnd, lParam); break; case WM_MOUSEMOVE: if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) { if(lpImeL->wImeStyle == IME_APRS_AUTO){ POINT ptCursor; DrawDragBorder(hCompWnd, GetWindowLong(hCompWnd, UI_MOVE_XY), GetWindowLong(hCompWnd, UI_MOVE_OFFSET)); GetCursorPos(&ptCursor); SetWindowLong(hCompWnd, UI_MOVE_XY, MAKELONG(ptCursor.x, ptCursor.y)); DrawDragBorder(hCompWnd, MAKELONG(ptCursor.x, ptCursor.y), GetWindowLong(hCompWnd, UI_MOVE_OFFSET)); }else MessageBeep(0); } else { return DefWindowProc(hCompWnd, uMsg, wParam, lParam); } break; case WM_LBUTTONUP: if (!CompButtonUp(hCompWnd)) { return DefWindowProc(hCompWnd, uMsg, wParam, lParam); } break; case WM_SHOWWINDOW: if (wParam) cur_hibit = 0; else cur_hibit = 1; break; case WM_PAINT: if (wParam == 0xa ) UpdateCompCur(hCompWnd); else PaintCompWindow(hCompWnd); break; case WM_MOUSEACTIVATE: return (MA_NOACTIVATE); default: return DefWindowProc(hCompWnd, uMsg, wParam, lParam); } return (0L); } /**********************************************************************/ /* GetCandWnd */ /* Return Value : */ /* window handle of candidatte */ /**********************************************************************/ HWND PASCAL GetCandWnd( HWND hUIWnd) // UI window { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; HWND hCandWnd; hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { // can not darw candidate window return (HWND)NULL; } lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw candidate window return (HWND)NULL; } hCandWnd = lpUIPrivate->hCandWnd; GlobalUnlock(hUIPrivate); return (hCandWnd); } /**********************************************************************/ /* CalcCandPos */ /**********************************************************************/ void PASCAL CalcCandPos2( LPPOINT lpptWnd) // the composition window position { POINT ptNew; ptNew.x = lpptWnd->x + UI_MARGIN * 2; if (ptNew.x + sImeG.xCandWi > sImeG.rcWorkArea.right) { // exceed screen width ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN * 2; } ptNew.y = lpptWnd->y;// + lpImeL->cyCompBorder - sImeG.cyCandBorder; if (ptNew.y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) { // exceed screen high ptNew.y = sImeG.rcWorkArea.bottom - sImeG.yCandHi; } lpptWnd->x = ptNew.x; lpptWnd->y = ptNew.y; return; } /**********************************************************************/ /* CalcCandPos */ /**********************************************************************/ BOOL PASCAL CalcCandPos( LPPOINT lpptWnd) // the composition window position { POINT ptNew; ptNew.x = lpptWnd->x + lpImeL->xCompWi + UI_MARGIN * 2; if (ptNew.x + sImeG.xCandWi > sImeG.rcWorkArea.right) { // exceed screen width ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN * 2; } ptNew.y = lpptWnd->y;// + lpImeL->cyCompBorder - sImeG.cyCandBorder; if (ptNew.y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) { // exceed screen high ptNew.y = sImeG.rcWorkArea.bottom - sImeG.yCandHi; } lpptWnd->x = ptNew.x; lpptWnd->y = ptNew.y; return 0; } /**********************************************************************/ /* AdjustCandBoundry */ /**********************************************************************/ void PASCAL AdjustCandBoundry( LPPOINT lpptCandWnd) // the position { if (lpptCandWnd->x < sImeG.rcWorkArea.left) { lpptCandWnd->x = sImeG.rcWorkArea.left; } else if (lpptCandWnd->x + sImeG.xCandWi > sImeG.rcWorkArea.right) { lpptCandWnd->x = sImeG.rcWorkArea.right - sImeG.xCandWi; } if (lpptCandWnd->y < sImeG.rcWorkArea.top) { lpptCandWnd->y = sImeG.rcWorkArea.top; } else if (lpptCandWnd->y + sImeG.yCandHi > sImeG.rcWorkArea.bottom) { lpptCandWnd->y = sImeG.rcWorkArea.bottom - sImeG.yCandHi; } return; } /**********************************************************************/ /* GetCandPos() */ /**********************************************************************/ LRESULT PASCAL GetCandPos( HWND hUIWnd, LPCANDIDATEFORM lpCandForm) { HWND hCandWnd; HIMC hIMC; LPINPUTCONTEXT lpIMC; POINT ptNew; //DebugShow("GetCand...%x",hUIWnd); hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { return (1L); } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return (1L); } if (!(hCandWnd = GetCandWnd(hUIWnd))) { return (1L); } if (lpCandForm->dwStyle & CFS_FORCE_POSITION) { ptNew.x = (int)lpCandForm->ptCurrentPos.x; ptNew.y = (int)lpCandForm->ptCurrentPos.y; } else if (lpCandForm->dwStyle & CFS_CANDIDATEPOS) { ptNew.x = (int)lpCandForm->ptCurrentPos.x; ptNew.y = (int)lpCandForm->ptCurrentPos.y; } else if (lpCandForm->dwStyle & CFS_EXCLUDE) { ptNew.x = (int)lpCandForm->ptCurrentPos.x; ptNew.y = (int)lpCandForm->ptCurrentPos.y; } ImmUnlockIMC(hIMC); return (0L); } /**********************************************************************/ /* SetCandPosition() */ /**********************************************************************/ LRESULT PASCAL SetCandPosition( HWND hUIWnd, LPCANDIDATEFORM lpCandForm) { HWND hCandWnd; HIMC hIMC; LPINPUTCONTEXT lpIMC; POINT ptNew; // DebugShow("SetCand...%x",hUIWnd); hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { return (1L); } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return (1L); } if (!(hCandWnd = GetCandWnd(hUIWnd))) { return (1L); } if (lpCandForm->dwStyle & CFS_FORCE_POSITION) { ptNew.x = (int)lpCandForm->ptCurrentPos.x; ptNew.y = (int)lpCandForm->ptCurrentPos.y; ClientToScreen((HWND)lpIMC->hWnd, &ptNew); //##4 SetWindowPos(hCandWnd, NULL, ptNew.x, ptNew.y, sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER); } else if (lpCandForm->dwStyle & CFS_CANDIDATEPOS) { ptNew.x = (int)lpCandForm->ptCurrentPos.x; ptNew.y = (int)lpCandForm->ptCurrentPos.y; ClientToScreen((HWND)lpIMC->hWnd, &ptNew); AdjustCandBoundry(&ptNew); // ##5 SetWindowPos(hCandWnd, NULL, ptNew.x, ptNew.y, sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER); } else if (lpCandForm->dwStyle & CFS_EXCLUDE) { ptNew.x = (int)lpCandForm->ptCurrentPos.x; ptNew.y = (int)lpCandForm->ptCurrentPos.y; ClientToScreen((HWND)lpIMC->hWnd, &ptNew); AdjustCandBoundry(&ptNew); // ##6 SetWindowPos(hCandWnd, NULL, ptNew.x, ptNew.y, sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER); } else if (lpIMC->cfCandForm[0].dwStyle == CFS_DEFAULT) { HWND hCompWnd; if (hCompWnd = GetCompWnd(hUIWnd)) { ptNew.x = 0; ptNew.y = 0; ClientToScreen(hCompWnd, &ptNew); CalcCandPos(&ptNew); } else { AdjustCandBoundry(&ptNew); } SetWindowPos(hCandWnd, NULL, ptNew.x, ptNew.y, sImeG.xCandWi,sImeG.yCandHi, SWP_NOACTIVATE|/*SWP_NOSIZE|*/SWP_NOZORDER); } ImmUnlockIMC(hIMC); return (0L); } /**********************************************************************/ /* ShowCand() */ /**********************************************************************/ void PASCAL ShowCand( // Show the candidate window HWND hUIWnd, int nShowCandCmd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; // if (ShowCandTimerCount<5) {ShowCandTimerCount = 0; return 0;} // ShowCandTimerCount = 0 ; hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { // can not darw candidate window return; } lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw candidate window return; } if (!lpUIPrivate->hCandWnd) { // not in show candidate window mode } else if (lpUIPrivate->nShowCandCmd != nShowCandCmd) { ShowWindow(lpUIPrivate->hCandWnd, nShowCandCmd); lpUIPrivate->nShowCandCmd = nShowCandCmd; } else { } GlobalUnlock(hUIPrivate); return; } /**********************************************************************/ /* OpenCand */ /**********************************************************************/ void PASCAL OpenCand( HWND hUIWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; POINT ptWnd; int value; // DebugShow("In Open Cand",0); hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { // can not darw candidate window return; } lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw candidate window return; } lpUIPrivate->fdwSetContext |= ISC_SHOWUICANDIDATEWINDOW; ptWnd.x = 0; ptWnd.y = 0; // DebugShow("OpenCand ..->hCompWnd=%X",lpUIPrivate); value = ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd); // DebugShow("OpenCand ..value", value); if (!value){ // if there no Comp wndows GetCaretPos(&ptWnd); ClientToScreen(GetFocus(),&ptWnd); CalcCandPos2(&ptWnd); } else { ptWnd.x -= lpImeL->cxCompBorder; // ptWnd.y -= lpImeL->cyCompBorder; CalcCandPos(&ptWnd); } if (lpImeL->wImeStyle == IME_APRS_FIX) { ptWnd.x = lpImeL->ptDefCand.x; ptWnd.y = lpImeL->ptDefCand.y; } // ##7 if (lpUIPrivate->hCandWnd) { SetWindowPos(lpUIPrivate->hCandWnd, NULL, ptWnd.x, ptWnd.y, sImeG.xCandWi, sImeG.yCandHi, SWP_NOACTIVATE/*|SWP_NOSIZE*/|SWP_NOZORDER); } else { lpUIPrivate->hCandWnd = CreateWindowEx( /* WS_EX_TOPMOST*/ /*|*/ /* WS_EX_CLIENTEDGE|WS_EX_WINDOWEDGE/*|WS_EX_DLGMODALFRAME*/ 0, szCandClassName, NULL, WS_POPUP|WS_DISABLED, //|WS_BORDER, ptWnd.x, ptWnd.y, sImeG.xCandWi, sImeG.yCandHi, hUIWnd, (HMENU)NULL, hInst, NULL); if ( lpUIPrivate->hCandWnd ) { SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG); SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_XY, 0L); } } ShowCand(hUIWnd, SW_SHOWNOACTIVATE); GlobalUnlock(hUIPrivate); return; } /**********************************************************************/ /* CloseCand */ /**********************************************************************/ void PASCAL CloseCand( HWND hUIWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; hUIPrivate = (HGLOBAL)GetWindowLongPtr(hUIWnd, IMMGWLP_PRIVATE); if (!hUIPrivate) { // can not darw candidate window return; } lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw candidate window return; } ShowWindow(lpUIPrivate->hCandWnd, SW_HIDE); lpUIPrivate->nShowCandCmd = SW_HIDE; GlobalUnlock(hUIPrivate); return; } /**********************************************************************/ /* DestroyCandWindow */ /**********************************************************************/ void PASCAL DestroyCandWindow( HWND hCandWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; hUIPrivate = (HGLOBAL)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_PRIVATE); if (!hUIPrivate) { // can not darw candidate window return; } lpUIPrivate = (LPUIPRIV)GlobalLock(hUIPrivate); if (!lpUIPrivate) { // can not draw candidate window return; } lpUIPrivate->nShowCandCmd = SW_HIDE; lpUIPrivate->hCandWnd = (HWND)NULL; GlobalUnlock(hUIPrivate); return; } /**********************************************************************/ /* MouseSelectCandStr() */ /**********************************************************************/ void PASCAL MouseSelectCandStr( HWND hCandWnd, LPPOINT lpCursor) { HIMC hIMC; LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; DWORD dwValue, value = 0 ; hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC); if (!hIMC) { return; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } if (!lpIMC->hCandInfo) { ImmUnlockIMC(hIMC); return; } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { ImmUnlockIMC(hIMC); return; } if (PtInRect(&sImeG.rcHome, *lpCursor)) value = VK_HOME*0x100; if (PtInRect(&sImeG.rcEnd, *lpCursor)) value = VK_END*0x100; if (PtInRect(&sImeG.rcPageUp, *lpCursor)) value = VK_PRIOR*0x100; if (PtInRect(&sImeG.rcPageDown, *lpCursor)) value = VK_NEXT*0x100; if (PtInRect(&sImeG.rcCandText, *lpCursor)){ if (lpImeL->wImeStyle == IME_APRS_AUTO ) value = 0x8030 + 1 + (lpCursor->y - sImeG.rcCandText.top) / sImeG.yChiCharHi; else value = 0x8030+1+ (lpCursor->x - sImeG.rcCandText.left)/ (sImeG.xChiCharWi*unit_length/2+ sImeG.Ajust); } if(value) { LPPRIVCONTEXT lpImcP; lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); lpImcP->fdwImeMsg =lpImcP->fdwImeMsg & ~MSG_IN_IMETOASCIIEX; ImmUnlockIMCC(lpIMC->hPrivate); NotifyIME(hIMC, NI_SELECTCANDIDATESTR, 0, value); } ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; } /**********************************************************************/ /* CandSetCursor() */ /**********************************************************************/ void PASCAL CandSetCursor( HWND hCandWnd, LPARAM lParam) { POINT ptCursor; RECT rcWnd; if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) { SetCursor(LoadCursor(NULL, IDC_SIZEALL)); return; } if (HIWORD(lParam) == WM_LBUTTONDOWN) { SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0); GetCursorPos(&ptCursor); ScreenToClient(hCandWnd, &ptCursor); if (PtInRect(&sImeG.rcCandText, ptCursor)|| PtInRect(&sImeG.rcHome, ptCursor)|| PtInRect(&sImeG.rcEnd, ptCursor)|| PtInRect(&sImeG.rcPageUp, ptCursor)|| PtInRect(&sImeG.rcPageDown, ptCursor)) { SetCursor(LoadCursor(hInst, szHandCursor)); MouseSelectCandStr(hCandWnd, &ptCursor); return; } else { SetCursor(LoadCursor(NULL, IDC_SIZEALL)); } } else { GetCursorPos(&ptCursor); ScreenToClient(hCandWnd, &ptCursor); if (PtInRect(&sImeG.rcCandText, ptCursor)|| PtInRect(&sImeG.rcHome, ptCursor)|| PtInRect(&sImeG.rcEnd, ptCursor)|| PtInRect(&sImeG.rcPageUp, ptCursor)|| PtInRect(&sImeG.rcPageDown, ptCursor)) { SetCursor(LoadCursor(hInst, szHandCursor)); } else { SetCursor(LoadCursor(NULL, IDC_SIZEALL)); } return; } SetCapture(hCandWnd); GetCursorPos(&ptCursor); SetWindowLong(hCandWnd, UI_MOVE_XY, MAKELONG(ptCursor.x, ptCursor.y)); GetWindowRect(hCandWnd, &rcWnd); SetWindowLong(hCandWnd, UI_MOVE_OFFSET, MAKELONG(ptCursor.x - rcWnd.left, ptCursor.y - rcWnd.top)); DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y), GetWindowLong(hCandWnd, UI_MOVE_OFFSET)); return; } /**********************************************************************/ /* CandButtonUp() */ /**********************************************************************/ BOOL PASCAL CandButtonUp( HWND hCandWnd) { LONG lTmpCursor, lTmpOffset; POINT pt; HWND hUIWnd; HIMC hIMC; LPINPUTCONTEXT lpIMC; HWND hFocusWnd; CANDIDATEFORM cfCandForm; if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) { return (FALSE); } lTmpCursor = GetWindowLong(hCandWnd, UI_MOVE_XY); pt.x = (*(LPPOINTS)&lTmpCursor).x; pt.y = (*(LPPOINTS)&lTmpCursor).y; // calculate the org by the offset lTmpOffset = GetWindowLong(hCandWnd, UI_MOVE_OFFSET); pt.x -= (*(LPPOINTS)&lTmpOffset).x; pt.y -= (*(LPPOINTS)&lTmpOffset).y; DrawDragBorder(hCandWnd, lTmpCursor, lTmpOffset); SetWindowLong(hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG); ReleaseCapture(); hUIWnd = GetWindow(hCandWnd, GW_OWNER); hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { return (FALSE); } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return (FALSE); } hFocusWnd = lpIMC->hWnd; ImmUnlockIMC(hIMC); AdjustCandBoundry(&pt); ScreenToClient(hFocusWnd, &pt); cfCandForm.dwStyle = CFS_CANDIDATEPOS; cfCandForm.ptCurrentPos.x = pt.x; cfCandForm.ptCurrentPos.y = pt.y; SendMessage(hUIWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, (LPARAM)&cfCandForm); return (TRUE); } /**********************************************************************/ /* PaintOP() */ /**********************************************************************/ void PASCAL PaintOP( HDC hDC, HWND hWnd) { RECT rcSunken; int x1,y1,x2,y2; rcSunken = sImeG.rcCandText; x1=rcSunken.left-2; y1=rcSunken.top-1;//2; x2=rcSunken.right+7; y2=rcSunken.bottom+5; rcSunken.left =x1; rcSunken.top =y1; rcSunken.right =x2; rcSunken.bottom = y2; // ShowBitmap(hDC,x2-50,y2,49,20, szUpDown); if(lpImeL->wImeStyle == IME_APRS_AUTO ){ DrawConvexRect(hDC,0,0,sImeG.xCandWi-1, sImeG.yCandHi-1); // DrawConcaveRect(hDC ,x1,y1,x2,y2); if(bx_inpt_on){ ShowBitmap2(hDC, sImeG.xCandWi/2-25, sImeG.rcHome.top, 50, 15, sImeG.SnumbBmp); }else { ShowBitmap2(hDC, sImeG.xCandWi/2-25, sImeG.rcHome.top, 50, 15, sImeG.NumbBmp); } ShowBitmap2(hDC, sImeG.rcHome.left, sImeG.rcHome.top, 14, 14, sImeG.HomeBmp); ShowBitmap2(hDC, sImeG.rcEnd.left, sImeG.rcEnd.top, 14, 14, sImeG.EndBmp); ShowBitmap2(hDC, sImeG.rcPageUp.left, sImeG.rcPageUp.top, 14, 14, sImeG.PageUpBmp); ShowBitmap2(hDC, sImeG.rcPageDown.left, sImeG.rcPageDown.top, 14, 14, sImeG.PageDownBmp); }else{ ShowBitmap2(hDC, sImeG.rcHome.left, sImeG.rcHome.top, 14, 14, sImeG.Home2Bmp); ShowBitmap2(hDC, sImeG.rcEnd.left, sImeG.rcEnd.top, 14, 14, sImeG.End2Bmp); ShowBitmap2(hDC, sImeG.rcPageUp.left, sImeG.rcPageUp.top, 14, 14, sImeG.PageUp2Bmp); ShowBitmap2(hDC, sImeG.rcPageDown.left, sImeG.rcPageDown.top, 14, 14, sImeG.PgDown2Bmp); } return ; } int keep =9; /**********************************************************************/ /* UpdateCandWindow() */ /**********************************************************************/ void PASCAL UpdateCandWindow2( HWND hCandWnd, HDC hDC) { HIMC hIMC; LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; LPPRIVCONTEXT lpImcP; DWORD dwStart, dwEnd; TCHAR szStrBuf[30* sizeof(WCHAR) / sizeof(TCHAR)]; int i , LenOfAll; HGDIOBJ hOldFont; LOGFONT lfFont; hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC); if (!hIMC) { return; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } if (!lpIMC->hCandInfo) { ImmUnlockIMC(hIMC); return ; } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { ImmUnlockIMC(hIMC); return ; } if (!lpIMC->hPrivate) { ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; } lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); if (!lpImcP) { ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; } lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); if(lpImeL->wImeStyle == IME_APRS_FIX) lpCandList->dwPageSize = now.fmt_group; else lpCandList->dwPageSize = CANDPERPAGE ; if (!lpCandList->dwPageSize) lpCandList->dwPageSize = keep; keep = lpCandList->dwPageSize; dwStart = lpCandList->dwSelection / lpCandList->dwPageSize * lpCandList->dwPageSize; dwEnd = dwStart + lpCandList->dwPageSize; if (dwEnd > lpCandList->dwCount) { dwEnd = lpCandList->dwCount; } hOldFont = GetCurrentObject(hDC, OBJ_FONT); GetObject(hOldFont, sizeof(lfFont), &lfFont); lfFont.lfWeight = FW_DONTCARE; SelectObject(hDC, CreateFontIndirect(&lfFont)); if(lpImeL->wImeStyle != IME_APRS_FIX){ PaintOP(hDC,hCandWnd); if (lpImcP->iImeState == CST_INIT) { // phrase prediction SetTextColor(hDC, RGB(0x00, 0x80, 0x00)); } else if (lpImcP->iImeState != CST_CHOOSE) { // quick key SetTextColor(hDC, RGB(0x80, 0x00, 0x80)); } else { } SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0)); sImeG.rcCandText.bottom+=3; ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top, ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL); sImeG.rcCandText.bottom-=3; szStrBuf[0] = '1'; szStrBuf[1] = ':'; for (i = 0; dwStart < dwEnd; dwStart++, i++) { int iLen; szStrBuf[0] = szDigit[i + CAND_START]; iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])); // according to init.c, 7 DBCS char if (iLen > 6 * sizeof(WCHAR) / sizeof(TCHAR)) { iLen = 6 * sizeof(WCHAR) / sizeof(TCHAR); CopyMemory(&szStrBuf[2], ((LPBYTE)lpCandList+lpCandList->dwOffset[dwStart]), iLen * sizeof(TCHAR) - sizeof(TCHAR) * 2); // maybe not good for UNICODE szStrBuf[iLen] = '.'; szStrBuf[iLen + 1] = '.'; } else { CopyMemory(&szStrBuf[2], ((LPBYTE)lpCandList+lpCandList->dwOffset[dwStart]), iLen); } ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top + i * sImeG.yChiCharHi, (UINT)0, NULL, szStrBuf, iLen + 2, NULL); } } else { PaintOP(hDC,hCandWnd); SetTextColor(hDC, RGB(0xa0, 0x00, 0x80)); SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0)); ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top, ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL); szStrBuf[0] = '1'; szStrBuf[1] = ':'; LenOfAll = 0; for (i = 0; dwStart < dwEnd; dwStart++, i++) { int iLen; szStrBuf[LenOfAll++] = szDigit[i + CAND_START]; szStrBuf[LenOfAll++] = '.' ; iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])); CopyMemory(&szStrBuf[LenOfAll], ((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]), iLen); LenOfAll += iLen; szStrBuf[LenOfAll] = '.'; szStrBuf[LenOfAll] = '.'; } DrawConvexRect(hDC,0,0,sImeG.xCandWi-1,sImeG.yCandHi-1); //zl PaintOP(hDC,hCandWnd); { int TopOfText = 2; if (sImeG.yChiCharHi >0x10) TopOfText = 0; ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top + TopOfText, (UINT)0, NULL, szStrBuf, LenOfAll, NULL); } } DeleteObject(SelectObject(hDC, hOldFont)); ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; } /**********************************************************************/ /* PaintCandWindow() */ /**********************************************************************/ void PASCAL PaintCandWindow( // handle WM_PAINT message HWND hCandWnd) { HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hCandWnd, &ps); UpdateCandWindow2(hCandWnd, hDC); EndPaint(hCandWnd, &ps); return; } /**********************************************************************/ /* CandWndProc() */ /**********************************************************************/ LRESULT CALLBACK CandWndProc( HWND hCandWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: sImeG.HomeBmp = LoadBitmap(hInst, szHome); //zl sImeG.EndBmp = LoadBitmap(hInst, szEnd); sImeG.PageUpBmp = LoadBitmap(hInst, szPageUp); sImeG.PageDownBmp = LoadBitmap(hInst, szPageDown); sImeG.NumbBmp = LoadBitmap(hInst, szNumb); sImeG.SnumbBmp = LoadBitmap(hInst, szSnumb); sImeG.Home2Bmp = LoadBitmap(hInst, szHome2); sImeG.End2Bmp = LoadBitmap(hInst, szEnd2); sImeG.PageUp2Bmp = LoadBitmap(hInst, szPageUp2); sImeG.PgDown2Bmp = LoadBitmap(hInst, szPgDown2); break; case WM_DESTROY: DeleteObject(sImeG.HomeBmp); DeleteObject(sImeG.EndBmp); DeleteObject(sImeG.PageUpBmp); DeleteObject(sImeG.PageDownBmp); DeleteObject(sImeG.NumbBmp ); DeleteObject(sImeG.SnumbBmp ); DeleteObject(sImeG.Home2Bmp); DeleteObject(sImeG.End2Bmp); DeleteObject(sImeG.PageUp2Bmp); DeleteObject(sImeG.PgDown2Bmp); DestroyCandWindow(hCandWnd); break; case WM_SETCURSOR: CandSetCursor(hCandWnd, lParam); break; case WM_MOUSEMOVE: if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) { POINT ptCursor; if (lpImeL->wImeStyle == IME_APRS_AUTO){ DrawDragBorder(hCandWnd, GetWindowLong(hCandWnd, UI_MOVE_XY), GetWindowLong(hCandWnd, UI_MOVE_OFFSET)); GetCursorPos(&ptCursor); SetWindowLong(hCandWnd, UI_MOVE_XY, MAKELONG(ptCursor.x, ptCursor.y)); DrawDragBorder(hCandWnd, MAKELONG(ptCursor.x, ptCursor.y), GetWindowLong(hCandWnd, UI_MOVE_OFFSET)); }else MessageBeep(0); } else { return DefWindowProc(hCandWnd, uMsg, wParam, lParam); } break; case WM_LBUTTONUP: if (!CandButtonUp(hCandWnd)) { return DefWindowProc(hCandWnd, uMsg, wParam, lParam); } break; case WM_PAINT: InvalidateRect(hCandWnd,0,1); PaintCandWindow(hCandWnd); break; case WM_MOUSEACTIVATE: return (MA_NOACTIVATE); /* case WM_IME_NOTIFY: if (wParam != IMN_SETCANDIDATEPOS) { } else if (lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI) { } else if (lParam & 0x0001) { return SetCandPosition(hCandWnd); } else { } break;*/ default: return DefWindowProc(hCandWnd, uMsg, wParam, lParam); } return (0L); } /**********************************************************************/ /* ImeInquire() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL WINAPI ImeInquire( // initialized data structure of IME LPIMEINFO lpImeInfo, // IME specific data report to IMM LPTSTR lpszWndCls, // the class name of UI DWORD dwSystemInfoFlags) { if (!lpImeInfo) { return (FALSE); } lpImeInfo->dwPrivateDataSize = sizeof(PRIVCONTEXT); lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST|IME_PROP_IGNORE_UPKEYS|IME_PROP_CANDLIST_START_FROM_1; lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE|IME_CMODE_FULLSHAPE| /* IME_CMODE_CHARCODE|*/IME_CMODE_SOFTKBD|IME_CMODE_NOCONVERSION/*| IME_CMODE_EUDC*/; lpImeInfo->fdwSentenceCaps = TRUE; // IME will have different distance base multiple of 900 escapement lpImeInfo->fdwUICaps = UI_CAP_ROT90|UI_CAP_SOFTKBD; // composition string is the reading string for simple IME lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR|SCS_CAP_MAKEREAD; // IME want to decide conversion mode on ImeSelect lpImeInfo->fdwSelectCaps = (DWORD)0; lstrcpy(lpszWndCls, (LPSTR)szUIClassName); if ( lpImeL ) { if ( dwSystemInfoFlags & IME_SYSINFO_WINLOGON ) { // the client app is running in logon mode. lpImeL->fWinLogon = TRUE; } else lpImeL->fWinLogon = FALSE; } return (TRUE); } BOOL FAR PASCAL ConfigDlgProc( // dialog procedure of configuration HWND hDlg, UINT uMessage, WORD wParam, LONG lParam) { return (TRUE); } /**********************************************************************/ /* ImeConfigure() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL WINAPI ImeConfigure( // configurate the IME setting HKL hKL, // hKL of this IME HWND hAppWnd, // the owner window DWORD dwMode, LPVOID lpData) // mode of dialog { switch (dwMode) { case IME_CONFIG_GENERAL: DoPropertySheet(hAppWnd,NULL); ReInitIme(hAppWnd,lpImeL->wImeStyle); //#@1 break; default: return (FALSE); break; } return (TRUE); } /**********************************************************************/ /* ImeConversionList() */ /**********************************************************************/ DWORD WINAPI ImeConversionList( HIMC hIMC, LPCTSTR lpszSrc, LPCANDIDATELIST lpCandList, DWORD uBufLen, UINT uFlag) { return (UINT)0; } /**********************************************************************/ /* ImeDestroy() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL WINAPI ImeDestroy( // this dll is unloaded UINT uReserved) { if (uReserved) { return (FALSE); } // free the IME table or data base // FreeTable(); return (TRUE); } /**********************************************************************/ /* SetPrivateSetting() */ /**********************************************************************/ void PASCAL SetPrivateFileSetting( LPBYTE szBuf, int cbBuf, DWORD dwOffset, LPCTSTR szSettingFile) // file for IME private related settings { TCHAR szSettingPath[MAX_PATH]; UINT uLen; HANDLE hSettingFile; DWORD dwWriteByte; return; } /**********************************************************************/ /* Input2Sequence */ /* Return Value: */ /* LOWORD - Internal Code, HIWORD - sequence code */ /**********************************************************************/ LRESULT PASCAL Input2Sequence( DWORD uVirtKey, LPBYTE lpSeqCode) { return 0; } /**********************************************************************/ /* ImeEscape() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ #define IME_INPUTKEYTOSEQUENCE 0x22 LRESULT WINAPI ImeEscape( // escape function of IMEs HIMC hIMC, UINT uSubFunc, LPVOID lpData) { LRESULT lRet; switch (uSubFunc) { case IME_ESC_QUERY_SUPPORT: if ( lpData == NULL ) return FALSE; switch (*(LPUINT)lpData) { case IME_ESC_QUERY_SUPPORT: case IME_ESC_SEQUENCE_TO_INTERNAL: case IME_ESC_GET_EUDC_DICTIONARY: case IME_ESC_SET_EUDC_DICTIONARY: case IME_INPUTKEYTOSEQUENCE: // will not supported in next version // and not support 32 bit applications case IME_ESC_MAX_KEY: case IME_ESC_IME_NAME: case IME_ESC_GETHELPFILENAME: return (TRUE); default: return (FALSE); } break; case IME_ESC_SEQUENCE_TO_INTERNAL: lRet = 0; return (lRet); case IME_ESC_GET_EUDC_DICTIONARY: return (FALSE); case IME_ESC_SET_EUDC_DICTIONARY: return (FALSE); case IME_INPUTKEYTOSEQUENCE: return 0; case IME_ESC_MAX_KEY: return (lpImeL->nMaxKey); case IME_ESC_IME_NAME: { TCHAR szIMEName[MAX_PATH]; if ( lpData == NULL ) return FALSE; LoadString(hInst, IDS_IMENAME, szIMEName, sizeof(szIMEName) ); lstrcpy(lpData, szIMEName); return (TRUE); } case IME_ESC_GETHELPFILENAME: if ( lpData == NULL ) return FALSE; lstrcpy(lpData, TEXT("winabc.hlp") ); return TRUE; default: return (FALSE); } return (lRet); } /**********************************************************************/ /* InitCompStr() */ /**********************************************************************/ void PASCAL InitCompStr( // init setting for composing string LPCOMPOSITIONSTRING lpCompStr) { if (!lpCompStr) { return; } lpCompStr->dwCompReadAttrLen = 0; lpCompStr->dwCompReadClauseLen = 0; lpCompStr->dwCompReadStrLen = 0; lpCompStr->dwCompAttrLen = 0; lpCompStr->dwCompClauseLen = 0; lpCompStr->dwCompStrLen = 0; lpCompStr->dwCursorPos = 0; lpCompStr->dwDeltaStart = 0; lpCompStr->dwResultReadClauseLen = 0; lpCompStr->dwResultReadStrLen = 0; lpCompStr->dwResultClauseLen = 0; lpCompStr->dwResultStrLen = 0; return; } /**********************************************************************/ /* ClearCompStr() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL PASCAL ClearCompStr( LPINPUTCONTEXT lpIMC) { HIMCC hMem; LPCOMPOSITIONSTRING lpCompStr; DWORD dwSize = // header length sizeof(COMPOSITIONSTRING) + // composition reading attribute plus NULL terminator lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE) + // composition reading clause sizeof(DWORD) + sizeof(DWORD) + // composition reading string plus NULL terminator lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) + // result reading clause sizeof(DWORD) + sizeof(DWORD) + // result reading string plus NULL terminateor lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD) + // result clause sizeof(DWORD) + sizeof(DWORD) + // result string plus NULL terminateor MAXSTRLEN * sizeof(WORD) + sizeof(WORD); if (!lpIMC) { return (FALSE); } if (!lpIMC->hCompStr) { // it maybe free by other IME, init it lpIMC->hCompStr = ImmCreateIMCC(dwSize); } else if (hMem = ImmReSizeIMCC(lpIMC->hCompStr, dwSize)) { lpIMC->hCompStr = hMem; } else { ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = ImmCreateIMCC(dwSize); return (FALSE); } if (!lpIMC->hCompStr) { return (FALSE); } lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr); if (!lpCompStr) { ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = ImmCreateIMCC(dwSize); return (FALSE); } lpCompStr->dwSize = dwSize; // 1. composition (reading) string - simple IME // 2. result reading string // 3. result string lpCompStr->dwCompReadAttrLen = 0; lpCompStr->dwCompReadAttrOffset = sizeof(COMPOSITIONSTRING); lpCompStr->dwCompReadClauseLen = 0; lpCompStr->dwCompReadClauseOffset = lpCompStr->dwCompReadAttrOffset + lpImeL->nMaxKey * sizeof(BYTE) + sizeof(BYTE); lpCompStr->dwCompReadStrLen = 0; lpCompStr->dwCompReadStrOffset = lpCompStr->dwCompReadClauseOffset + sizeof(DWORD) + sizeof(DWORD); // composition string is the same with composition reading string // for simple IMEs lpCompStr->dwCompAttrLen = 0; lpCompStr->dwCompAttrOffset = lpCompStr->dwCompReadAttrOffset; lpCompStr->dwCompClauseLen = 0; lpCompStr->dwCompClauseOffset = lpCompStr->dwCompReadClauseOffset; lpCompStr->dwCompStrLen = 0; lpCompStr->dwCompStrOffset = lpCompStr->dwCompReadStrOffset; lpCompStr->dwCursorPos = 0; lpCompStr->dwDeltaStart = 0; lpCompStr->dwResultReadClauseLen = 0; lpCompStr->dwResultReadClauseOffset = lpCompStr->dwCompStrOffset + lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD); lpCompStr->dwResultReadStrLen = 0; lpCompStr->dwResultReadStrOffset = lpCompStr->dwResultReadClauseOffset + sizeof(DWORD) + sizeof(DWORD); lpCompStr->dwResultClauseLen = 0; lpCompStr->dwResultClauseOffset = lpCompStr->dwResultReadStrOffset + lpImeL->nMaxKey * sizeof(WORD) + sizeof(WORD); lpCompStr->dwResultStrOffset = 0; lpCompStr->dwResultStrOffset = lpCompStr->dwResultClauseOffset + sizeof(DWORD) + sizeof(DWORD); GlobalUnlock((HGLOBAL)lpIMC->hCompStr); return (TRUE); } /**********************************************************************/ /* ClearCand() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL PASCAL ClearCand( LPINPUTCONTEXT lpIMC) { HIMCC hMem; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; DWORD dwSize = // header length sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST) + // candidate string pointers sizeof(DWORD) * (MAXCAND) + // string plus NULL terminator (sizeof(WORD) + sizeof(WORD)) * MAXCAND; if (!lpIMC) { return (FALSE); } if (!lpIMC->hCandInfo) { // it maybe free by other IME, init it lpIMC->hCandInfo = ImmCreateIMCC(dwSize); } else if (hMem = ImmReSizeIMCC(lpIMC->hCandInfo, dwSize)) { lpIMC->hCandInfo = hMem; } else { ImmDestroyIMCC(lpIMC->hCandInfo); lpIMC->hCandInfo = ImmCreateIMCC(dwSize); return (FALSE); } if (!lpIMC->hCandInfo) { return (FALSE); } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { ImmDestroyIMCC(lpIMC->hCandInfo); lpIMC->hCandInfo = ImmCreateIMCC(dwSize); return (FALSE); } // ordering of strings are // buffer size lpCandInfo->dwSize = dwSize; lpCandInfo->dwCount = 0; lpCandInfo->dwOffset[0] = sizeof(CANDIDATEINFO); lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); // whole candidate info size - header lpCandList->dwSize = lpCandInfo->dwSize - sizeof(CANDIDATEINFO); lpCandList->dwStyle = IME_CAND_READ; lpCandList->dwCount = 0; lpCandList->dwSelection = 0; lpCandList->dwPageSize = CANDPERPAGE; lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) * (MAXCAND - 1); ImmUnlockIMCC(lpIMC->hCandInfo); return (TRUE); } /**********************************************************************/ /* ClearGuideLine() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL PASCAL ClearGuideLine( LPINPUTCONTEXT lpIMC) { HIMCC hMem; LPGUIDELINE lpGuideLine; DWORD dwSize = sizeof(GUIDELINE) + sImeG.cbStatusErr; if (!lpIMC->hGuideLine) { // it maybe free by IME lpIMC->hGuideLine = ImmCreateIMCC(dwSize); } else if (hMem = ImmReSizeIMCC(lpIMC->hGuideLine, dwSize)) { lpIMC->hGuideLine = hMem; } else { ImmDestroyIMCC(lpIMC->hGuideLine); lpIMC->hGuideLine = ImmCreateIMCC(dwSize); } lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine); if (!lpGuideLine) { return (FALSE); } lpGuideLine->dwSize = dwSize; lpGuideLine->dwLevel = GL_LEVEL_NOGUIDELINE; lpGuideLine->dwIndex = GL_ID_UNKNOWN; lpGuideLine->dwStrLen = 0; lpGuideLine->dwStrOffset = sizeof(GUIDELINE); CopyMemory((LPBYTE)lpGuideLine + lpGuideLine->dwStrOffset, sImeG.szStatusErr, sImeG.cbStatusErr); ImmUnlockIMCC(lpIMC->hGuideLine); return (TRUE); } /**********************************************************************/ /* InitContext() */ /**********************************************************************/ void PASCAL InitContext( LPINPUTCONTEXT lpIMC, LPPRIVCONTEXT lpImcP) { //if (lpIMC->fdwInit & INIT_STATUSWNDPOS) { //} else if (!lpIMC->hWnd) { //} else if (lpImcP->fdwInit & INIT_STATUSWNDPOS) { //} else { if (lpIMC->fdwInit & INIT_STATUSWNDPOS) { } else if (!lpIMC->hWnd) { } else { POINT ptWnd; ptWnd.x = 0; ptWnd.y = 0; ClientToScreen(lpIMC->hWnd, &ptWnd); if (ptWnd.x < sImeG.rcWorkArea.left) { lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.left; } else if (ptWnd.x + sImeG.xStatusWi > sImeG.rcWorkArea.right) { lpIMC->ptStatusWndPos.x = sImeG.rcWorkArea.right - sImeG.xStatusWi; } else { lpIMC->ptStatusWndPos.x = ptWnd.x; } // DebugShow2 ("ptst.y,", lpIMC->ptStatusWndPos.y, "bottom" , sImeG.rcWorkArea.bottom); if(!lpIMC->ptStatusWndPos.y) // == sImeG.rcWorkArea.bottom) lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;// - 2 * UI_MARGIN;// - 20; else lpIMC->ptStatusWndPos.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi;// - 2 * UI_MARGIN; //lpImcP->fdwInit |= INIT_STATUSWNDPOS; lpIMC->fdwInit |= INIT_STATUSWNDPOS; } if (!(lpIMC->fdwInit & INIT_COMPFORM)) { lpIMC->cfCompForm.dwStyle = CFS_DEFAULT; } if (lpIMC->cfCompForm.dwStyle != CFS_DEFAULT) { } else if (!lpIMC->hWnd) { } else if (lpImcP->fdwInit & INIT_COMPFORM) { } else { if (0/*lpImeL->fdwModeConfig & MODE_CONFIG_OFF_CARET_UI*/) { // lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x + // lpImeL->rcStatusText.right + lpImeL->cxCompBorder * 2 + // UI_MARGIN; // if (lpIMC->cfCompForm.ptCurrentPos.x + (lpImeL->nRevMaxKey * // sImeG.xChiCharWi) > sImeG.rcWorkArea.right) { // lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x - // lpImeL->nRevMaxKey * sImeG.xChiCharWi - // lpImeL->cxCompBorder * 3; // } } else { lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x + sImeG.xStatusWi + UI_MARGIN; if (lpIMC->cfCompForm.ptCurrentPos.x + lpImeL->xCompWi > sImeG.rcWorkArea.right) { lpIMC->cfCompForm.ptCurrentPos.x = lpIMC->ptStatusWndPos.x - lpImeL->xCompWi - lpImeL->cxCompBorder * 2 - UI_MARGIN; } } lpIMC->cfCompForm.ptCurrentPos.y = sImeG.rcWorkArea.bottom - lpImeL->yCompHi;// - 2 * UI_MARGIN; ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos); lpImcP->fdwInit |= INIT_COMPFORM; } return; } /**********************************************************************/ /* Select() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL PASCAL Select( HIMC hIMC, LPINPUTCONTEXT lpIMC, BOOL fSelect) { LPPRIVCONTEXT lpImcP; sImeG.First = 0; if (fSelect) { // init "every" fields of hPrivate, please!!! if (lpIMC->cfCompForm.dwStyle == CFS_DEFAULT) { } else { } if (!ClearCompStr(lpIMC)) { return (FALSE); } if (!ClearCand(lpIMC)) { return (FALSE); } ClearGuideLine(lpIMC); } if (!lpIMC->hPrivate) { return (FALSE); } lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); if (!lpImcP) { return (FALSE); } if (fSelect) { // init "every" fields of hPrivate, please!!! static bFirstTimeCallHere = TRUE; InterlockedIncrement( &lLock ); if ( bFirstTimeCallHere == TRUE ) { // we move the following code here from the DLL_ATTACH_PROCESS to // avoid application hang. // With static variable bFirstTimeCallHere, we ensure the following // code will be called only when the ImeSelect( ) is first called. GetCurrentUserEMBPath( ); data_init( ); bFirstTimeCallHere = FALSE; } InterlockedDecrement( &lLock ); lpImcP->iImeState = CST_INIT; // init the IME state machine lpImcP->fdwImeMsg = (DWORD)0; // no UI windpws show lpImcP->dwCompChar = (DWORD)0; lpImcP->fdwGcsFlag = (DWORD)0; lpImcP->hSoftKbdWnd = NULL; // soft keyboard window lpImcP->nShowSoftKbdCmd = 0; lpIMC->fOpen = TRUE; if (!(lpIMC->fdwInit & INIT_CONVERSION)) { if(GetKeyState(VK_CAPITAL)&1) lpIMC->fdwConversion = IME_CMODE_NOCONVERSION; else lpIMC->fdwConversion = IME_CMODE_NATIVE; kb_mode = CIN_STD; DispMode(hIMC); lpIMC->fdwConversion |= IME_CMODE_SYMBOL; lpIMC->fdwInit |= INIT_CONVERSION; }else { if (lpIMC->fdwConversion & IME_CMODE_SOFTKBD) { sImeG.First = 1; } } if (lpIMC->fdwInit & INIT_SENTENCE) { } else if (lpImeL->fModeConfig & MODE_CONFIG_PREDICT) { lpIMC->fdwSentence = IME_SMODE_PHRASEPREDICT; lpIMC->fdwInit |= INIT_SENTENCE; } else { } if (!(lpIMC->fdwInit & INIT_LOGFONT)) { HDC hDC; HGDIOBJ hSysFont; hDC = GetDC(NULL); hSysFont = GetStockObject(SYSTEM_FONT); GetObject(hSysFont, sizeof(LOGFONT), &lpIMC->lfFont.A); ReleaseDC(NULL, hDC); lpIMC->fdwInit |= INIT_LOGFONT; } // Get Current User's specific phrase table path InitContext(lpIMC,lpImcP); } else { if(hCrtDlg) { SendMessage(hCrtDlg, WM_CLOSE, (WPARAM)NULL, (LPARAM)NULL); hCrtDlg = NULL; } } ImmUnlockIMCC(lpIMC->hPrivate); return (TRUE); } /**********************************************************************/ /* ImeSelect() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL WINAPI ImeSelect( HIMC hIMC, BOOL fSelect) { LPINPUTCONTEXT lpIMC; BOOL fRet; // to load/free IME table if (fSelect) { InitCvtPara(); if (!lpImeL->cRefCount++) { /* zst LoadTable() */ ; } } else { if (!lpImeL->cRefCount) { /* zst FreeTable() */ ; } } if (!hIMC) { return (FALSE); } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return (FALSE); } fRet = Select(hIMC, lpIMC, fSelect); ImmUnlockIMC(hIMC); return (fRet); } /**********************************************************************/ /* ImeSetActiveContext() */ /* Return Value: */ /* TRUE - successful, FALSE - failure */ /**********************************************************************/ BOOL WINAPI ImeSetActiveContext( HIMC hIMC, BOOL fOn) { if (!fOn) { } else if (!hIMC) { } else { LPINPUTCONTEXT lpIMC; LPPRIVCONTEXT lpImcP; //zl lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return (FALSE); } if(lpIMC->hPrivate){ lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); //zl if (!lpImcP){ //zl return (FALSE); //zl } //zl }else return(FALSE); InitContext(lpIMC,lpImcP); //zl // DispModeEx(0); ImmUnlockIMCC(lpIMC->hPrivate); //zl ImmUnlockIMC(hIMC); } return (TRUE); } /**********************************************************************/ /* ReInitIme() */ /**********************************************************************/ void PASCAL ReInitIme( HWND hWnd , WORD WhatStyle) { HWND hStatusWnd,MainWnd; POINT ptPos; RECT rcStatusWnd,TempRect; int cxBorder, cyBorder; if (sImeG.unchanged) return ; // border + raising edge + sunken edge cxBorder = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE) * 2; cyBorder = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE) * 2; //if (!WhatStyle){ if (WhatStyle==IME_APRS_AUTO){ lpImeL->rcCompText.left = 4; lpImeL->rcCompText.top =4; lpImeL->rcCompText.right = sImeG.TextLen+5; lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6; lpImeL->cxCompBorder = cxBorder; lpImeL->cyCompBorder = cyBorder; // set the width & height for composition window lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2; //lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl lpImeL->yCompHi = sImeG.yStatusHi;//lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl } else { // text position relative to the composition window lpImeL->rcCompText.left = 4; lpImeL->rcCompText.top = 4; lpImeL->rcCompText.right = sImeG.TextLen+5; lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;/*cyBorder;*/ lpImeL->cxCompBorder = cxBorder; lpImeL->cyCompBorder = cyBorder; // set the width & height for composition window lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2; lpImeL->yCompHi = sImeG.yStatusHi; //zl } // border + raising edge + sunken edge cxBorder = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE) /* 2*/; cyBorder = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE) /* 2*/; //if (!WhatStyle){ if (WhatStyle==IME_APRS_AUTO){ sImeG.rcCandText.left = 4; sImeG.rcCandText.top = 4; sImeG.rcCandText.right = sImeG.xChiCharWi * 7; sImeG.rcCandText.bottom = sImeG.yChiCharHi * CANDPERPAGE+1;//zl sImeG.cxCandBorder = cxBorder+3; sImeG.cyCandBorder = cyBorder+3; sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2+3;//zl sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder *2+12; sImeG.rcHome.left = 4 ; sImeG.rcHome.top = sImeG.rcCandText.bottom+6 ; sImeG.rcHome.right = sImeG.rcHome.left + 14 ; sImeG.rcHome.bottom = sImeG.rcHome.top +14 ; sImeG.rcEnd.left = sImeG.rcHome.right ; sImeG.rcEnd.top = sImeG.rcHome.top ; sImeG.rcEnd.right = sImeG.rcEnd.left + 14 ; sImeG.rcEnd.bottom = sImeG.rcHome.bottom ; sImeG.rcPageDown.top = sImeG.rcHome.top ; sImeG.rcPageDown.right = sImeG.xCandWi-4; sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ; sImeG.rcPageDown.bottom = sImeG.rcHome.bottom ; sImeG.rcPageUp.top = sImeG.rcHome.top ; sImeG.rcPageUp.right = sImeG.rcPageDown.left ; sImeG.rcPageUp.left = sImeG.rcPageUp.right -14 ; sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ; }else{ sImeG.cxCandBorder = cxBorder; sImeG.cyCandBorder = cyBorder; sImeG.xCandWi = lpImeL->xCompWi + sImeG.xStatusWi - cxBorder+1; sImeG.yCandHi = sImeG.yStatusHi; //sImeG.yChiCharHi+3 + sImeG.cyCandBorder *2; sImeG.rcHome.left = 3; //2; sImeG.rcHome.top = 4;//7; sImeG.rcHome.right = sImeG.rcHome.left + 10; //14; sImeG.rcHome.bottom = sImeG.rcHome.top +8; //14 ; sImeG.rcEnd.left =sImeG.rcHome.left; //sImeG.rcHome.right ; sImeG.rcEnd.top = sImeG.rcHome.top+9; //14 ; sImeG.rcEnd.right =sImeG.rcHome.right; //sImeG.rcEnd.left + 14 ; sImeG.rcEnd.bottom = sImeG.rcHome.bottom+10; //14 ; sImeG.rcPageDown.top = sImeG.rcEnd.top;//sImeG.rcHome.top ; sImeG.rcPageDown.right = sImeG.xCandWi-1;//2; sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ; sImeG.rcPageDown.bottom = sImeG.rcEnd.bottom ;//sImeG.rcHome.bottom ; sImeG.rcPageUp.top = sImeG.rcHome.top -1; //zl sImeG.rcPageUp.right = sImeG.rcPageDown.right+1;//zl;sImeG.rcPageDown.left ; sImeG.rcPageUp.left = sImeG.rcPageDown.left;//sImeG.rcPageUp.right -14 ; sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ; sImeG.rcCandText.left = sImeG.rcEnd.right+2;//1;//4;//sImeG.rcEnd.right; sImeG.rcCandText.top = 4; sImeG.rcCandText.right = sImeG.rcPageUp.left-4;//2;//sImeG.rcPageUp.left-2; sImeG.rcCandText.bottom = sImeG.yChiCharHi+7;//6;//3; } /* ptPos.x = 0 ; ptPos.y = 0 ; ClientToScreen(hWnd, &ptPos); lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2; lpImeL->ptDefComp.y = ptPos.y - cyBorder; lpImeL->ptDefCand.x = ptPos.x - cxBorder; lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2; if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10) {lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi; lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;} if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5)) lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi; //sImeG.yCandHi+2; */ if (hWnd){ ptPos.x = 0 ; ptPos.y = 0 ; ClientToScreen(hWnd, &ptPos); CountDefaultComp(ptPos.x,ptPos.y,sImeG.rcWorkArea); lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2+4;//zl lpImeL->ptDefComp.y = ptPos.y - cyBorder+3;//2;//3; //zl lpImeL->ptDefCand.x = ptPos.x - cxBorder+3; //zl lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2+2;//zl if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10){ lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi; lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ; } if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5)) lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi-4; //sImeG.yCandHi+2; }else{ ptPos.x = lpImeL->Ox ; ptPos.y = lpImeL->Oy ; lpImeL->ptDefComp.x = sImeG.xStatusWi - cxBorder*2; lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi; lpImeL->ptDefCand.x = lpImeL->ptDefComp.x + lpImeL->xCompWi; lpImeL->ptDefCand.y = lpImeL->ptDefComp.y ; /* if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10) {lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi; lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ;} if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5)) lpImeL->ptDefCand.y = ptPos.y + sImeG.yCandHi+2; */ } fmt_transfer(); CandWndChange = 1; CompWndChange = 1; return ; } void PASCAL ReInitIme2( HWND hWnd , WORD WhatStyle) { HWND hStatusWnd,MainWnd; POINT ptPos; RECT rcStatusWnd,TempRect; int cxBorder, cyBorder; if (sImeG.unchanged) return ; // border + raising edge + sunken edge cxBorder = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE) * 2; cyBorder = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE) * 2; if (!WhatStyle){ lpImeL->rcCompText.left = 4; lpImeL->rcCompText.top =4; lpImeL->rcCompText.right = sImeG.TextLen+5; lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6; lpImeL->cxCompBorder = cxBorder; lpImeL->cyCompBorder = cyBorder; // set the width & height for composition window lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2; //lpImeL->yCompHi = lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl lpImeL->yCompHi = sImeG.yStatusHi;//lpImeL->rcCompText.bottom +/* lpImeL->cyCompBorder*/3 * 2+1;//zl } else { // text position relative to the composition window lpImeL->rcCompText.left = 4; lpImeL->rcCompText.top = 4; lpImeL->rcCompText.right = sImeG.TextLen+5; lpImeL->rcCompText.bottom = sImeG.yStatusHi-4;//6;/*cyBorder;*/ lpImeL->cxCompBorder = cxBorder; lpImeL->cyCompBorder = cyBorder; // set the width & height for composition window lpImeL->xCompWi = lpImeL->rcCompText.right + /*lpImeL->cxCompBorder*/3 * 2; lpImeL->yCompHi = sImeG.yStatusHi; //zl } // border + raising edge + sunken edge cxBorder = GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXEDGE) /* 2*/; cyBorder = GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYEDGE) /* 2*/; if (!WhatStyle){ sImeG.rcCandText.left = 4; sImeG.rcCandText.top = 4; sImeG.rcCandText.right = sImeG.xChiCharWi * 7; sImeG.rcCandText.bottom = sImeG.yChiCharHi * CANDPERPAGE+1;//zl sImeG.cxCandBorder = cxBorder+3; sImeG.cyCandBorder = cyBorder+3; sImeG.xCandWi = sImeG.rcCandText.right + sImeG.cxCandBorder * 2+3;//zl sImeG.yCandHi = sImeG.rcCandText.bottom + sImeG.cyCandBorder *2+12; sImeG.rcHome.left = 4 ; sImeG.rcHome.top = sImeG.rcCandText.bottom+6 ; sImeG.rcHome.right = sImeG.rcHome.left + 14 ; sImeG.rcHome.bottom = sImeG.rcHome.top +14 ; sImeG.rcEnd.left = sImeG.rcHome.right ; sImeG.rcEnd.top = sImeG.rcHome.top ; sImeG.rcEnd.right = sImeG.rcEnd.left + 14 ; sImeG.rcEnd.bottom = sImeG.rcHome.bottom ; sImeG.rcPageDown.top = sImeG.rcHome.top ; sImeG.rcPageDown.right = sImeG.xCandWi-4; sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ; sImeG.rcPageDown.bottom = sImeG.rcHome.bottom ; sImeG.rcPageUp.top = sImeG.rcHome.top ; sImeG.rcPageUp.right = sImeG.rcPageDown.left ; sImeG.rcPageUp.left = sImeG.rcPageUp.right -14 ; sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ; }else{ sImeG.cxCandBorder = cxBorder; sImeG.cyCandBorder = cyBorder; sImeG.xCandWi = lpImeL->xCompWi + sImeG.xStatusWi - cxBorder+1; sImeG.yCandHi = sImeG.yStatusHi; //sImeG.yChiCharHi+3 + sImeG.cyCandBorder *2; sImeG.rcHome.left = 3; //2; sImeG.rcHome.top = 4;//7; sImeG.rcHome.right = sImeG.rcHome.left + 10; //14; sImeG.rcHome.bottom = sImeG.rcHome.top +8; //14 ; sImeG.rcEnd.left =sImeG.rcHome.left; //sImeG.rcHome.right ; sImeG.rcEnd.top = sImeG.rcHome.top+9; //14 ; sImeG.rcEnd.right =sImeG.rcHome.right; //sImeG.rcEnd.left + 14 ; sImeG.rcEnd.bottom = sImeG.rcHome.bottom+10; //14 ; sImeG.rcPageDown.top = sImeG.rcEnd.top;//sImeG.rcHome.top ; sImeG.rcPageDown.right = sImeG.xCandWi-1;//2; sImeG.rcPageDown.left = sImeG.rcPageDown.right - 14 ; sImeG.rcPageDown.bottom = sImeG.rcEnd.bottom ;//sImeG.rcHome.bottom ; sImeG.rcPageUp.top = sImeG.rcHome.top -1; //zl sImeG.rcPageUp.right = sImeG.rcPageDown.right+1;//zl;sImeG.rcPageDown.left ; sImeG.rcPageUp.left = sImeG.rcPageDown.left;//sImeG.rcPageUp.right -14 ; sImeG.rcPageUp.bottom = sImeG.rcHome.bottom ; sImeG.rcCandText.left = sImeG.rcEnd.right+2;//1;//4;//sImeG.rcEnd.right; sImeG.rcCandText.top = 4; sImeG.rcCandText.right = sImeG.rcPageUp.left-4;//2;//sImeG.rcPageUp.left-2; sImeG.rcCandText.bottom = sImeG.yChiCharHi+7;//6;//3; } if (hWnd){ ptPos.x = 0 ; ptPos.y = 0 ; ClientToScreen(hWnd, &ptPos); lpImeL->ptDefComp.x = ptPos.x + sImeG.xStatusWi - cxBorder*2+4;//zl lpImeL->ptDefComp.y = ptPos.y - cyBorder+3;//2;//3; //zl lpImeL->ptDefCand.x = ptPos.x - cxBorder+3; //zl lpImeL->ptDefCand.y = ptPos.y - sImeG.yCandHi-2+2;//zl if ((sImeG.rcWorkArea.right-lpImeL->ptDefComp.x -lpImeL->xCompWi)<10){ lpImeL->ptDefComp.x = ptPos.x - lpImeL->xCompWi; lpImeL->ptDefCand.x = lpImeL->ptDefComp.x ; } if ((ptPos.y - sImeG.yCandHi)< (sImeG.rcWorkArea.top+5)) lpImeL->ptDefCand.y = ptPos.y + sImeG.yStatusHi-4; //sImeG.yCandHi+2; }else{ ptPos.x = lpImeL->Ox ; ptPos.y = lpImeL->Oy ; lpImeL->ptDefComp.x = sImeG.xStatusWi - cxBorder*2; lpImeL->ptDefComp.y = sImeG.rcWorkArea.bottom - sImeG.yStatusHi; lpImeL->ptDefCand.x = lpImeL->ptDefComp.x + lpImeL->xCompWi; lpImeL->ptDefCand.y = lpImeL->ptDefComp.y ; } return ; } /**********************************************************************/ /* InitUserSetting() */ /**********************************************************************/ int InitUserSetting(void) { HKEY hKey,hFirstKey; DWORD dwSize, dx; int lRet; RegCreateKey(HKEY_CURRENT_USER, szRegNearCaret, &hFirstKey); RegCreateKey(hFirstKey, szAIABC, &hKey); RegCloseKey(hFirstKey); //1 KeyType dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey, szKeyType, NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey,szKeyType , 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { sImeG.KbType =(BYTE)dx ; } // 2 ImeStyle dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey,szImeStyle , NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey,szImeStyle, 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { lpImeL->wImeStyle = (WORD)dx ; } // 3 AutoCp dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey, szCpAuto, NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey,szCpAuto, 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { sImeG.auto_mode =(BYTE)dx ; } // 4 BxFlag dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey, szBxFlag , NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey, szBxFlag , 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { sImeG.cbx_flag =(BYTE)dx ; } // 5 TuneFlag dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey, szTuneFlag , NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey, szTuneFlag , 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { sImeG.tune_flag=(BYTE)dx ; } // 6 AutoCvt dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey, szAutoCvt , NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey, szAutoCvt, 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { sImeG.auto_cvt_flag=(BYTE)dx ; } // 7 SdaHelp dwSize = sizeof(dwSize); lRet = RegQueryValueEx(hKey, szSdaHelp , NULL, NULL, (LPBYTE)&dx, &dwSize); if (lRet != ERROR_SUCCESS) { dx = 0; RegSetValueEx(hKey, szSdaHelp, 0, REG_DWORD, (LPBYTE)&dx, sizeof(int)); }else { sImeG.SdOpenFlag=(BYTE)dx ; } RegCloseKey(hKey); //ReInitIme2(NULL, lpImeL->wImeStyle); return 0; } /**********************************************************************/ /* ChangeUserSetting() */ /**********************************************************************/ ChangeUserSetting() { HKEY hKey,hFirstKey; DWORD dwSize, dx; int lRet; RegCreateKey(HKEY_CURRENT_USER, szRegNearCaret, &hFirstKey); RegCreateKey(hFirstKey, szAIABC, &hKey); RegCloseKey(hFirstKey); RegSetValueEx(hKey, szKeyType, 0, REG_DWORD, (LPBYTE)&sImeG.KbType, sizeof(int)); RegSetValueEx(hKey, szImeStyle, 0, REG_DWORD, (LPBYTE)&lpImeL->wImeStyle, sizeof(int)); RegSetValueEx(hKey, szCpAuto, 0, REG_DWORD, (LPBYTE)&sImeG.auto_mode, sizeof(int)); RegSetValueEx(hKey, szBxFlag, 0, REG_DWORD, (LPBYTE)&sImeG.cbx_flag, sizeof(int)); RegSetValueEx(hKey, szTuneFlag, 0, REG_DWORD, (LPBYTE)&sImeG.tune_flag, sizeof(int)); RegSetValueEx(hKey, szAutoCvt, 0, REG_DWORD, (LPBYTE)&sImeG.auto_cvt_flag, sizeof(int)); RegSetValueEx(hKey, szSdaHelp, 0, REG_DWORD, (LPBYTE)&sImeG.SdOpenFlag, sizeof(int)); RegCloseKey(hKey); return 0; } /**********************************************************************/ /* InitImeGlobalData() */ /**********************************************************************/ void PASCAL InitImeGlobalData( HINSTANCE hInstance) { int cxBorder, cyBorder; HDC hDC; BYTE szChiChar[4]; SIZE lTextSize; HGLOBAL hResData; int i; DWORD dwSize; HKEY hKeyIMESetting; LONG lRet; BYTE NumChar[]="1.2.3.4.5.6.7.8.9."; BYTE CNumChar[]="ÀëÀëÔ­ÉϲÝÒ»ËêÒ»¿ÝÈÙ"; 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.xptStatusWndPos.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); }