Example #1
0
/*----------------------------------------------------------------------------*/ 
BOOL	TImm::UnlockIMC(HIMC hImc)
{
	if(_ImmUnlockIMC == NULL) 
	{
		return FALSE;
	}
	else 
	{
		return _ImmUnlockIMC(hImc);
	}
}
Example #2
0
// Obtain the reading string upon WM_IME_NOTIFY/INM_PRIVATE notification.
void CIME::GetPrivateReadingString()
{
	DWORD dwId = GetImeId();
	if(!dwId)
	{
		s_bShowReadingWindow = false;
		return;
	}

	HIMC hImc;
	hImc = ImmGetContext(UIGetHWND());
	if(!hImc)
	{
		s_bShowReadingWindow = false;
		return;
	}

	DWORD dwReadingStrLen = 0;
	DWORD dwErr = 0;
	WCHAR *pwszReadingStringBuffer = NULL;  // Buffer for when the IME supports GetReadingString()
	WCHAR *wstr = 0;
	bool bUnicodeIme = false;  // Whether the IME context component is Unicode.
	INPUTCONTEXT *lpIC = NULL;

	if(_GetReadingString)
	{
		UINT uMaxUiLen;
		BOOL bVertical;
		// Obtain the reading string size
		dwReadingStrLen = _GetReadingString(hImc, 0, NULL, (PINT)&dwErr, &bVertical, &uMaxUiLen);
		if(dwReadingStrLen)
		{
			wstr = pwszReadingStringBuffer = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * dwReadingStrLen);
			if(!pwszReadingStringBuffer)
			{
				// Out of memory. Exit.
				_ImmReleaseContext(UIGetHWND(), hImc);
				return;
			}

			// Obtain the reading string
			dwReadingStrLen = _GetReadingString(hImc, dwReadingStrLen, wstr, (PINT)&dwErr, &bVertical, &uMaxUiLen);
		}

		s_bHorizontalReading = !bVertical;
		bUnicodeIme = true;
	}
	else
	{
		// IMEs that doesn't implement Reading String API

		lpIC = _ImmLockIMC(hImc);

		LPBYTE p = 0;
		switch(dwId)
		{
		case IMEID_CHT_VER42: // New(Phonetic/ChanJie)IME98  : 4.2.x.x // Win98
		case IMEID_CHT_VER43: // New(Phonetic/ChanJie)IME98a : 4.3.x.x // WinMe, Win2k
		case IMEID_CHT_VER44: // New ChanJie IME98b          : 4.4.x.x // WinXP
			p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 24);
			if(!p) break;
			dwReadingStrLen = *(DWORD *)(p + 7 * 4 + 32 * 4);
			dwErr = *(DWORD *)(p + 8 * 4 + 32 * 4);
			wstr = (WCHAR *)(p + 56);
			bUnicodeIme = true;
			break;

		case IMEID_CHT_VER50: // 5.0.x.x // WinME
			p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 3 * 4);
			if(!p) break;
			p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4 + 4*2);
			if(!p) break;
			dwReadingStrLen = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16);
			dwErr = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 + 1*4);
			wstr = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
			bUnicodeIme = false;
			break;

		case IMEID_CHT_VER51: // 5.1.x.x // IME2002(w/OfficeXP)
		case IMEID_CHT_VER52: // 5.2.x.x // (w/whistler)
		case IMEID_CHS_VER53: // 5.3.x.x // SCIME2k or MSPY3 (w/OfficeXP and Whistler)
			p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 4);
			if(!p) break;
			p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
			if(!p) break;
			dwReadingStrLen = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * 2);
			dwErr = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * 2 + 1*4);
			wstr  = (WCHAR *) (p + 1*4 + (16*2+2*4) + 5*4);
			bUnicodeIme = true;
			break;

			// the code tested only with Win 98 SE (MSPY 1.5/ ver 4.1.0.21)
		case IMEID_CHS_VER41:
			{
				int nOffset;
				nOffset = (GetImeId(1) >= 0x00000002) ? 8 : 7;

				p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + nOffset * 4);
				if(!p) break;
				dwReadingStrLen = *(DWORD *)(p + 7*4 + 16*2*4);
				dwErr = *(DWORD *)(p + 8*4 + 16*2*4);
				dwErr = __min(dwErr, dwReadingStrLen);
				wstr = (WCHAR *)(p + 6*4 + 16*2*1);
				bUnicodeIme = true;
				break;
			}

		case IMEID_CHS_VER42: // 4.2.x.x // SCIME98 or MSPY2 (w/Office2k, Win2k, WinME, etc)
			{
				OSVERSIONINFOW osi;
				osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
				GetVersionExW(&osi);

				int nTcharSize = (osi.dwPlatformId == VER_PLATFORM_WIN32_NT) ? sizeof(WCHAR) : sizeof(char);
				p = *(LPBYTE *)((LPBYTE)_ImmLockIMCC(lpIC->hPrivate) + 1*4 + 1*4 + 6*4);
				if(!p) break;
				dwReadingStrLen = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * nTcharSize);
				dwErr = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16 * nTcharSize + 1*4);
				wstr  = (WCHAR *) (p + 1*4 + (16*2+2*4) + 5*4);
				bUnicodeIme = (osi.dwPlatformId == VER_PLATFORM_WIN32_NT) ? true : false;
			}
		}   // switch
	}

	// Copy the reading string to the candidate list first
	s_CandList.awszCandidate[0][0] = 0;
	s_CandList.awszCandidate[1][0] = 0;
	s_CandList.awszCandidate[2][0] = 0;
	s_CandList.awszCandidate[3][0] = 0;
	s_CandList.dwCount = dwReadingStrLen;
	s_CandList.dwSelection = (DWORD)-1; // do not select any char
	if(bUnicodeIme)
	{
		UINT i;
		for(i = 0; i < dwReadingStrLen; ++i) // dwlen > 0, if known IME
		{
			if(dwErr <= i && s_CandList.dwSelection == (DWORD)-1)
			{
				// select error char
				s_CandList.dwSelection = i;
			}

			s_CandList.awszCandidate[i][0] = wstr[i];
			s_CandList.awszCandidate[i][1] = 0;
		}
		s_CandList.awszCandidate[i][0] = 0;
	}
	else
	{
		char *p = (char *)wstr;
		DWORD i, j;
		for(i = 0, j = 0; i < dwReadingStrLen; ++i, ++j) // dwlen > 0, if known IME
		{
			if(dwErr <= i && s_CandList.dwSelection == (DWORD)-1)
			{
				s_CandList.dwSelection = j;
			}
			// Obtain the current code page
			WCHAR wszCodePage[8];
			UINT uCodePage = CP_ACP;  // Default code page
			if(GetLocaleInfoW(MAKELCID(GetLanguage(), SORT_DEFAULT),
				LOCALE_IDEFAULTANSICODEPAGE,
				wszCodePage,
				sizeof(wszCodePage)/sizeof(wszCodePage[0])))
			{
				uCodePage = wcstoul(wszCodePage, NULL, 0);
			}
			MultiByteToWideChar(uCodePage, 0, p + i, IsDBCSLeadByteEx(uCodePage, p[i]) ? 2 : 1,
				s_CandList.awszCandidate[j], 1);
			if(IsDBCSLeadByteEx(uCodePage, p[i]))
				++i;
		}
		s_CandList.awszCandidate[j][0] = 0;
		s_CandList.dwCount = j;
	}
	if(!_GetReadingString)
	{
		_ImmUnlockIMCC(lpIC->hPrivate);
		_ImmUnlockIMC(hImc);
		GetReadingWindowOrientation(dwId);
	}
	_ImmReleaseContext(UIGetHWND(), hImc);

	if(pwszReadingStringBuffer)
		HeapFree(GetProcessHeap(), 0, pwszReadingStringBuffer);

	// Copy the string to the reading string buffer
	if(s_CandList.dwCount > 0)
		s_bShowReadingWindow = true;
	else
		s_bShowReadingWindow = false;
	if(s_bHorizontalReading)
	{
		s_CandList.nReadingError = -1;
		s_wstrReadingString.clear();
		for(UINT i = 0; i < s_CandList.dwCount; ++i)
		{
			if(s_CandList.dwSelection == i)
				s_CandList.nReadingError = s_wstrReadingString.length();
			s_wstrReadingString+=s_CandList.awszCandidate[i];
		}
	}

	s_CandList.dwPageSize = MAX_CANDLIST;
}