📄 compui.cpp
字号:
//
// 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 + -