📄 imeui.cpp
字号:
dwCandWidth += tx;
}
}
DWORD slotsUsed;
if (g_bReadingWindow && g_dwCount < g_uCandPageSize)
slotsUsed = g_dwCount;
else
slotsUsed = g_uCandPageSize;
// Show candidate list above composition string if there isn't enough room below.
DWORD dwCandHeight;
if (g_bVerticalCand && !(g_bReadingWindow && g_bHorizontalReading))
dwCandHeight = slotsUsed * largest.cy + 2;
else
dwCandHeight = largest.cy + 2;
if ( candY + hCompChar + dwCandHeight > g_screenHeight)
candY -= dwCandHeight;
else
candY += hCompChar;
if ( (int)candY < 0 )
candY = 0;
// Move candidate list horizontally to keep it inside of screen
if ( !g_bReadingWindow && IMEID_LANG( GetImeId() ) == LANG_CHS )
dwCandWidth += dwMarginX * (slotsUsed-1);
else if ( g_bReadingWindow && g_bHorizontalReading )
dwCandWidth = largest.cx + 2 + dwMarginX * 2;
else if ( g_bVerticalCand || g_bReadingWindow )
dwCandWidth = largest.cx + 2 + dwMarginX * 2;
else
dwCandWidth = slotsUsed * (largest.cx + 1) + 1;
if (candX + dwCandWidth > g_screenWidth)
candX = g_screenWidth - dwCandWidth;
if ( (int)candX < 0 )
candX = 0;
// Draw frame and background of candidate list / reading window
int seperateLineX = 0;
int left = candX;
int top = candY;
int right = candX + dwCandWidth;
int bottom = candY + dwCandHeight;
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(left, top, right, bottom, gSkinIME.candColorBorder);
left++;
top++;
right--;
bottom--;
if ( g_bReadingWindow || IMEID_LANG( GetImeId() ) == LANG_CHS )
{
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(left,top, right, bottom, gSkinIME.candColorBase);
}
else if ( g_bVerticalCand )
{
// uDigitWidth is the max width of all digits.
if ( !g_bReadingWindow )
{
seperateLineX = left + dwMarginX + uDigitWidth + uSpaceWidth / 2;
if( ImeUiCallback_DrawRect )
{
ImeUiCallback_DrawRect(left, top, seperateLineX-1, bottom, gSkinIME.candColorBase);
ImeUiCallback_DrawRect(seperateLineX, top, right, bottom, gSkinIME.candColorBase);
}
}
}
else
{
for (i = 0; (DWORD)i < slotsUsed; i++)
{
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(left, top, left + largest.cx, bottom, gSkinIME.candColorBase);
left += largest.cx + 1;
}
}
// Draw candidates / reading strings
candX++;
candY++;
if (g_bReadingWindow && g_bHorizontalReading)
{
int iStart = -1, iEnd = -1, iDummy;
candX += dwMarginX;
// draw background of error character if it exists
TCHAR szTemp[ COUNTOF( g_szReadingString ) ];
if (g_iReadingError >= 0) {
StringCchCopy(szTemp, COUNTOF(szTemp), g_szReadingString);
LPTSTR psz = szTemp + g_iReadingError;
#ifdef UNICODE
psz++;
#else
psz += ( _IsLeadByte( szTemp[g_iReadingError] ) ) ? 2 : 1;
#endif
*psz = 0;
g_CaretInfo.pFont->GetTextExtent(szTemp, (DWORD*)&iEnd, (DWORD*)&iDummy);
TCHAR cSave = szTemp[ g_iReadingError ];
szTemp[g_iReadingError] = 0;
g_CaretInfo.pFont->GetTextExtent(szTemp, (DWORD*)&iStart, (DWORD*)&iDummy);
szTemp[g_iReadingError] = cSave;
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(candX + iStart, candY, candX + iEnd, candY + largest.cy, gSkinIME.candColorBorder);
}
g_CaretInfo.pFont->SetPosition(candX , candY);
g_CaretInfo.pFont->SetColor(g_CaretInfo.colorCand);
g_CaretInfo.pFont->DrawText(g_szReadingString);
// draw error character if it exists
if (iStart >= 0) {
g_CaretInfo.pFont->SetPosition(candX + iStart, candY);
if ( gSkinIME.candColorBase != 0xffffffff || gSkinIME.candColorBorder != 0xff000000 )
g_CaretInfo.pFont->SetColor(g_CaretInfo.colorCand);
else
g_CaretInfo.pFont->SetColor(0xff000000 + (~((0x00ffffff) & g_CaretInfo.colorCand)));
g_CaretInfo.pFont->DrawText(szTemp + g_iReadingError);
}
}
else
{
for (i = 0; i < (int)g_uCandPageSize && (DWORD)i < g_dwCount; i++)
{
if (g_dwSelection == (DWORD)i)
{
if ( gSkinIME.candColorBase != 0xffffffff || gSkinIME.candColorBorder != 0xff000000 )
g_CaretInfo.pFont->SetColor(g_CaretInfo.colorCand);
else
g_CaretInfo.pFont->SetColor(0xff000000 + (~((0x00ffffff) & g_CaretInfo.colorCand)));
if( ImeUiCallback_DrawRect )
{
if ( g_bReadingWindow || g_bVerticalCand )
ImeUiCallback_DrawRect( candX, candY + i * largest.cy,
candX - 1 + dwCandWidth, candY + (i + 1) * largest.cy, gSkinIME.candColorBorder );
else
ImeUiCallback_DrawRect( candX, candY,
candX + adwCandWidth[i], candY + largest.cy, gSkinIME.candColorBorder );
}
}
else
g_CaretInfo.pFont->SetColor(g_CaretInfo.colorCand);
if (g_szCandidate[i][0] != 0)
{
if (!g_bReadingWindow && g_bVerticalCand)
{
TCHAR szOneDigit[2] = { g_szCandidate[i][0], 0 };
int nOneDigit = g_szCandidate[i][0] - TEXT('0');
TCHAR *szCandidateBody = g_szCandidate[i] + 2;
int dx = candX + (seperateLineX - candX - uDigitWidthList[nOneDigit]) / 2;
int dy = candY + largest.cy * i;
g_CaretInfo.pFont->SetPosition( dx, dy );
g_CaretInfo.pFont->DrawText(szOneDigit);
g_CaretInfo.pFont->SetPosition( seperateLineX+dwMarginX, dy );
g_CaretInfo.pFont->DrawText(szCandidateBody);
}
else if ( g_bReadingWindow )
{
g_CaretInfo.pFont->SetPosition( dwMarginX + candX, candY + i * largest.cy );
g_CaretInfo.pFont->DrawText(g_szCandidate[i]);
}
else
{
g_CaretInfo.pFont->SetPosition( uSpaceWidth / 2 + candX, candY );
g_CaretInfo.pFont->DrawText(g_szCandidate[i]);
}
}
if ( !g_bReadingWindow && !g_bVerticalCand )
{
if ( IMEID_LANG( GetImeId() ) == LANG_CHS )
candX += adwCandWidth[i] + dwMarginX;
else
candX += largest.cx + 1;
}
}
}
}
static void CloseCandidateList()
{
g_bCandList = false;
if (!g_bReadingWindow) // fix for Ent Gen #120.
{
g_dwCount = 0;
memset(&g_szCandidate, 0, sizeof(g_szCandidate));
}
}
//
// ProcessIMEMessages()
// Processes IME related messages and acquire information
//
LPARAM ImeUi_ProcessMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM& lParam, bool * trapped )
{
HIMC himc;
int len;
static LPARAM lAlt = 0x80000000, lCtrl = 0x80000000, lShift = 0x80000000;
*trapped = false;
if (!g_bInitialized || g_bDisableImeCompletely)
{
return 0;
}
switch( uMsg )
{
//
// IME Handling
//
case WM_INPUTLANGCHANGE:
OnInputLangChange();
break;
case WM_IME_SETCONTEXT:
//
// We don't want anything to display, so we have to clear lParam and pass it to DefWindowProc().
// Expecially important in Vista to receive IMN_CHANGECANDIDATE correctly.
//
lParam = 0;
break;
case WM_IME_STARTCOMPOSITION:
InitCompStringData();
*trapped = true;
break;
case WM_IME_COMPOSITION:
{
LONG lRet;
TCHAR szCompStr[COUNTOF(g_szCompositionString)];
*trapped = true;
if (NULL == (himc = _ImmGetContext(hWnd)))
{
break;
}
// ResultStr must be processed before composition string.
if ( lParam & GCS_RESULTSTR )
{
lRet = (LONG)_ImmGetCompositionString( himc, GCS_RESULTSTR, szCompStr, COUNTOF( szCompStr ) ) / sizeof(TCHAR);
szCompStr[lRet] = 0;
CancelCompString( g_hwndCurr, false, GetCharCount( szCompStr ) );
StringCchCopy(g_szCompositionString, COUNTOF(g_szCompositionString), szCompStr);
_SendCompString();
InitCompStringData();
}
//
// Reads in the composition string.
//
if ( lParam & GCS_COMPSTR )
{
//////////////////////////////////////////////////////
// Retrieve the latest user-selected IME candidates
lRet = (LONG)_ImmGetCompositionString( himc, GCS_COMPSTR, szCompStr, COUNTOF( szCompStr ) ) / sizeof(TCHAR);
szCompStr[lRet] = 0;
//
// Remove the whole of the string
//
CancelCompString(g_hwndCurr, false, GetCharCount( szCompStr ) );
StringCchCopy(g_szCompositionString, COUNTOF(g_szCompositionString), szCompStr);
lRet = _ImmGetCompositionString( himc, GCS_COMPATTR, g_szCompAttrString, COUNTOF( g_szCompAttrString ) );
g_szCompAttrString[lRet] = 0;
// Older CHT IME uses composition string for reading string
if ( GETLANG() == LANG_CHT && !GetImeId() )
{
int i, chars = lstrlen(g_szCompositionString) / (3 - sizeof(TCHAR));
if (chars)
{
g_dwCount = 4;
g_dwSelection = (DWORD)-1; // don't select any candidate
for (i = 3; i >= 0; i--)
{
if (i > chars - 1)
g_szCandidate[i][0] = 0;
else
{
#ifdef UNICODE
g_szCandidate[i][0] = g_szCompositionString[i];
g_szCandidate[i][1] = 0;
#else
g_szCandidate[i][0] = g_szCompositionString[i*2];
g_szCandidate[i][1] = g_szCompositionString[i*2+1];
g_szCandidate[i][2] = 0;
#endif
}
}
g_uCandPageSize = MAX_CANDLIST;
memset(g_szCompositionString, 0, 8);
g_bReadingWindow = true;
GetReadingWindowOrientation( 0 );
if (g_bHorizontalReading) {
g_iReadingError = -1;
g_szReadingString[0] = 0;
for (i = 0; i < (int)g_dwCount; i++) {
if (g_dwSelection == (DWORD)i)
g_iReadingError = lstrlen(g_szReadingString);
LPCTSTR pszTmp = g_szCandidate[i];
StringCchCat(g_szReadingString, COUNTOF(g_szReadingString), pszTmp);
}
}
}
else
g_dwCount = 0;
}
// get caret position in composition string
g_IMECursorBytes = _ImmGetCompositionString(himc, GCS_CURSORPOS, NULL, 0);
g_IMECursorChars = GetCharCountFromBytes(g_szCompositionString, g_IMECursorBytes);
if (g_dwIMELevel == 3)
{
// send composition string via WM_CHAR
_SendCompString();
// move caret to appropreate location
len = GetCharCount(g_szCompositionString + g_IMECursorBytes);
SendControlKeys(VK_LEFT, len);
}
}
_ImmReleaseContext(hWnd, himc);
}
break;
case WM_IME_ENDCOMPOSITION:
CancelCompString(g_hwndCurr);
InitCompStringData();
break;
case WM_IME_NOTIFY:
switch (wParam)
{
case IMN_SETCONVERSIONMODE:
{
// Disable CHT IME software keyboard.
static bool bNoReentrance = false;
if (LANG_CHT == GETLANG() && !bNoReentrance)
{
bNoReentrance = true;
DWORD dwConvMode, dwSentMode;
_ImmGetConversionStatus( g_himcOrg, &dwConvMode, &dwSentMode );
const DWORD dwFlag = IME_CMODE_SOFTKBD | IME_CMODE_SYMBOL;
if ( dwConvMode & dwFlag )
_ImmSetConversionStatus( g_himcOrg, dwConvMode & ~dwFlag, dwSentMode );
}
bNoReentrance = false;
}
// fall through
case IMN_SETOPENSTATUS:
if (g_bUILessMode)
break;
CheckToggleState();
break;
case IMN_OPENCANDIDATE:
case IMN_CHANGECANDIDATE:
if ( g_bUILessMode )
{
break;
}
{
g_bCandList = true;
*trapped = true;
if (NULL == (himc = _ImmGetContext(hWnd)))
break;
LPCANDIDATELIST lpCandList;
DWORD dwIndex, dwBufLen;
g_bReadingWindow = false;
dwIndex = 0;
dwBufLen = _GetCandidateList( himc, dwIndex, &lpCandList );
if ( dwBufLen )
{
g_dwSelection = lpCandList->dwSelection;
g_dwCount = lpCandList->dwCount;
int startOfPage = 0;
if (GETLANG() == LANG_CHS && GetImeId())
{
// MSPY (CHS IME) has variable number of candidates in candidate window
// find where current page starts, and the size of current page
const int maxCandChar = 18 * (3 - sizeof(TCHAR));
UINT cChars = 0;
UINT i;
for (i = 0; i < g_dwCount; i++)
{
UINT uLen = lstrlen(
(LPTSTR)((DWORD)lpCandList + lpCandList->dwOffset[i])) + (3 - sizeof(TCHAR));
if (uLen + cChars > maxCandChar)
{
if (i > g_dwSelection)
{
break;
}
startOfPage = i;
cChars = uLen;
}
else
{
cChars += uLen;
}
}
g_uCandPageSize = i - startOfPage;
}
else
{
g_uCandPageSize = min( lpCandList->dwPageSize, MAX_CANDLIST );
startOfPage = g_bUILessMode ? lpCandList->dwPageStart : ( g_dwSelection / g_uCandPageSize ) * g_uCandPageSize;
}
g_dwSelection = ( GETLANG() == LANG_CHS && !GetImeId() ) ? (DWORD)-1
: g_dwSelection - startOfPage;
memset(&g_szCandidate, 0, sizeof(g_szCandidate));
for (UINT i = startOfPage, j = 0;
(DWORD)i < lpCandList->dwCount && j < g_uCandPageSize;
i++, j++)
{
ComposeCandidateLine( j,
(LPTSTR)( (DWORD)lpCandList + lpCandList->dwOffset[i] ) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -