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

📄 imeui.cpp

📁 声音和图片的加载功能,不过运行起来有点卡
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			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 + -