⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compui.cpp

📁 基于Pocket PC的简体中文拼音输入法中的用户接口部分的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

#include <windows.h>
#include <imm.h>
#include <sipapi.h>
#include "uipriv.h"
#ifdef WPC
#include "pimemsg.h"
#endif // WPC


/**********************************************************************/
/* GetWorkArea()                                                      */
/**********************************************************************/
void GetWorkArea(LPRECT lprcWorkArea)
{
    SIPINFO  sSipInfo;

    sSipInfo.cbSize = sizeof(SIPINFO);
    sSipInfo.dwImDataSize = 0;
    sSipInfo.pvImData = NULL;
    if (SipGetInfo(&sSipInfo)) {
        *lprcWorkArea = sSipInfo.rcVisibleDesktop;
    } else {
        SystemParametersInfo(SPI_GETWORKAREA, 0, lprcWorkArea, 0);
    }
}

/**********************************************************************/
/* SetCompPosition() : set the composition window position            */
/**********************************************************************/
void SetCompPosition(HWND hCompWnd)
{
    LPUIPRIV        lpUIPriv;
    HIMC            hIMC;
    LPINPUTCONTEXT  lpIMC;
    POINT           ptNew;

    lpUIPriv = (LPUIPRIV)GetWindowLong(hCompWnd, IMMGWL_PRIVATE);
    if (!lpUIPriv) {
        return;
    }

    hIMC = (HIMC)GetWindowLong(hCompWnd, IMMGWL_IMC);
    if (!hIMC) {
        return;
    }

    lpIMC = ImmLockIMC(hIMC);
    if (!lpIMC) {
        return;
    }

    GetWorkArea(&g_sImeUIG.rcWorkArea);

    if (GetCaretPos(&ptNew)){
        ClientToScreen(lpIMC->hWnd, &ptNew);
        if (ptNew.x < g_sImeUIG.rcWorkArea.left) {
            ptNew.x = g_sImeUIG.rcWorkArea.left + CARET_WIDTH;
        } else if (ptNew.x + lpUIPriv->nCompWi > g_sImeUIG.rcWorkArea.right) {
            ptNew.x = g_sImeUIG.rcWorkArea.right - lpUIPriv->nCompWi;
        } else {
            ptNew.x += CARET_WIDTH;
        }
        if (ptNew.y < g_sImeUIG.rcWorkArea.top) {
            ptNew.y = g_sImeUIG.rcWorkArea.top - (g_sImeUIG.cyBorder + COMP_TEXTMARGIN);
        } else if (ptNew.y + lpUIPriv->nCompHi > g_sImeUIG.rcWorkArea.bottom) {
            ptNew.y = g_sImeUIG.rcWorkArea.bottom - lpUIPriv->nCompHi;
        } else {
            ptNew.y -= g_sImeUIG.cyBorder + COMP_TEXTMARGIN;
        }
    } else {
        ptNew.x = g_sImeUIG.rcWorkArea.right - lpUIPriv->nCompWi;
        ptNew.y = g_sImeUIG.rcWorkArea.bottom - lpUIPriv->nCompHi;
    }
    
    if (lpUIPriv->ptComp.x != ptNew.x ||
        lpUIPriv->ptComp.y != ptNew.y) {
        lpUIPriv->ptComp = ptNew;
        SetWindowPos(hCompWnd, NULL, ptNew.x, ptNew.y, 0, 0,
                     SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
    }

    ImmUnlockIMC(hIMC);

    return;
}

/**********************************************************************/
/* PaintCompWindow()                                                  */
/**********************************************************************/
void PaintCompWindow(HWND hUIWnd, HDC hDC)
{
    LPUIPRIV            lpUIPriv;
    HIMC                hIMC;
    LPINPUTCONTEXT      lpIMC;
    LPCOMPOSITIONSTRING lpCompStr;
    LPTSTR              lpszCompStr;
    DWORD               dwCompStrLen;

    lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE);
    if (!lpUIPriv) {
        return;
    }

    hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC);
    if (!hIMC) {
        return;
    }

    lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
    if (!lpIMC) {
        return;
    }

    lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
    if (!lpCompStr) {
        ImmUnlockIMC(hIMC);
        return;
    }

#ifdef WPC
    UINT uData;

    uData = IME_ESC_GET_COMPSTR_LEN;
    if (ImmEscape(NULL, hIMC, IME_ESC_QUERY_SUPPORT, (LPVOID)&uData)) {
        dwCompStrLen = ImmEscape(NULL, hIMC, IME_ESC_GET_COMPSTR_LEN, NULL);
    } else {
        dwCompStrLen = 0;
    }
#else
    dwCompStrLen = lpCompStr->dwCompStrLen;
#endif // WPC

    if (0 == dwCompStrLen) {
        goto PaintCompUnlockIMCC;
    }

    lpszCompStr = (LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwCompStrOffset);

    SetTextColor(hDC, g_sImeUIG.crWindowText);
    SetBkColor(hDC, g_sImeUIG.crWindow);

    ExtTextOut(hDC, COMP_TEXTMARGIN, COMP_TEXTMARGIN, ETO_OPAQUE, &lpUIPriv->rcCompText,
               lpszCompStr, dwCompStrLen, NULL);

    if (dwCompStrLen <= lpCompStr->dwCursorPos) {
        goto PaintCompUnlockIMCC;
    }

    int  nDx[MAX_COMPKEYS + 1];
    int  nFit;
    SIZE size;

    nDx[0] = 0;
    GetTextExtentExPoint(hDC, lpszCompStr, dwCompStrLen, 32767, &nFit, &nDx[1], &size);

    // there is error part
#if 0   // bug 4037. Don't show the invalid tone input
    // red text for error
    SetTextColor(hDC, RGB(0xFF, 0x00, 0x00));
    // dark gray background for error
    SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0));
#else
    // Use window background color as text and background.
    // Error text won't show up on the reading window
    SetTextColor(hDC, g_sImeUIG.crWindow);
    SetBkColor(hDC, g_sImeUIG.crWindow);
#endif

    ExtTextOut(hDC, COMP_TEXTMARGIN + nDx[lpCompStr->dwCursorPos],
               COMP_TEXTMARGIN, ETO_OPAQUE, NULL,
               lpszCompStr + lpCompStr->dwCursorPos,
               dwCompStrLen - lpCompStr->dwCursorPos,
               NULL);

PaintCompUnlockIMCC:

    ImmUnlockIMCC(lpIMC->hCompStr);

    ImmUnlockIMC(hIMC);

    return;
}

/**********************************************************************/
/* OnCompCreate()                                                     */
/**********************************************************************/
static __inline
LRESULT OnCompCreate(HWND hCompWnd, LPCREATESTRUCT lpCS)
{
    HWND                hUIWnd;
    LPUIPRIV            lpUIPriv;
    HIMC                hIMC;
    LPINPUTCONTEXT      lpIMC;
    LPCOMPOSITIONSTRING lpCompStr;
    LPTSTR              lpszCompStr;
    TCHAR               szCompChar[2] = {0};
    int                 nMaxKey, i, nCompBytes;
    HDC                 hDC;
    TEXTMETRIC          tm;

    hUIWnd = GetWindow(hCompWnd, GW_OWNER);
    if (!hUIWnd) {
        return -1L;
    }

    lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE);
    if (!lpUIPriv) {
        return -1L;
    }
    SetWindowLong(hCompWnd, IMMGWL_PRIVATE, (LONG)lpUIPriv);

    hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC);
    if (!lpUIPriv) {
        return -1L;
    }
    SetWindowLong(hCompWnd, IMMGWL_IMC, (LONG)hIMC);

    lpIMC = ImmLockIMC(hIMC);
    if (!lpIMC) {
        return -1L;
    }

    nMaxKey = ImmEscape(NULL, hIMC, IME_ESC_MAX_KEY, (LPVOID)NULL);

    lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC(lpIMC->hCompStr);
    lpszCompStr = (LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwCompStrOffset);
    // There is a problem. If the first composition string is '\0', then this calculation will get trouble.
    // Currently, We don't want to waste time on it. So use fix composition window width.
    for (i=0; i < nMaxKey; i++, lpszCompStr++) {
        if (0 == *lpszCompStr) { continue; }

        szCompChar[0] = *lpszCompStr;
    }
    ImmUnlockIMCC(lpIMC->hCompStr);

    if (0 != szCompChar[0]) {
        nCompBytes = WideCharToMultiByte(CP_ACP, 0, szCompChar, 1, NULL, 0, NULL, NULL);
    } else {
        nCompBytes = 2;
    }

    hDC = GetDC(NULL);
    GetTextMetrics(hDC, &tm);
    ReleaseDC(NULL, hDC);

    lpUIPriv->ptComp.x = lpCS->x;
    lpUIPriv->ptComp.y = lpCS->y;

    lpUIPriv->rcCompText.left = 0;
    lpUIPriv->rcCompText.top = 0;
#ifdef BYTE_WIDTH
    lpUIPriv->rcCompText.right = (nMaxKey * nCompBytes * BYTE_WIDTH) + COMP_TEXTMARGIN * 2;
#else
    // Heck the width of reading window. Add 10% more in prevent wide character
    lpUIPriv->rcCompText.right = (nMaxKey * nCompBytes * tm.tmAveCharWidth) * 13 / 10 + COMP_TEXTMARGIN * 2;
#endif // FIX_COMPWIDTH
    lpUIPriv->rcCompText.bottom = tm.tmHeight + COMP_TEXTMARGIN * 2;

    lpUIPriv->nCompWi = lpUIPriv->rcCompText.right + g_sImeUIG.cxBorder * 2;
    lpUIPriv->nCompHi = lpUIPriv->rcCompText.bottom + g_sImeUIG.cxBorder * 2;

    return 0L;
}

/**********************************************************************/
/* OnCompDestroy()                                                    */
/**********************************************************************/
static __inline
LRESULT OnCompDestroy(HWND hCompWnd)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -