/*++ Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved Module Name: candui.c ++*/ #include #include #include /**********************************************************************/ /* 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); } void PASCAL CalcCandPos( HIMC hIMC, HWND hUIWnd, LPPOINT lpptWnd) // the composition window position { POINT ptNew, ptSTWPos; RECT rcWorkArea; #ifdef MUL_MONITOR rcWorkArea = ImeMonitorWorkAreaFromPoint(*lpptWnd); #else rcWorkArea = sImeG.rcWorkArea; #endif ptNew.x = lpptWnd->x + lpImeL->xCompWi + UI_MARGIN; if (ptNew.x + sImeG.xCandWi > rcWorkArea.right) { // exceed screen width ptNew.x = lpptWnd->x - sImeG.xCandWi - UI_MARGIN; } ptNew.y = lpptWnd->y + lpImeL->cyCompBorder - sImeG.cyCandBorder; if (ptNew.y + sImeG.yCandHi > rcWorkArea.bottom) { // exceed screen high ptNew.y = rcWorkArea.bottom - sImeG.yCandHi; } if(!sImeG.IC_Trace) { HWND hCompWnd; ImmGetStatusWindowPos(hIMC, (LPPOINT)&ptSTWPos); hCompWnd = GetCompWnd(hUIWnd); if (hCompWnd) { ptNew.x = ptSTWPos.x + sImeG.xStatusWi + lpImeL->xCompWi + 2 * UI_MARGIN; if((ptSTWPos.x + sImeG.xStatusWi + sImeG.xCandWi + lpImeL->xCompWi + 2 * UI_MARGIN)> rcWorkArea.right) { if (ptSTWPos.x >= (sImeG.xCandWi + lpImeL->xCompWi + 2 * UI_MARGIN)) { ptNew.x = ptSTWPos.x - lpImeL->xCompWi - sImeG.xCandWi - 2 * UI_MARGIN; } else { ptNew.x = ptSTWPos.x + sImeG.xStatusWi + UI_MARGIN; } } ptNew.y = ptSTWPos.y + lpImeL->cyCompBorder - sImeG.cyCandBorder; if (ptNew.y + sImeG.yCandHi > rcWorkArea.bottom) { ptNew.y = rcWorkArea.bottom - sImeG.yCandHi; } } else { ptNew.x = ptSTWPos.x + sImeG.xStatusWi + UI_MARGIN; if(((ptSTWPos.x + sImeG.xStatusWi + sImeG.xCandWi + UI_MARGIN)>= rcWorkArea.right) && (ptSTWPos.x >= sImeG.xCandWi + UI_MARGIN)) { ptNew.x = ptSTWPos.x - sImeG.xCandWi - UI_MARGIN; } ptNew.y = ptSTWPos.y + lpImeL->cyCompBorder - sImeG.cyCandBorder; if (ptNew.y + sImeG.yCandHi > rcWorkArea.bottom) { ptNew.y = rcWorkArea.bottom - sImeG.yCandHi; } } } lpptWnd->x = ptNew.x; lpptWnd->y = ptNew.y; return; } /**********************************************************************/ /* AdjustCandPos */ /**********************************************************************/ void AdjustCandPos( HIMC hIMC, LPPOINT lpptWnd) // the composition window position { LPINPUTCONTEXT lpIMC; LONG ptFontHi; UINT uEsc; RECT rcWorkArea; #ifdef MUL_MONITOR rcWorkArea = ImeMonitorWorkAreaFromPoint(*lpptWnd); #else rcWorkArea = sImeG.rcWorkArea; #endif lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } if (lpIMC->lfFont.A.lfHeight > 0) { ptFontHi = lpIMC->lfFont.A.lfHeight; } else if (lpIMC->lfFont.A.lfWidth == 0) { ptFontHi = lpImeL->yCompHi; } else { ptFontHi = -lpIMC->lfFont.A.lfHeight; } if (ptFontHi > lpImeL->yCompHi * 8) { ptFontHi = lpImeL->yCompHi * 8; } if (ptFontHi < sImeG.yChiCharHi) { ptFontHi = 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 ptFontHi = ptFontHi * ptInputEsc[uEsc].y; if(lpptWnd->y + ptFontHi + sImeG.yCandHi <= rcWorkArea.bottom) { lpptWnd->y += ptFontHi; } else { lpptWnd->y -= (ptFontHi + sImeG.yCandHi); } ImmUnlockIMC(hIMC); return; } /**********************************************************************/ /* AdjustCandRectBoundry */ /**********************************************************************/ void PASCAL AdjustCandRectBoundry( LPINPUTCONTEXT lpIMC, LPPOINT lpptCandWnd) // the caret position { RECT rcExclude, rcUIRect, rcInterSect; UINT uEsc; RECT rcWorkArea; #ifdef MUL_MONITOR { RECT rcCandWnd; *(LPPOINT)&rcCandWnd = *(LPPOINT)lpptCandWnd; rcCandWnd.right = rcCandWnd.left + sImeG.xCandWi; rcCandWnd.bottom = rcCandWnd.top + sImeG.yCandHi; rcWorkArea = ImeMonitorWorkAreaFromRect(&rcCandWnd); } #else rcWorkArea = sImeG.rcWorkArea; #endif // be a normal rectangle, not a negative rectangle if (lpIMC->cfCandForm[0].rcArea.left > lpIMC->cfCandForm[0].rcArea.right) { LONG tmp; tmp = lpIMC->cfCandForm[0].rcArea.left; lpIMC->cfCandForm[0].rcArea.left = lpIMC->cfCandForm[0].rcArea.right; lpIMC->cfCandForm[0].rcArea.right = tmp; } if (lpIMC->cfCandForm[0].rcArea.top > lpIMC->cfCandForm[0].rcArea.bottom) { LONG tmp; tmp = lpIMC->cfCandForm[0].rcArea.top; lpIMC->cfCandForm[0].rcArea.top = lpIMC->cfCandForm[0].rcArea.bottom; lpIMC->cfCandForm[0].rcArea.bottom = tmp; } // translate from client coordinate to screen coordinate rcExclude = lpIMC->cfCandForm[0].rcArea; rcExclude.left += lpptCandWnd->x - lpIMC->cfCandForm[0].ptCurrentPos.x; rcExclude.right += lpptCandWnd->x - lpIMC->cfCandForm[0].ptCurrentPos.x; rcExclude.top += lpptCandWnd->y - lpIMC->cfCandForm[0].ptCurrentPos.y; rcExclude.bottom += lpptCandWnd->y - lpIMC->cfCandForm[0].ptCurrentPos.y; // if original point is OK, we use it *(LPPOINT)&rcUIRect = *lpptCandWnd; if (rcUIRect.left < rcWorkArea.left) { rcUIRect.left = rcWorkArea.left; } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { rcUIRect.left = rcWorkArea.right - sImeG.xCandWi; } else { } if (rcUIRect.top < rcWorkArea.top) { rcUIRect.top = rcWorkArea.top; } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi; } else { } rcUIRect.right = rcUIRect.left + sImeG.xCandWi; rcUIRect.bottom = rcUIRect.top + sImeG.yCandHi; if (!IntersectRect(&rcInterSect, &rcExclude, &rcUIRect)) { *lpptCandWnd = *(LPPOINT)&rcUIRect; return; } uEsc = (UINT)((lpIMC->lfFont.A.lfEscapement + 450) / 900 % 4); if (uEsc & 0x0001) { // 900 & 2700 we need change x coordinate if (ptInputEsc[uEsc].x > 0) { rcUIRect.left = rcExclude.right; } else { rcUIRect.left = rcExclude.left - sImeG.xCandWi; } } else { // 0 & 1800 we do not change x coordinate rcUIRect.left = lpptCandWnd->x; } if (rcUIRect.left < rcWorkArea.left) { rcUIRect.left = rcWorkArea.left; } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { rcUIRect.left = rcWorkArea.right - sImeG.xCandWi; } else { } if (uEsc & 0x0001) { // 900 & 2700 we do not change y coordinate rcUIRect.top = lpptCandWnd->y; } else { // 0 & 1800 we need change y coordinate if (ptInputEsc[uEsc].y > 0) { rcUIRect.top = rcExclude.bottom; } else { rcUIRect.top = rcExclude.top - sImeG.yCandHi; } } if (rcUIRect.top < rcWorkArea.top) { rcUIRect.top = rcWorkArea.top; } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi; } else { } rcUIRect.right = rcUIRect.left + sImeG.xCandWi; rcUIRect.bottom = rcUIRect.top + sImeG.yCandHi; // the candidate window not overlapped with exclude rectangle // so we found a position if (!IntersectRect(&rcInterSect, &rcExclude, &rcUIRect)) { *lpptCandWnd = *(LPPOINT)&rcUIRect; return; } // adjust according to *(LPPOINT)&rcUIRect = *lpptCandWnd; if (uEsc & 0x0001) { // 900 & 2700 we prefer adjust x if (ptInputEsc[uEsc].x > 0) { rcUIRect.left = rcExclude.right; } else { rcUIRect.left = rcExclude.left - sImeG.xCandWi; } if (rcUIRect.left < rcWorkArea.left) { } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { } else { if (rcUIRect.top < rcWorkArea.top) { rcUIRect.top = rcWorkArea.top; } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi; } *lpptCandWnd = *(LPPOINT)&rcUIRect; return; } // negative try if (ptInputEsc[uEsc].x > 0) { rcUIRect.left = rcExclude.left - sImeG.xCandWi; } else { rcUIRect.left = rcExclude.right; } if (rcUIRect.left < rcWorkArea.left) { } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { } else { if (rcUIRect.top < rcWorkArea.top) { rcUIRect.top = rcWorkArea.top; } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi; } *lpptCandWnd = *(LPPOINT)&rcUIRect; return; } // negative try failure again, we use positive plus display adjust if (ptInputEsc[uEsc].x > 0) { rcUIRect.left = rcExclude.right; } else { rcUIRect.left = rcExclude.left - sImeG.xCandWi; } if (rcUIRect.left < rcWorkArea.left) { rcUIRect.left = rcWorkArea.left; } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { rcUIRect.left = rcWorkArea.right - sImeG.xCandWi; } if (rcUIRect.top < rcWorkArea.top) { rcUIRect.top = rcWorkArea.top; } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi; } *lpptCandWnd = *(LPPOINT)&rcUIRect; } else { // 0 & 1800 we prefer adjust y if (ptInputEsc[uEsc].y > 0) { rcUIRect.top = rcExclude.bottom; } else { rcUIRect.top = rcExclude.top - sImeG.yCandHi; } if (rcUIRect.top < rcWorkArea.top) { } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { } else { if (rcUIRect.left < rcWorkArea.left) { rcUIRect.left = rcWorkArea.left; } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { rcUIRect.left = rcWorkArea.right - sImeG.xCandWi; } *lpptCandWnd = *(LPPOINT)&rcUIRect; return; } // negative try if (ptInputEsc[uEsc].y > 0) { rcUIRect.top = rcExclude.top - sImeG.yCandHi; } else { rcUIRect.top = rcExclude.bottom; } if (rcUIRect.top < rcWorkArea.top) { } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.right) { } else { if (rcUIRect.left < rcWorkArea.left) { rcUIRect.left = rcWorkArea.left; } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { rcUIRect.left = rcWorkArea.right - sImeG.xCandWi; } *lpptCandWnd = *(LPPOINT)&rcUIRect; return; } // negative try failure again, we use positive plus display adjust if (ptInputEsc[uEsc].y > 0) { rcUIRect.top = rcExclude.bottom; } else { rcUIRect.top = rcExclude.top - sImeG.yCandHi; } if (rcUIRect.left < rcWorkArea.left) { rcUIRect.left = rcWorkArea.left; } else if (rcUIRect.left + sImeG.xCandWi > rcWorkArea.right) { rcUIRect.left = rcWorkArea.right - sImeG.xCandWi; } if (rcUIRect.top < rcWorkArea.top) { rcUIRect.top = rcWorkArea.top; } else if (rcUIRect.top + sImeG.yCandHi > rcWorkArea.bottom) { rcUIRect.top = rcWorkArea.bottom - sImeG.yCandHi; } *lpptCandWnd = *(LPPOINT)&rcUIRect; } return; } /**********************************************************************/ /* AdjustCandBoundry */ /**********************************************************************/ void PASCAL AdjustCandBoundry( LPPOINT lpptCandWnd) // the position { RECT rcWorkArea; #ifdef MUL_MONITOR { RECT rcCandWnd; *(LPPOINT)&rcCandWnd = *(LPPOINT)lpptCandWnd; rcCandWnd.right = rcCandWnd.left + sImeG.xCandWi; rcCandWnd.bottom = rcCandWnd.top + sImeG.yCandHi; rcWorkArea = ImeMonitorWorkAreaFromRect(&rcCandWnd); } #else rcWorkArea = sImeG.rcWorkArea; #endif if (lpptCandWnd->x < rcWorkArea.left) { lpptCandWnd->x = rcWorkArea.left; } else if (lpptCandWnd->x + sImeG.xCandWi > rcWorkArea.right) { lpptCandWnd->x = rcWorkArea.right - sImeG.xCandWi; } if (lpptCandWnd->y < rcWorkArea.top) { lpptCandWnd->y = rcWorkArea.top; } else if (lpptCandWnd->y + sImeG.yCandHi > rcWorkArea.bottom) { lpptCandWnd->y = rcWorkArea.bottom - sImeG.yCandHi; } return; } /**********************************************************************/ /* SetCandPosition() */ /**********************************************************************/ LRESULT PASCAL SetCandPosition( HWND hCandWnd) { HWND hUIWnd; HIMC hIMC; LPINPUTCONTEXT lpIMC; POINT ptNew; hUIWnd = GetWindow(hCandWnd, GW_OWNER); hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { return (1L); } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return (1L); } ptNew = lpIMC->cfCandForm[0].ptCurrentPos; ClientToScreen((HWND)lpIMC->hWnd, &ptNew); if (lpIMC->cfCandForm[0].dwStyle & CFS_FORCE_POSITION) { } else if (lpIMC->cfCandForm[0].dwStyle == CFS_CANDIDATEPOS) { AdjustCandBoundry(&ptNew); } else if (lpIMC->cfCandForm[0].dwStyle == CFS_EXCLUDE) { if(!sImeG.IC_Trace) { CalcCandPos(hIMC, hUIWnd, &ptNew); } AdjustCandBoundry(&ptNew); } SetWindowPos(hCandWnd, NULL, ptNew.x, ptNew.y, 0, 0, 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; 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->nShowCandCmd == nShowCandCmd) { goto SwCandNoChange; } if (nShowCandCmd == SW_HIDE) { lpUIPrivate->fdwSetContext &= ~(ISC_HIDE_CAND_WINDOW); } if (!lpUIPrivate->hCandWnd) { // not in show candidate window mode } else if (lpUIPrivate->nShowCandCmd == nShowCandCmd) { } else { if(nShowCandCmd == SW_HIDE) { uOpenCand = 0; } else { HIMC hIMC; POINT ptSTWPos; int Comp_CandWndLen; RECT rcWorkArea; uOpenCand = 1; // reset status window for LINE_UI(FIX_UI) hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { goto ShowCand; } ImmGetStatusWindowPos(hIMC, (LPPOINT)&ptSTWPos); #ifdef MUL_MONITOR rcWorkArea = ImeMonitorWorkAreaFromPoint(ptSTWPos); #else rcWorkArea = sImeG.rcWorkArea; #endif Comp_CandWndLen = 0; if(uOpenCand) { Comp_CandWndLen += sImeG.xCandWi + UI_MARGIN; if(uStartComp) { Comp_CandWndLen += lpImeL->xCompWi + UI_MARGIN; } if(ptSTWPos.x + sImeG.xStatusWi + Comp_CandWndLen > rcWorkArea.right) { PostMessage(GetCompWnd(hUIWnd), WM_IME_NOTIFY, IMN_SETCOMPOSITIONWINDOW, 0); } } } ShowCand: ShowWindow(lpUIPrivate->hCandWnd, nShowCandCmd); lpUIPrivate->nShowCandCmd = nShowCandCmd; } SwCandNoChange: GlobalUnlock(hUIPrivate); return; } /**********************************************************************/ /* OpenCand */ /**********************************************************************/ void PASCAL OpenCand( HWND hUIWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; HIMC hIMC; LPINPUTCONTEXT lpIMC; POINT ptWnd; 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; hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC); if (!hIMC) { goto OpenCandUnlockUIPriv; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { goto OpenCandUnlockUIPriv; } if (lpIMC->cfCandForm[0].dwIndex == 0) { ptWnd = lpIMC->cfCandForm[0].ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptWnd); if (lpIMC->cfCandForm[0].dwStyle & CFS_FORCE_POSITION) { } else if (lpIMC->cfCandForm[0].dwStyle == CFS_EXCLUDE) { POINT ptCaret; AdjustCandBoundry(&ptWnd); if((!sImeG.IC_Trace) || (!GetCaretPos(&ptCaret))) { if(GetCompWnd(hUIWnd)) { ptWnd.x = ptWnd.y = 0; ClientToScreen(lpIMC->hWnd, &ptWnd); ptWnd.x -= lpImeL->cxCompBorder + 1; ptWnd.y -= lpImeL->cyCompBorder + 1; } else { ptWnd.x = lpImeL->cxCompBorder + 1; ptWnd.y = lpImeL->cyCompBorder + 1; } CalcCandPos(hIMC, hUIWnd, &ptWnd); lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS; lpIMC->cfCandForm[0].ptCurrentPos = ptWnd; ScreenToClient(lpIMC->hWnd, &lpIMC->cfCandForm[0].ptCurrentPos); } else { AdjustCandPos(hIMC, &ptWnd); } } else if (lpIMC->cfCandForm[0].dwStyle == CFS_CANDIDATEPOS) { AdjustCandBoundry(&ptWnd); } else { if (lpUIPrivate->nShowCompCmd != SW_HIDE) { ptWnd.x = ptWnd.y = 0; ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd); } else { ptWnd = lpIMC->cfCompForm.ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptWnd); } ptWnd.x -= lpImeL->cxCompBorder + 1; ptWnd.y -= lpImeL->cyCompBorder + 1; CalcCandPos(hIMC, hUIWnd, &ptWnd); lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS; lpIMC->cfCandForm[0].ptCurrentPos = ptWnd; ScreenToClient(lpIMC->hWnd, &lpIMC->cfCandForm[0].ptCurrentPos); } } else { // make cand windows trace comp window ! if (lpUIPrivate->nShowCompCmd != SW_HIDE) { ptWnd.x = ptWnd.y = 0; ClientToScreen(lpUIPrivate->hCompWnd, &ptWnd); } else { ptWnd = lpIMC->cfCompForm.ptCurrentPos; ClientToScreen(lpIMC->hWnd, &ptWnd); } ptWnd.x -= lpImeL->cxCompBorder + 1; ptWnd.y -= lpImeL->cyCompBorder + 1; CalcCandPos(hIMC, hUIWnd, &ptWnd); lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS; lpIMC->cfCandForm[0].ptCurrentPos = ptWnd; ScreenToClient(lpIMC->hWnd, &lpIMC->cfCandForm[0].ptCurrentPos); } ImmUnlockIMC(hIMC); if (lpUIPrivate->hCandWnd) { SetWindowPos(lpUIPrivate->hCandWnd, NULL, ptWnd.x, ptWnd.y, 0, 0, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER); } else { lpUIPrivate->hCandWnd = CreateWindowEx( WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME, szCandClassName, NULL, WS_POPUP|WS_DISABLED, ptWnd.x, ptWnd.y, sImeG.xCandWi, sImeG.yCandHi, hUIWnd, (HMENU)NULL, hInst, NULL); SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG); SetWindowLong(lpUIPrivate->hCandWnd, UI_MOVE_XY, 0L); } ShowCand(hUIWnd, SW_SHOWNOACTIVATE); OpenCandUnlockUIPriv: GlobalUnlock(hUIPrivate); return; } /**********************************************************************/ /* CloseCand */ /**********************************************************************/ void PASCAL CloseCand( HWND hUIWnd) { uOpenCand = 0; ShowCand(hUIWnd, SW_HIDE); return; } /**********************************************************************/ /* DestroyCandWindow */ /**********************************************************************/ void PASCAL DestroyCandWindow( HWND hCandWnd) { HGLOBAL hUIPrivate; LPUIPRIV lpUIPrivate; if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) { // undo the drag border DrawDragBorder(hCandWnd, GetWindowLong(hCandWnd, UI_MOVE_XY), GetWindowLong(hCandWnd, UI_MOVE_OFFSET)); } 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; 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; } dwValue = (lpCursor->y - sImeG.rcCandText.top) / sImeG.yChiCharHi; lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); dwValue = dwValue + lpCandList->dwSelection / lpCandList->dwPageSize * lpCandList->dwPageSize; if (dwValue >= lpCandList->dwCount) { // invalid choice MessageBeep((UINT)-1); } else { NotifyIME(hIMC, NI_SELECTCANDIDATESTR, 0, dwValue); } ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); return; } /**********************************************************************/ /* CandPageDownUP() */ /**********************************************************************/ void PASCAL CandPageDownUP( HWND hCandWnd, UINT uCandDownUp) { HIMC hIMC; LPINPUTCONTEXT lpIMC; LPPRIVCONTEXT lpImcP; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; HDC hDC; HBITMAP hCandHpBmp, hCandUpBmp, hCandDpBmp, hCandEpBmp; HBITMAP hOldBmp; HDC hMemDC; // change candlist hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC); if (!hIMC) { return; } // get lpIMC lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } // get lpImcP lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); if (!lpImcP) { return; } // get lpCandInfo lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { return; } // get lpCandList and init dwCount & dwSelection lpCandList = (LPCANDIDATELIST) ((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); switch(uCandDownUp) { case uCandHome: ChooseCand(0x24, lpIMC, lpCandInfo, lpImcP); NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0); break; case uCandUp: ChooseCand('-', lpIMC, lpCandInfo, lpImcP); NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0); break; case uCandDown: ChooseCand('=', lpIMC, lpCandInfo, lpImcP); NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0); break; case uCandEnd: ChooseCand(0x23, lpIMC, lpCandInfo, lpImcP); NotifyIME(hIMC, NI_CHANGECANDIDATELIST, 0, 0); break; default: break; } ImmUnlockIMCC(lpIMC->hPrivate); ImmUnlockIMCC(lpIMC->hCandInfo); ImmUnlockIMC(hIMC); // draw button down hDC = GetDC(hCandWnd); if ( hDC == NULL ) return; hMemDC = CreateCompatibleDC(hDC); if ( hMemDC == NULL ) { ReleaseDC(hCandWnd, hDC); return; } hOldBmp = NULL; switch(uCandDownUp) { case uCandHome: hCandHpBmp = LoadBitmap(hInst, TEXT("CandHp")); if ( hCandHpBmp != NULL) { hOldBmp = SelectObject(hMemDC, hCandHpBmp); BitBlt(hDC, sImeG.rcCandBTH.left, sImeG.rcCandBTH.top, sImeG.rcCandBTH.right - sImeG.rcCandBTH.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); DeleteObject(hCandHpBmp); } break; case uCandUp: hCandUpBmp = LoadBitmap(hInst, TEXT("CandUp")); if ( hCandUpBmp != NULL ) { hOldBmp = SelectObject(hMemDC, hCandUpBmp); BitBlt(hDC, sImeG.rcCandBTU.left, sImeG.rcCandBTU.top, sImeG.rcCandBTU.right - sImeG.rcCandBTU.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); DeleteObject(hCandUpBmp); } break; case uCandDown: hCandDpBmp = LoadBitmap(hInst, TEXT("CandDp")); if ( hCandDpBmp != NULL) { hOldBmp = SelectObject(hMemDC, hCandDpBmp); BitBlt(hDC, sImeG.rcCandBTD.left, sImeG.rcCandBTD.top, sImeG.rcCandBTD.right - sImeG.rcCandBTD.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); DeleteObject(hCandDpBmp); } break; case uCandEnd: hCandEpBmp = LoadBitmap(hInst, TEXT("CandEp")); if ( hCandEpBmp != NULL) { hOldBmp = SelectObject(hMemDC, hCandEpBmp); BitBlt(hDC, sImeG.rcCandBTE.left, sImeG.rcCandBTE.top, sImeG.rcCandBTE.right - sImeG.rcCandBTE.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); DeleteObject(hCandEpBmp); } break; default: break; } if ( hOldBmp != NULL) SelectObject(hMemDC, hOldBmp); DeleteDC(hMemDC); ReleaseDC(hCandWnd, hDC); 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) && sImeG.IC_Trace) { SetCursor(LoadCursor(hInst, szHandCursor)); MouseSelectCandStr(hCandWnd, &ptCursor); return; } else if (PtInRect(&sImeG.rcCandBTH, ptCursor)) { CandPageDownUP(hCandWnd, uCandHome); return; } else if (PtInRect(&sImeG.rcCandBTU, ptCursor)) { CandPageDownUP(hCandWnd, uCandUp); return; } else if (PtInRect(&sImeG.rcCandBTD, ptCursor)) { CandPageDownUP(hCandWnd, uCandDown); return; } else if (PtInRect(&sImeG.rcCandBTE, ptCursor)) { CandPageDownUP(hCandWnd, uCandEnd); return; } else { SetCursor(LoadCursor(NULL, IDC_SIZEALL)); } } else if (HIWORD(lParam) == WM_LBUTTONUP) { HDC hDC; HBITMAP hCandHBmp, hCandUBmp, hCandDBmp, hCandEBmp; HBITMAP hOldBmp; HDC hMemDC; hDC = GetDC(hCandWnd); hMemDC = CreateCompatibleDC(hDC); if ( hMemDC ) { hCandHBmp = LoadBitmap(hInst, TEXT("CandH")); if ( hCandHBmp ) { hOldBmp = SelectObject(hMemDC, hCandHBmp); BitBlt(hDC, sImeG.rcCandBTH.left, sImeG.rcCandBTH.top, sImeG.rcCandBTH.right - sImeG.rcCandBTH.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOldBmp); DeleteObject(hCandHBmp); } hCandUBmp = LoadBitmap(hInst, TEXT("CandU")); if ( hCandUBmp ) { hOldBmp=SelectObject(hMemDC, hCandUBmp); BitBlt(hDC, sImeG.rcCandBTU.left, sImeG.rcCandBTU.top, sImeG.rcCandBTU.right - sImeG.rcCandBTU.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOldBmp); DeleteObject(hCandUBmp); } hCandDBmp = LoadBitmap(hInst, TEXT("CandD")); if ( hCandDBmp ) { hOldBmp=SelectObject(hMemDC, hCandDBmp); BitBlt(hDC, sImeG.rcCandBTD.left, sImeG.rcCandBTD.top, sImeG.rcCandBTD.right - sImeG.rcCandBTD.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOldBmp); DeleteObject(hCandDBmp); } hCandEBmp = LoadBitmap(hInst, TEXT("CandE")); if ( hCandEBmp ) { hOldBmp=SelectObject(hMemDC, hCandEBmp); BitBlt(hDC, sImeG.rcCandBTE.left, sImeG.rcCandBTE.top, sImeG.rcCandBTE.right - sImeG.rcCandBTE.left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOldBmp); DeleteObject(hCandEBmp); } DeleteDC(hMemDC); } ReleaseDC(hCandWnd, hDC); return; } else { SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0); GetCursorPos(&ptCursor); ScreenToClient(hCandWnd, &ptCursor); if (PtInRect(&sImeG.rcCandText, ptCursor)) { SetCursor(LoadCursor(hInst, szHandCursor)); return; } else if (PtInRect(&sImeG.rcCandBTH, ptCursor)) { SetCursor(LoadCursor(hInst, szHandCursor)); } else if (PtInRect(&sImeG.rcCandBTU, ptCursor)) { SetCursor(LoadCursor(hInst, szHandCursor)); } else if (PtInRect(&sImeG.rcCandBTD, ptCursor)) { SetCursor(LoadCursor(hInst, szHandCursor)); } else if (PtInRect(&sImeG.rcCandBTE, 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; if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) { return (FALSE); } lTmpCursor = GetWindowLong(hCandWnd, UI_MOVE_XY); // calculate the org by the offset lTmpOffset = GetWindowLong(hCandWnd, UI_MOVE_OFFSET); pt.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x; pt.y = (*(LPPOINTS)&lTmpCursor).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); } AdjustCandBoundry(&pt); ScreenToClient(lpIMC->hWnd, &pt); lpIMC->cfCandForm[0].dwStyle |= CFS_CANDIDATEPOS; lpIMC->cfCandForm[0].ptCurrentPos = pt; ImmUnlockIMC(hIMC); PostMessage(hCandWnd, WM_IME_NOTIFY, IMN_SETCANDIDATEPOS, 0x0001); return (TRUE); } /**********************************************************************/ /* UpdateCandWindow() */ /**********************************************************************/ void PASCAL PaintCandWindow( HWND hCandWnd, HDC hDC) { HIMC hIMC; LPINPUTCONTEXT lpIMC; LPCANDIDATEINFO lpCandInfo; LPCANDIDATELIST lpCandList; LPPRIVCONTEXT lpImcP; HGDIOBJ hOldFont; DWORD dwStart, dwEnd; TCHAR szStrBuf[2 * MAXSTRLEN * sizeof(WCHAR) / sizeof(TCHAR) + 1]; int i; HBITMAP hCandIconBmp, hCandInfBmp; HBITMAP hOldBmp, hCandHBmp, hCandUBmp, hCandDBmp, hCandEBmp; HDC hMemDC; hIMC = (HIMC)GetWindowLongPtr(GetWindow(hCandWnd, GW_OWNER), IMMGWLP_IMC); if (!hIMC) { return; } lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); if (!lpIMC) { return; } if (!lpIMC->hCandInfo) { goto UpCandW2UnlockIMC; } lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpIMC->hCandInfo); if (!lpCandInfo) { goto UpCandW2UnlockIMC; } if (!lpIMC->hPrivate) { goto UpCandW2UnlockCandInfo; } lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate); if (!lpImcP) { goto UpCandW2UnlockCandInfo; } // set font if (sImeG.fDiffSysCharSet) { LOGFONT lfFont; ZeroMemory(&lfFont, sizeof(lfFont)); hOldFont = GetCurrentObject(hDC, OBJ_FONT); lfFont.lfHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72); lfFont.lfCharSet = NATIVE_CHARSET; lstrcpy(lfFont.lfFaceName, TEXT("Simsun")); SelectObject(hDC, CreateFontIndirect(&lfFont)); } lpCandList = (LPCANDIDATELIST)((LPBYTE)lpCandInfo + lpCandInfo->dwOffset[0]); dwStart = lpCandList->dwSelection; dwEnd = dwStart + lpCandList->dwPageSize; if (dwEnd > lpCandList->dwCount) { dwEnd = lpCandList->dwCount; } // draw CandWnd Layout if (sImeG.IC_Trace) { RECT rcWnd; GetClientRect(hCandWnd, &rcWnd); DrawConcaveRect(hDC, rcWnd.left, rcWnd.top + UI_CANDINF, rcWnd.right - 1, rcWnd.bottom - 1); } else { RECT rcWnd; GetClientRect(hCandWnd, &rcWnd); DrawConcaveRect(hDC, sImeG.rcCandText.left - 1, rcWnd.top, sImeG.rcCandText.right + 1, rcWnd.bottom - 1); } SetTextColor(hDC, RGB(0x00, 0x00, 0x00)); SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0)); if (sImeG.IC_Trace) { ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top, ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL); szStrBuf[0] = TEXT('1'); szStrBuf[1] = TEXT(':'); for (i = 0; dwStart < dwEnd; dwStart++, i++) { int iLen; iLen = 0; szStrBuf[0] = szDigit[i + CAND_START]; #if defined(COMBO_IME) if(sImeL.dwRegImeIndex == INDEX_GB || sImeL.dwRegImeIndex == INDEX_GBK){ iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])); if (iLen > 10 * 2 / sizeof(TCHAR)) { iLen = 10 * 2 / sizeof(TCHAR); CopyMemory(&szStrBuf[2], ((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])), (iLen - 2) * sizeof(TCHAR)); // maybe not good for UNICODE szStrBuf[iLen] = TEXT('.'); szStrBuf[iLen+1] = TEXT('.'); szStrBuf[iLen+2] = TEXT('\0'); } else { CopyMemory(&szStrBuf[2], (LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]), iLen*sizeof(TCHAR)); } }else if(sImeL.dwRegImeIndex == INDEX_UNICODE){ WORD wCode; wCode = *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]); #ifdef UNICODE szStrBuf[2]= wCode; szStrBuf[3]=TEXT('\0'); #else szStrBuf[2]= LOBYTE(wCode); szStrBuf[3]= HIBYTE(wCode); szStrBuf[4]=TEXT('\0'); #endif iLen = 2/sizeof(TCHAR); } #else iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])); if (iLen > 10 * 2 / sizeof(TCHAR)) { iLen = 10 * 2 / sizeof(TCHAR); CopyMemory(&szStrBuf[2], ((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]), (iLen - 2) * sizeof(TCHAR)); szStrBuf[iLen] = TEXT('.'); szStrBuf[iLen+1] = TEXT('.'); szStrBuf[iLen+2] = TEXT('\0'); } else { CopyMemory(&szStrBuf[2], ((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]), iLen*sizeof(TCHAR)); } #endif //COMBO_IME ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top + i * sImeG.yChiCharHi, (UINT)0, NULL, szStrBuf, iLen + 2, NULL); // QW/GB info { int iMyLen; WORD wCode, wGB; TCHAR AbSeq[5]; TCHAR GbSeq[5]; TCHAR szMyStrBuf[12 * sizeof(WCHAR) / sizeof(TCHAR)]; RECT GBARInfo; #ifdef UNICODE wCode = *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]); AbSeq[0] = wCode; AbSeq[1] = TEXT('\0'); // change the CP_ACP to 936, so that it can work under Multilingul Env. WideCharToMultiByte(NATIVE_ANSI_CP, WC_COMPOSITECHECK, AbSeq, 1, (BYTE*)GbSeq, sizeof(GbSeq), NULL, NULL); wGB = HIBYTE(GbSeq[0]) | (LOBYTE(GbSeq[0]) << 8); wsprintf (GbSeq,TEXT("%04lx"),wGB); // get GB string wGB -= 0xa0a0; wsprintf (AbSeq,TEXT("%02d%02d"),HIBYTE(wGB),LOBYTE(wGB)); #else wCode = *(LPUNAWORD)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]); MultiByteToWideChar(CP_ACP, NULL, &wCode, 2, &wGB, 1); wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8); wsprintf (GbSeq,"%04lx",wCode); // get GB string wCode -= 0xa0a0; wsprintf (AbSeq,"%02d%02d",HIBYTE(wCode),LOBYTE(wCode)); #endif // if (lpImcP->fdwGB & IME_SELECT_GB) { #if defined(COMBO_IME) switch(sImeL.dwRegImeIndex){ case INDEX_GB: lstrcpy (szMyStrBuf,TEXT("(")); lstrcat (szMyStrBuf,GbSeq); lstrcat (szMyStrBuf,TEXT(", ")); lstrcat (szMyStrBuf,AbSeq); lstrcat (szMyStrBuf,TEXT(")")); iMyLen = 12; break; case INDEX_GBK: lstrcpy (szMyStrBuf,TEXT(" ")); lstrcat (szMyStrBuf,TEXT("(")); lstrcat (szMyStrBuf,GbSeq); lstrcat (szMyStrBuf,TEXT(")")); iMyLen = 10; break; case INDEX_UNICODE: //adjust code display info lstrcpy (szMyStrBuf,TEXT("(")); lstrcat (szMyStrBuf,GbSeq); lstrcat (szMyStrBuf,TEXT(", ")); wsprintf (AbSeq,TEXT("%04lx"),wCode); lstrcat (szMyStrBuf, AbSeq); lstrcat (szMyStrBuf,TEXT(")")); iMyLen = lstrlen(szMyStrBuf); break; } #else //COMBO_IME #ifdef GB lstrcpy (szMyStrBuf,TEXT("(")); lstrcat (szMyStrBuf,GbSeq); lstrcat (szMyStrBuf,TEXT(", ")); lstrcat (szMyStrBuf,AbSeq); lstrcat (szMyStrBuf,TEXT(")")); iMyLen = 12; #else lstrcpy (szMyStrBuf,TEXT(" ")); lstrcat (szMyStrBuf,TEXT("(")); lstrcat (szMyStrBuf,GbSeq); lstrcat (szMyStrBuf,TEXT(")")); iMyLen = 10; #endif //GB #endif //COMBO_IME GBARInfo.top = sImeG.rcCandText.top + i * sImeG.yChiCharHi; GBARInfo.left = sImeG.rcCandText.left; GBARInfo.right = sImeG.rcCandText.right; GBARInfo.bottom = sImeG.rcCandText.bottom; DrawText(hDC, szMyStrBuf, lstrlen(szMyStrBuf), &GBARInfo, DT_RIGHT | DT_SINGLELINE); } } } else { int nX; ExtTextOut(hDC, sImeG.rcCandText.left, sImeG.rcCandText.top + 1, ETO_OPAQUE, &sImeG.rcCandText, NULL, 0, NULL); nX = 0; for (i = 0; dwStart < dwEnd; dwStart++, i++) { int iLen; int j, k; TCHAR AnsiStr[MAXCODE+1]; SIZE StrSize; // display numbers AnsiStr[0] = szDigit[i + CAND_START]; AnsiStr[1] = TEXT(':'); AnsiStr[2] = 0; ExtTextOut(hDC, sImeG.rcCandText.left + nX, sImeG.rcCandText.top + 1, ETO_CLIPPED, &sImeG.rcCandText, AnsiStr, lstrlen(AnsiStr), NULL); if(!GetTextExtentPoint(hDC, (LPCTSTR)AnsiStr, lstrlen(AnsiStr), &StrSize)) memset(&StrSize, 0, sizeof(SIZE)); nX += StrSize.cx; // display chinese word and code iLen = lstrlen((LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart])); CopyMemory(szStrBuf, ((LPBYTE)lpCandList + lpCandList->dwOffset[dwStart]), iLen*sizeof(TCHAR)); for(j=0; j 0x100) { #else if(szStrBuf[j] & 0x80) { #endif j++; continue; } break; } k = j-1; for(j=0; jhPrivate); UpCandW2UnlockCandInfo: ImmUnlockIMCC(lpIMC->hCandInfo); UpCandW2UnlockIMC: ImmUnlockIMC(hIMC); return; } /**********************************************************************/ /* CandWndProc() */ /**********************************************************************/ LRESULT CALLBACK CandWndProc( HWND hCandWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: DestroyCandWindow(hCandWnd); break; case WM_SETCURSOR: CandSetCursor(hCandWnd, lParam); break; case WM_MOUSEMOVE: if (GetWindowLong(hCandWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) { POINT ptCursor; 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 { return DefWindowProc(hCandWnd, uMsg, wParam, lParam); } break; case WM_LBUTTONUP: if (!CandButtonUp(hCandWnd)) { return DefWindowProc(hCandWnd, uMsg, wParam, lParam); } break; case WM_IME_NOTIFY: if (wParam == IMN_SETCANDIDATEPOS) { return SetCandPosition(hCandWnd); } break; case WM_PAINT: { HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hCandWnd, &ps); PaintCandWindow(hCandWnd, hDC); EndPaint(hCandWnd, &ps); } break; case WM_MOUSEACTIVATE: return (MA_NOACTIVATE); default: return DefWindowProc(hCandWnd, uMsg, wParam, lParam); } return (0L); }