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

📄 compui.c

📁 This folder includes IME sample source code for Simplified Chinese IMEs
💻 C
📖 第 1 页 / 共 3 页
字号:

    if (HIWORD(lParam) != WM_LBUTTONDOWN) {
        return;
    }

    // start dragging
    SystemParametersInfo(SPI_GETWORKAREA, 0, &sImeG.rcWorkArea, 0);

    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;
    RECT            rcWorkArea;

    if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) == WINDOW_NOT_DRAG) {
        return (FALSE);
    }

    lTmpCursor = GetWindowLong(hCompWnd, UI_MOVE_XY);

    // calculate the org by the offset
    lTmpOffset = GetWindowLong(hCompWnd, UI_MOVE_OFFSET);

    pt.x = (*(LPPOINTS)&lTmpCursor).x - (*(LPPOINTS)&lTmpOffset).x;
    pt.y = (*(LPPOINTS)&lTmpCursor).y - (*(LPPOINTS)&lTmpOffset).y;

    DrawDragBorder(hCompWnd, lTmpCursor, lTmpOffset);
    SetWindowLong(hCompWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);

    SetWindowLong(hCompWnd, UI_MOVE_XY, lpImeL->nMaxKey);

    ReleaseCapture();

    hUIWnd = GetWindow(hCompWnd, GW_OWNER);

    hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
    if (!hIMC) {
        return (FALSE);
    }

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

#ifdef MUL_MONITOR
    rcWorkArea = ImeMonitorWorkAreaFromWindow(lpIMC->hWnd);
#else
    rcWorkArea = sImeG.rcWorkArea;
#endif

    if (pt.x < rcWorkArea.left) {
        pt.x = rcWorkArea.left;
    } else if (pt.x + lpImeL->xCompWi > rcWorkArea.right) {
        pt.x = rcWorkArea.right - lpImeL->xCompWi;
    }

    if (pt.y < rcWorkArea.top) {
        pt.y = rcWorkArea.top;
    } else if (pt.y + lpImeL->yCompHi > rcWorkArea.bottom) {
        pt.y = rcWorkArea.bottom - lpImeL->yCompHi;
    }

    lpIMC->cfCompForm.dwStyle = CFS_FORCE_POSITION;
    lpIMC->cfCompForm.ptCurrentPos.x = pt.x + lpImeL->cxCompBorder;
    lpIMC->cfCompForm.ptCurrentPos.y = pt.y + lpImeL->cyCompBorder;

    ScreenToClient(lpIMC->hWnd, &lpIMC->cfCompForm.ptCurrentPos);

    ImmUnlockIMC(hIMC);

    // set composition window to the new poosition
    PostMessage(hCompWnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONWINDOW, 0);

    return (TRUE);
}

/**********************************************************************/
/* PaintCompWindow()                                                */
/**********************************************************************/
void PASCAL PaintCompWindow(
    HWND   hUIWnd,
    HWND   hCompWnd,
    HDC    hDC)
{
    HIMC                hIMC;
    LPINPUTCONTEXT      lpIMC;
    HGDIOBJ             hOldFont;
    LPCOMPOSITIONSTRING lpCompStr;
    LPGUIDELINE         lpGuideLine;
    BOOL                fShowString;

    hIMC = (HIMC)GetWindowLongPtr(hUIWnd, IMMGWLP_IMC);
    if (!hIMC) {
        return;
    }

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

    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));
    }

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

    lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
    if (!lpGuideLine) {          
        return;
    }


    // draw CompWnd Layout
    {
      RECT rcWnd;

      GetClientRect(hCompWnd, &rcWnd);
      DrawConcaveRect(hDC,
                      rcWnd.left,
                      rcWnd.top,
                      rcWnd.right - 1,
                      rcWnd.bottom - 1);
    }
    
    SetBkColor(hDC, RGB(0xC0, 0xC0, 0xC0));

    fShowString = (BOOL)0;

    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, RGB(0x80, 0x80, 0x80));
        }

        ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
            ETO_OPAQUE, &lpImeL->rcCompText,
            (LPCTSTR)((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->dwCompStrLen > 0) {
        ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
            ETO_OPAQUE, &lpImeL->rcCompText,
            (LPTSTR)NULL, 0, NULL);
        DrawText(hDC, (LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwCompStrOffset),
                (int)lpCompStr->dwCompStrLen, &lpImeL->rcCompText,
                DT_LEFT | DT_VCENTER | DT_SINGLELINE);
        if (fShowString & IME_STR_ERROR) {
            // red text for error
            //SetTextColor(hDC, RGB(0xFF, 0, 0));
            // light gray background for error
            SetBkColor(hDC, RGB(0x80, 0x80, 0x80));
            ExtTextOut(hDC, lpImeL->rcCompText.left +
                lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2,
                lpImeL->rcCompText.top,
                ETO_CLIPPED, &lpImeL->rcCompText,
                (LPTSTR)((LPBYTE)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, RGB(0x80, 0x80, 0x80));
            ExtTextOut(hDC, lpImeL->rcCompText.left +
                lpCompStr->dwCursorPos * sImeG.xChiCharWi/ 2,
                lpImeL->rcCompText.top,
                ETO_CLIPPED, &lpImeL->rcCompText,
                (LPTSTR)((LPBYTE)lpCompStr + lpCompStr->dwCompStrOffset +
                lpCompStr->dwCursorPos),
                (UINT)lpCompStr->dwCompStrLen - lpCompStr->dwCursorPos, NULL);
        } else {
        }
    } else {
#ifdef CROSSREF
        {    
            LPCANDIDATELIST lpRevCandList;
            LPPRIVCONTEXT       lpImcP;

            lpImcP = (LPPRIVCONTEXT)ImmLockIMCC(lpIMC->hPrivate);
            if (lpImcP) {
                if(lpImcP->hRevCandList){    
                       lpRevCandList = (LPCANDIDATELIST)GlobalLock((HGLOBAL)lpImcP->hRevCandList);
                       if (lpRevCandList != NULL && lpRevCandList->dwCount) {

                        // green text for information
                        SetTextColor(hDC, RGB(0x00, 0x80, 0x00));
                        SetBkColor(hDC, RGB(0xc0, 0xc0, 0xc0));

                        ExtTextOut(hDC, 
                            lpImeL->rcCompText.left, 
                            lpImeL->rcCompText.top,
                            ETO_OPAQUE, 
                            &lpImeL->rcCompText,
                            (LPTSTR)((LPBYTE)lpRevCandList+lpRevCandList->dwOffset[0]), 
                            (int)lstrlen((LPTSTR)((LPBYTE)lpRevCandList + lpRevCandList->dwOffset[0])),
                            NULL);
                               GlobalUnlock((HGLOBAL)lpImcP->hRevCandList);
                        GlobalFree((HGLOBAL)lpImcP->hRevCandList);
                        lpImcP->hRevCandList = 0;
                        goto CrossCodeFinish;
                    }
                }
            }    
            ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
            ETO_OPAQUE, &lpImeL->rcCompText,
            (LPTSTR)NULL, 0, NULL);
CrossCodeFinish:
            ImmUnlockIMCC(lpIMC->hPrivate);
        }
#else
            ExtTextOut(hDC, lpImeL->rcCompText.left, lpImeL->rcCompText.top,
            ETO_OPAQUE, &lpImeL->rcCompText,
            (LPTSTR)NULL, 0, NULL);
#endif
    }

    if (sImeG.fDiffSysCharSet) {
        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);
    hDC = GetDC(hCompWnd);
    PaintCompWindow(hUIWnd, hCompWnd, hDC);
    ReleaseDC(hCompWnd, hDC);
}

/**********************************************************************/
/* CompWndProc()                                                      */
/**********************************************************************/
LRESULT CALLBACK CompWndProc(           // composition window proc
    HWND   hCompWnd,
    UINT   uMsg,
    WPARAM wParam,
    LPARAM lParam)
{
    switch (uMsg) {
    case WM_DESTROY:
        DestroyCompWindow(hCompWnd);
        break;
    case WM_SETCURSOR:
        CompSetCursor(hCompWnd, lParam);
        break;
    case WM_MOUSEMOVE:
        if (GetWindowLong(hCompWnd, UI_MOVE_OFFSET) != WINDOW_NOT_DRAG) {
            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 {
            return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
        }
        break;
    case WM_LBUTTONUP:
        if (!CompButtonUp(hCompWnd)) {
            return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
        }
        break;
    case WM_IME_NOTIFY:
        if (wParam != IMN_SETCOMPOSITIONWINDOW) {
        // 9.8.del
        //} else if (sImeG.IC_Trace) {
        //    SetCompWindow(hCompWnd);
        } else {
            // 9.8.add
            SetCompWindow(hCompWnd);
        }
        break;
    case WM_PAINT:
        {
            HDC         hDC;
            PAINTSTRUCT ps;

            hDC = BeginPaint(hCompWnd, &ps);
            PaintCompWindow(GetWindow(hCompWnd, GW_OWNER), hCompWnd, hDC);
            EndPaint(hCompWnd, &ps);
        }
        break;
    case WM_MOUSEACTIVATE:
        return (MA_NOACTIVATE);
    default:
        return DefWindowProc(hCompWnd, uMsg, wParam, lParam);
    }
    return (0L);
}


⌨️ 快捷键说明

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