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

📄 imeui.cpp

📁 声音和图片的加载功能,不过运行起来有点卡
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	}
	else {
		while ( *psz && ( '0' <= *psz && *psz <= '9' ) )
		{
			ulRet = ulRet * 10 + ( *psz - '0' );
			psz++;
		}
	}
	return ulRet;
}

#ifdef UNICODE
#define GetCharCount(psz) lstrlen(psz)
#define GetCharCountFromBytes(psz,iBytes) (iBytes)
static void AW_SendCompString()
{
	int i, iLen;
	if ( ImeUiCallback_OnChar )
	{
		for ( i = 0; g_szCompositionString[i]; i++ )
		{
			ImeUiCallback_OnChar( g_szCompositionString[i] );
		}
		return;
	}

	BYTE szCompStr[COUNTOF(g_szCompositionString) * 2];
	iLen = WideCharToMultiByte(g_uCodePage, 0, g_szCompositionString, -1, 
				(LPSTR)szCompStr, COUNTOF(szCompStr), NULL, NULL) - 1; // don't need to send NUL terminator;
	for (i = 0; i < iLen; i++)
	{
		SendKeyMsg(g_hwndCurr, WM_CHAR, szCompStr[i]);
	}
}

// The following AW_Imm* functions are there to support Win95/98 first version.
// They can be deleted if the game doesn't supports them (i.e. games requires Win98 SE or later).
static DWORD AW_GetCandidateList(HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList)
{
	DWORD dwBufLen = ImmGetCandidateListA( himc, dwIndex, NULL, 0 );
	if (dwBufLen)
	{
		LPCANDIDATELIST pCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(dwBufLen);
		if (pCandList) {
			dwBufLen = ImmGetCandidateListA( himc, dwIndex, pCandList, dwBufLen );
			if (dwBufLen) {
				int i;
				int wideBufLen = 0;
				for (i = 0; i < (int)pCandList->dwCount; i++) {
					wideBufLen += MultiByteToWideChar(g_uCodePage, 0, (LPSTR)pCandList + pCandList->dwOffset[i], -1, NULL, 0) * sizeof(WCHAR);
				}
				wideBufLen += pCandList->dwOffset[0];
				*ppCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(wideBufLen);
				LPCANDIDATELIST pCandListW = *ppCandList;
				memcpy(pCandListW, pCandList, pCandList->dwOffset[0]);
				LPWSTR pwz = (LPWSTR)((LPSTR)pCandListW + pCandList->dwOffset[0]);
				for (i = 0; i < (int)pCandList->dwCount; i++) {
					pCandListW->dwOffset[i] = (LPSTR)pwz - (LPSTR)pCandListW;
					pwz += MultiByteToWideChar(g_uCodePage, 0, (LPSTR)pCandList + pCandList->dwOffset[i], -1, pwz, 256);
				}
				dwBufLen = wideBufLen;
			}
			ImeUiCallback_Free(pCandList);
		}
	}
	return dwBufLen;
}

static LONG WINAPI AW_ImmGetCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
{
	char pszMb[COUNTOF(g_szCompositionString) * 2];
	DWORD dwRet = ImmGetCompositionStringA(himc, dwIndex, pszMb, sizeof(pszMb));
	switch (dwIndex) {
	case GCS_RESULTSTR:
	case GCS_COMPSTR:
		if (dwRet) {
			pszMb[dwRet] = 0;
			dwRet = (DWORD)MultiByteToWideChar(g_uCodePage, 0, pszMb, -1, (LPWSTR)lpBuf, dwBufLen);
			if (dwRet) {
				// Note that ImmGetCompositionString() returns number of bytes copied, regardless of the width of character.
				dwRet = (dwRet - 1) * sizeof(WCHAR);
			}
		}
		break;
	case GCS_CURSORPOS:
		dwRet /= 2;
		break;
	case GCS_COMPATTR: {
		char pszMb2[COUNTOF(g_szCompositionString) * 2];
		DWORD dwRet2 = ImmGetCompositionStringA(himc, GCS_COMPSTR, pszMb2, sizeof(pszMb2));
		if (!dwRet2) {
			dwRet2 = ImmGetCompositionStringA(himc, GCS_RESULTSTR, pszMb2, sizeof(pszMb2));
			if (!dwRet2) {
				return 0;
			}
		}
		char* pOut = (char*)lpBuf;
		for (DWORD i = 0; i < dwRet; i++) {
			*pOut++ = pszMb[i];	// copy attribute
			if (_IsLeadByte(pszMb2[i]))
				i++;
		}
		dwRet = pOut - (char*)lpBuf;
		}
		break;
	}
	return dwRet;
}

#else	// !UNICODE
// returns number of characters from number of bytes
static int GetCharCountFromBytes(LPCSTR pszString, int iBytes)
{
	int iCount = 0;
	int i;
	for (i = 0; pszString[i] && i < iBytes; i++) {
		iCount++;
		if (_IsLeadByte(pszString[i]))
			i++;
	}
	if (i != iBytes)
		iCount = -iCount;	// indicate error - iBytes specifies wrong boundary (i.e. the last byte is leadbyte)
	return iCount;
}

static int GetCharCount(LPTSTR psz)
{
	int i = 0;
	while (*psz) {
		if (_IsLeadByte(*psz)) {
			psz++;
		}
		psz++;
		i++;
	}
	return i;
}

static DWORD WA_GetCandidateList(HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList)
{
	DWORD dwBufLen = ImmGetCandidateListW( himc, dwIndex, NULL, 0 );
	if (dwBufLen)
	{
		LPCANDIDATELIST pCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(dwBufLen);
		if (pCandList)
		{
			dwBufLen = ImmGetCandidateListW( himc, dwIndex, pCandList, dwBufLen );
			if (dwBufLen)
			{
				int i;
				int mbBufLen = 0;
				for ( i = 0; i < (int)pCandList->dwCount; i++ )
				{
					mbBufLen += WideCharToMultiByte( g_uCodePage, 0, (LPWSTR)((LPSTR)pCandList + pCandList->dwOffset[i]), -1, NULL, 0, NULL, NULL );
				}
				mbBufLen += pCandList->dwOffset[0];
				*ppCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(mbBufLen);
				LPCANDIDATELIST pCandListA = *ppCandList;
				memcpy(pCandListA, pCandList, pCandList->dwOffset[0]);
				LPSTR psz = (LPSTR)pCandListA + pCandList->dwOffset[0];
				for (i = 0; i < (int)pCandList->dwCount; i++)
				{
					pCandListA->dwOffset[i] = (LPSTR)psz - (LPSTR)pCandListA;
					psz += WideCharToMultiByte( g_uCodePage, 0, (LPWSTR)((LPSTR)pCandList + pCandList->dwOffset[i]), -1, psz, 256, NULL, NULL );
				}
				dwBufLen = mbBufLen;
			}
			ImeUiCallback_Free(pCandList);
		}
	}
	return dwBufLen;
}

static LONG WINAPI WA_ImmGetCompositionString(HIMC himc, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen)
{
	WCHAR pwzUc[COUNTOF(g_szCompositionString)];
	DWORD dwRet = ImmGetCompositionStringW(himc, dwIndex, pwzUc, sizeof(pwzUc));
	switch (dwIndex) {
	case GCS_RESULTSTR:
	case GCS_COMPSTR:
		if (dwRet) {
			pwzUc[dwRet / sizeof(WCHAR)] = 0;
			dwRet = (DWORD)WideCharToMultiByte( g_uCodePage, 0, pwzUc, -1, (LPSTR)lpBuf, dwBufLen, NULL, NULL );
			if (dwRet) {
				dwRet = dwRet - 1;
			}
		}
		break;

	case GCS_CURSORPOS:
		{
		WCHAR pwzUc2[COUNTOF(g_szCompositionString)];
		DWORD dwRet2 = ImmGetCompositionStringW(himc, GCS_COMPSTR, pwzUc2, sizeof(pwzUc2));
		if (!dwRet2)
		{
			dwRet2 = ImmGetCompositionStringW(himc, GCS_RESULTSTR, pwzUc2, sizeof(pwzUc2));
			if (!dwRet2)
			{
				return 0;
			}
		}
		dwRet2 /= 2;
		//The return value of WideCharToMultiByte() should probably be checked/asserted for success.
		//bounds violation (overflow) 'pszMb[iRc]'
		const int bufSize = COUNTOF(g_szCompositionString) * 2;
		char pszMb[bufSize];
		int iRc = WideCharToMultiByte( g_uCodePage, 0, pwzUc2, dwRet2, pszMb, sizeof( pszMb ), NULL, NULL );
		assert( iRc > 0 ); //WideCharToMultiByte returns 0 if it failed, and it should *never* be negative in the first place
		if (iRc >= bufSize) //if we wrote more bytes than the length of the buffer, we need to terminate it
		{
			pszMb[ bufSize - 1] = 0; //0 terminate the end of the buffer
		}
		else
		{
			pszMb[ iRc ] = 0;
		}
		char* psz = pszMb;
		for ( dwRet2 = 0; dwRet2 != dwRet; dwRet2++ )
		{
			if ( _IsLeadByte( *psz ) )
				psz++;
			psz++;
		}
		dwRet = psz - pszMb;
		}
		break;

	case GCS_COMPATTR: {
		WCHAR pwzUc2[COUNTOF(g_szCompositionString)];
		DWORD dwRet2 = ImmGetCompositionStringW(himc, GCS_COMPSTR, pwzUc2, sizeof(pwzUc2));
		if (!dwRet2)
		{
			dwRet2 = ImmGetCompositionStringW(himc, GCS_RESULTSTR, pwzUc2, sizeof(pwzUc2));
			if (!dwRet2)
			{
				return 0;
			}
		}
		dwRet2 /= 2;
		const int bufSize = COUNTOF(g_szCompositionString) * 2;
		char pszMb[bufSize];
		int iRc = WideCharToMultiByte( g_uCodePage, 0, pwzUc2, dwRet2, pszMb, sizeof( pszMb ), NULL, NULL );
		assert( iRc > 0 ); //WideCharToMultiByte returns 0 if it failed, and it should *never* be negative in the first place
		if (iRc >= bufSize) //if we wrote more bytes than the length of the buffer, we need to terminate it
		{
			pszMb[ bufSize - 1] = 0; //0 terminate the end of the buffer
		}
		else
		{
			pszMb[ iRc ] = 0;
		}
		char* pSrc = (char*)pwzUc;
		char* pOut = (char*)lpBuf;
		for (char* psz = pszMb; *psz; psz++, pSrc++)
		{
			*pOut++ = *pSrc;	// copy attribute
			if ( _IsLeadByte( *psz ) )
			{
				*pOut++ = *pSrc;
				psz++;
			}
			// buffer overrun protection, pOut is incremented in the loop, but not part	of the 
			// loop	invariant test.	To make	the	code more readable we have a test rather than
			// rolling this	into the for stmt.
			if ((DWORD)(pOut-(char*)lpBuf) >=dwBufLen)
				break;
		}
		dwRet = pOut - (char*)lpBuf;
		}
		break;
	}
	return dwRet;
}

#endif	// UNICODE

static void ComposeCandidateLine( int index, LPCTSTR pszCandidate )
{
	LPTSTR psz = g_szCandidate[index];
	*psz++ = (TCHAR)( TEXT( '0' ) + ( ( index + g_iCandListIndexBase ) % 10 ) );
	if ( g_bVerticalCand )
	{
		*psz++ = TEXT( ' ' );
	}
	while ( *pszCandidate && (COUNTOF(g_szCandidate[index]) > (psz-g_szCandidate[index])) )
	{
		*psz++ = *pszCandidate++;
	}
	*psz = 0;
}

static void SendCompString()
{
	int i, iLen = lstrlen(g_szCompositionString);
	if ( ImeUiCallback_OnChar )
	{
		LPCWSTR pwz;
#ifdef UNICODE
		pwz = g_szCompositionString;
#else
		WCHAR szUnicode[ COUNTOF( g_szCompositionString ) ];
		pwz = szUnicode;
		iLen = MultiByteToWideChar( g_uCodePage, 0, g_szCompositionString, -1, szUnicode, COUNTOF(szUnicode) ) - 1;
#endif
		for ( i = 0; i < iLen; i++ )
		{
			ImeUiCallback_OnChar( pwz[i] );
		}
		return;
	}
	for ( i = 0; i < iLen; i++ )
	{
		SendKeyMsg(g_hwndCurr, WM_CHAR,
#ifdef UNICODE
			(WPARAM)g_szCompositionString[i]
#else
			(WPARAM)(BYTE)g_szCompositionString[i]
#endif
			);
	}
}

static DWORD GetCandidateList(HIMC himc, DWORD dwIndex, LPCANDIDATELIST* ppCandList)
{
	DWORD dwBufLen = _ImmGetCandidateList( himc, dwIndex, NULL, 0 );
	if ( dwBufLen )
	{
		*ppCandList = (LPCANDIDATELIST)ImeUiCallback_Malloc(dwBufLen);
		dwBufLen = _ImmGetCandidateList( himc, dwIndex, *ppCandList, dwBufLen );
	}
	return dwBufLen;
}

static void SendControlKeys(UINT vk, UINT num)
{
	if (num == 0)
		return;
	for (UINT i = 0; i < num ; i++) {
		SendKeyMsg_DOWN(g_hwndCurr, vk);
	}
	SendKeyMsg_UP(g_hwndCurr, vk);
}

// send key messages to erase composition string.
static void CancelCompString(HWND hwnd, bool bUseBackSpace = true, int iNewStrLen = 0)
{
	if (g_dwIMELevel != 3)
		return;
	int cc = GetCharCount(g_szCompositionString);
	int i;
	// move caret to the end of composition string
	SendControlKeys(VK_RIGHT, cc - g_IMECursorChars);

	if (bUseBackSpace || g_bInsertMode)
		iNewStrLen = 0;

	// The caller sets bUseBackSpace to false if there's possibility of sending 
	// new composition string to the app right after this function call.
	// 
	// If the app is in overwriting mode and new comp string is 
	// shorter than current one, delete previous comp string 
	// till it's same long as the new one. Then move caret to the beginning of comp string.
	// New comp string will overwrite old one.
	if (iNewStrLen < cc)
	{
		for (i = 0; i < cc - iNewStrLen; i++)
		{
			SendKeyMsg_DOWN(hwnd, VK_BACK);
			SendKeyMsg(hwnd, WM_CHAR, 8);	//Backspace character
		}
		SendKeyMsg_UP(hwnd, VK_BACK);
	}
	else
		iNewStrLen = cc;

	SendControlKeys(VK_LEFT, iNewStrLen);
}

// initialize composition string data.
static void InitCompStringData(void)
{
	g_IMECursorBytes = 0;
	g_IMECursorChars = 0;
	memset(&g_szCompositionString, 0, sizeof(g_szCompositionString));
	memset(&g_szCompAttrString, 0, sizeof(g_szCompAttrString));
}

static void DrawCaret(DWORD x, DWORD y, DWORD height)
{
	if (g_bCaretDraw && ImeUiCallback_DrawRect)
		ImeUiCallback_DrawRect(x, y + gSkinIME.caretYMargin, x + gSkinIME.caretWidth, y + height - gSkinIME.caretYMargin, g_CaretInfo.colorComp);
}

//
// Apps that draw the composition string on top of composition string attribute
// in level 3 support should call this function twice in rendering a frame.
//     // Draw edit box UI;
//     ImeUi_RenderUI(true, false);	// paint composition string attribute;
//     // Draw text in the edit box;
//     ImeUi_RenderUi(false, true); // paint the rest of IME UI;
//
void ImeUi_RenderUI(bool bDrawCompAttr, bool bDrawOtherUi)
{
	if (!g_bInitialized || !g_bImeEnabled || !g_CaretInfo.pFont)
		return;
	if (!bDrawCompAttr && !bDrawOtherUi)
		return;	// error case
	if (g_dwIMELevel == 2) {
		if (!bDrawOtherUi)
			return;	// 1st call for level 3 support
	}

	if (bDrawOtherUi)
		DrawImeIndicator();

	DrawCompositionString( bDrawCompAttr );

	if ( bDrawOtherUi )
		DrawCandidateList();
}

static void DrawImeIndicator()
{
	bool bOn = g_dwState != IMEUI_STATE_OFF;

	IMEUI_VERTEX PieData[17];

⌨️ 快捷键说明

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