|
|
/**************************************************************************\
* Module Name: jtranmsg.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * This module contains all the code for the Japanese translation subroutine. * * History: * 15-Aug-1995 kazum \**************************************************************************/ #include "precomp.h"
#pragma hdrstop
UINT JTransCompositionA( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStrA, PTRANSMSG pTransMsgSrc, PTRANSMSG pTransMsgDest );
UINT JTransCompositionW( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStrW, PTRANSMSG pTransMsgSrc, PTRANSMSG pTransMsgDest );
DWORD CompStrWToUndetW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPUNDETERMINESTRUCT lpUndetW );
DWORD CompStrWToUndetA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPUNDETERMINESTRUCT lpUndetA );
DWORD CompStrWToStringExW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPSTRINGEXSTRUCT lpStringExW );
DWORD CompStrWToStringExA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPSTRINGEXSTRUCT lpStringExA );
DWORD CompStrWToStringW( LPCOMPOSITIONSTRING lpCompStrW, LPWSTR lpStringW );
DWORD CompStrWToStringA( LPCOMPOSITIONSTRING lpCompStrW, LPSTR lpStringA );
VOID CompStrWToCharW( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrW );
VOID CompStrWToCharA( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrW );
DWORD CompStrAToUndetA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPUNDETERMINESTRUCT lpUndetA, DWORD dwUndetABufferSize );
DWORD CompStrAToUndetW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPUNDETERMINESTRUCT lpUndetW, DWORD dwUndetWBufferSize );
DWORD CompStrAToStringExA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPSTRINGEXSTRUCT lpStringExA, DWORD dwStringExABufferSize );
DWORD CompStrAToStringExW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPSTRINGEXSTRUCT lpStringExW, DWORD dwStringExWBufferSize );
DWORD CompStrAToStringA( LPCOMPOSITIONSTRING lpCompStrA, LPSTR lpStringA, DWORD dwStringABufferSize );
DWORD CompStrAToStringW( LPCOMPOSITIONSTRING lpCompStrA, LPWSTR lpStringW, DWORD dwStringWBufferSize );
VOID CompStrAToCharA( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrA );
VOID CompStrAToCharW( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrA );
UINT JTransCompositionA( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStrA, PTRANSMSG pTransMsgSrc, PTRANSMSG pTransMsgDest ) { UINT i = 0; int iNum = 0; DWORD dwSize; HWND hWnd; WORD wTextLen = 0; BOOL fDoneUndet = FALSE; BOOL fDoneDet = FALSE; DWORD dwGCS; BOOL bAnsiWnd;
hWnd = (HWND)lpIMC->hWnd;
if (!IsWindow(hWnd)) return 0;
bAnsiWnd = (! IsWindowUnicode(hWnd)) ? TRUE : FALSE;
dwGCS = (DWORD)pTransMsgSrc->lParam;
if (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) { if (bAnsiWnd) { dwSize = CompStrAToUndetA(dwGCS, lpCompStrA, NULL, 0); if (dwSize != 0) { HGLOBAL hUndetA = NULL; LPUNDETERMINESTRUCT lpUndetA;
if (hUndetA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpUndetA = (LPUNDETERMINESTRUCT)GlobalLock(hUndetA)) { if (CompStrAToUndetA(dwGCS, lpCompStrA, lpUndetA, dwSize)) { fDoneUndet = TRUE; GlobalUnlock(hUndetA);
if (SendMessageA(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetA)) { GlobalFree(hUndetA); return 0; } } else GlobalUnlock(hUndetA); } GlobalFree(hUndetA); } } } else { dwSize = CompStrAToUndetW(dwGCS, lpCompStrA, NULL, 0); if (dwSize != 0) { HGLOBAL hUndetW = NULL; LPUNDETERMINESTRUCT lpUndetW;
if (hUndetW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpUndetW = (LPUNDETERMINESTRUCT)GlobalLock(hUndetW)) { if (CompStrAToUndetW(dwGCS, lpCompStrA, lpUndetW, dwSize)) { fDoneUndet = TRUE; GlobalUnlock(hUndetW);
if (SendMessageW(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetW)) { GlobalFree(hUndetW); return 0; } } else GlobalUnlock(hUndetW); } GlobalFree(hUndetW); } } } }
//
// This is generate result string routine.
// This should be same as WINNLSSendString of WIN3.1.
//
if (dwGCS & GCS_RESULTSTR) { //
// Can we generate IR_STRINGEX ?
//
if (dwGCS & GCS_RESULTREADSTR) { if (bAnsiWnd) { dwSize = CompStrAToStringExA(dwGCS, lpCompStrA, NULL, 0); if (dwSize != 0) { HGLOBAL hStringExA = NULL; LPSTRINGEXSTRUCT lpStringExA;
if (hStringExA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringExA = (LPSTRINGEXSTRUCT)GlobalLock(hStringExA)) { if (CompStrAToStringExA(dwGCS, lpCompStrA, lpStringExA, dwSize)) { GlobalUnlock(hStringExA);
if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExA)) { GlobalFree(hStringExA); fDoneDet = TRUE; goto jtc_exit_30; } } else GlobalUnlock(hStringExA); } GlobalFree(hStringExA); } } } else { dwSize = CompStrAToStringExW(dwGCS, lpCompStrA, NULL, 0); if (dwSize != 0) { HGLOBAL hStringExW = NULL; LPSTRINGEXSTRUCT lpStringExW;
if (hStringExW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringExW = (LPSTRINGEXSTRUCT)GlobalLock(hStringExW)) { if (CompStrAToStringExW(dwGCS, lpCompStrA, lpStringExW, dwSize)) { GlobalUnlock(hStringExW);
if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExW)) { GlobalFree(hStringExW); fDoneDet = TRUE; goto jtc_exit_30; } } else GlobalUnlock(hStringExW); } GlobalFree(hStringExW); } } } }
//
// generate IR_STRING
//
if (bAnsiWnd) { dwSize = CompStrAToStringA(lpCompStrA, NULL, 0); if (dwSize != 0) { HGLOBAL hStringA = NULL; LPSTR lpStringA;
if (hStringA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringA = (LPSTR)GlobalLock(hStringA)) { if (CompStrAToStringA(lpCompStrA, lpStringA, dwSize)) { GlobalUnlock(hStringA);
if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringA)) { GlobalFree(hStringA); fDoneDet = TRUE; goto jtc_exit_30; } } else GlobalUnlock(hStringA); } GlobalFree(hStringA); } } else { return 0; } } else { dwSize = CompStrAToStringW(lpCompStrA, NULL, 0); if (dwSize != 0) { HGLOBAL hStringW = NULL; LPWSTR lpStringW;
if (hStringW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringW = (LPWSTR)GlobalLock(hStringW)) { if (CompStrAToStringW(lpCompStrA, lpStringW, dwSize)) { GlobalUnlock(hStringW);
if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringW)) { GlobalFree(hStringW); fDoneDet = TRUE; goto jtc_exit_30; } } else GlobalUnlock(hStringW); } GlobalFree(hStringW); } } else { return 0; } }
//
// generate IR_DBCSCHAR/IR_STRINGSTART/WM_CHAR/IR_STRINGEND
//
if (bAnsiWnd) { CompStrAToCharA(hWnd, lpCompStrA); } else { CompStrAToCharW(hWnd, lpCompStrA); }
fDoneDet = TRUE; }
if (!fDoneUndet && !fDoneDet) { *pTransMsgDest = *pTransMsgSrc; iNum++; }
jtc_exit_30:
if (!fDoneUndet && fDoneDet && (dwGCS & GCS_COMPSTR)) { pTransMsgDest->message = pTransMsgSrc->message; pTransMsgDest->wParam = pTransMsgSrc->wParam; pTransMsgDest->lParam = (LPARAM)(dwGCS & ~(GCS_RESULT | GCS_RESULTREAD)); iNum++; }
return iNum; }
UINT JTransCompositionW( LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStrW, PTRANSMSG pTransMsgSrc, PTRANSMSG pTransMsgDest ) { UINT i = 0; int iNum = 0; DWORD dwSize; HWND hWnd; WORD wTextLen = 0; BOOL fDoneUndet = FALSE; BOOL fDoneDet = FALSE; DWORD dwGCS; BOOL bAnsiWnd;
hWnd = (HWND)lpIMC->hWnd;
if (!IsWindow(hWnd)) return 0;
bAnsiWnd = (! IsWindowUnicode(hWnd)) ? TRUE : FALSE;
dwGCS = (DWORD)pTransMsgSrc->lParam;
if (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) { if (bAnsiWnd) { dwSize = CompStrWToUndetA(dwGCS, lpCompStrW, NULL); if (dwSize != 0) { HGLOBAL hUndetA = NULL; LPUNDETERMINESTRUCT lpUndetA;
if (hUndetA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpUndetA = (LPUNDETERMINESTRUCT)GlobalLock(hUndetA)) { CompStrWToUndetA(dwGCS, lpCompStrW, lpUndetA); fDoneUndet = TRUE; GlobalUnlock(hUndetA);
if (SendMessageA(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetA)) { GlobalFree(hUndetA); return 0; } } GlobalFree(hUndetA); } } } else { dwSize = CompStrWToUndetW(dwGCS, lpCompStrW, NULL); if (dwSize != 0) { HGLOBAL hUndetW = NULL; LPUNDETERMINESTRUCT lpUndetW;
if (hUndetW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpUndetW = (LPUNDETERMINESTRUCT)GlobalLock(hUndetW)) { CompStrWToUndetW(dwGCS, lpCompStrW, lpUndetW); fDoneUndet = TRUE; GlobalUnlock(hUndetW);
if (SendMessageW(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetW)) { GlobalFree(hUndetW); return 0; } } GlobalFree(hUndetW); } } } }
//
// This is generate result string routine.
// This should be same as WINNLSSendString of WIN3.1.
//
if (dwGCS & GCS_RESULTSTR) { //
// Can we generate IR_STRINGEX ?
//
if (dwGCS & GCS_RESULTREADSTR) { if (bAnsiWnd) { dwSize = CompStrWToStringExA(dwGCS, lpCompStrW, NULL); if (dwSize != 0) { HGLOBAL hStringExA = NULL; LPSTRINGEXSTRUCT lpStringExA;
if (hStringExA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringExA = (LPSTRINGEXSTRUCT)GlobalLock(hStringExA)) { CompStrWToStringExA(dwGCS, lpCompStrW, lpStringExA); GlobalUnlock(hStringExA);
if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExA)) { GlobalFree(hStringExA); fDoneDet = TRUE; goto jtc_exit_30; } } GlobalFree(hStringExA); } } } else { dwSize = CompStrWToStringExW(dwGCS, lpCompStrW, NULL); if (dwSize != 0) { HGLOBAL hStringExW = NULL; LPSTRINGEXSTRUCT lpStringExW;
if (hStringExW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringExW = (LPSTRINGEXSTRUCT)GlobalLock(hStringExW)) { CompStrWToStringExW(dwGCS, lpCompStrW, lpStringExW); GlobalUnlock(hStringExW);
if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExW)) { GlobalFree(hStringExW); fDoneDet = TRUE; goto jtc_exit_30; } } GlobalFree(hStringExW); } } } }
//
// generate IR_STRING
//
if (bAnsiWnd) { dwSize = CompStrWToStringA(lpCompStrW, NULL); if (dwSize != 0) { HGLOBAL hStringA = NULL; LPSTR lpStringA;
if (hStringA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringA = (LPSTR)GlobalLock(hStringA)) { CompStrWToStringA(lpCompStrW, lpStringA); GlobalUnlock(hStringA);
if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringA)) { GlobalFree(hStringA); fDoneDet = TRUE; goto jtc_exit_30; } } GlobalFree(hStringA); } } else { return 0; } } else { dwSize = CompStrWToStringW(lpCompStrW, NULL); if (dwSize != 0) { HGLOBAL hStringW = NULL; LPWSTR lpStringW;
if (hStringW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) { if (lpStringW = (LPWSTR)GlobalLock(hStringW)) { CompStrWToStringW(lpCompStrW, lpStringW); GlobalUnlock(hStringW);
if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringW)) { GlobalFree(hStringW); fDoneDet = TRUE; goto jtc_exit_30; } } GlobalFree(hStringW); } } else { return 0; } }
//
// generate IR_DBCSCHAR/IR_STRINGSTART/WM_CHAR/IR_STRINGEND
//
if (bAnsiWnd) { CompStrWToCharA(hWnd, lpCompStrW); } else { CompStrWToCharW(hWnd, lpCompStrW); }
fDoneDet = TRUE; }
if (!fDoneUndet && !fDoneDet) { *pTransMsgDest = *pTransMsgSrc; iNum++; }
jtc_exit_30:
if (!fDoneUndet && fDoneDet && (dwGCS & GCS_COMPSTR)) { pTransMsgDest->message = pTransMsgSrc->message; pTransMsgDest->wParam = pTransMsgSrc->wParam; pTransMsgDest->lParam = (LPARAM)(dwGCS & ~(GCS_RESULT | GCS_RESULTREAD)); iNum++; }
return iNum; }
UINT WINNLSTranslateMessageJ( UINT uiNumMsg, PTRANSMSG pTransMsg, LPINPUTCONTEXT lpIMC, LPCOMPOSITIONSTRING lpCompStr, BOOL bAnsiIMC )
/*++
Routine Description:
Arguments:
Return Value:
--*/
{ PTRANSMSG pTransMsgBuf, pTransMsgTemp; UINT uiNewNum = 0; UINT uiTempNum; DWORD dwTempSize; HWND hDefIMEWnd; UINT i; BOOL bAnsiWnd;
hDefIMEWnd = ImmGetDefaultIMEWnd((HWND)lpIMC->hWnd);
bAnsiWnd = (! IsWindowUnicode(lpIMC->hWnd)) ? TRUE : FALSE;
dwTempSize = uiNumMsg * sizeof(TRANSMSG);
//
// Allocate one more TRANSMSG and ZEROINIT the whole thing!
//
pTransMsgBuf = (PTRANSMSG)ImmLocalAlloc( HEAP_ZERO_MEMORY, dwTempSize + sizeof(TRANSMSG) ); if ( pTransMsgBuf == NULL ) goto wtmsg2_j_10;
RtlCopyMemory(pTransMsgBuf, pTransMsg, dwTempSize); pTransMsgTemp = pTransMsgBuf;
//
// When MCW_HIDDEN mode, WM_IME_ENDCOMPOSITION will be translated to
// IR_UNDETERMINE with 0 string. So that, this message have to be
// generated after all messages.
//
if (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) {
for (i = 0; i < uiNumMsg; i++, pTransMsgTemp++) { if (pTransMsgTemp->message == WM_IME_ENDCOMPOSITION) { break; } }
if (pTransMsgTemp->message == WM_IME_ENDCOMPOSITION) {
PTRANSMSG pTransMsgSrc = pTransMsgTemp + 1;
while (pTransMsgSrc->message != 0) { *pTransMsgTemp++ = *pTransMsgSrc++; }
pTransMsgTemp->message = WM_IME_ENDCOMPOSITION; pTransMsgTemp->wParam = 0L; pTransMsgTemp->lParam = 0L;
}
pTransMsgTemp = pTransMsgBuf; }
while (pTransMsgTemp->message != 0) {
switch (pTransMsgTemp->message) { case WM_IME_COMPOSITION:
if (bAnsiIMC) uiTempNum = JTransCompositionA(lpIMC,lpCompStr,pTransMsgTemp,pTransMsg); else uiTempNum = JTransCompositionW(lpIMC,lpCompStr,pTransMsgTemp,pTransMsg);
uiNewNum += uiTempNum; pTransMsg += uiTempNum;
if ( !(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) ) { if ( lpIMC->cfCompForm.dwStyle != CFS_DEFAULT ) { SendMessage((HWND)lpIMC->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0L); } }
break;
case WM_IME_STARTCOMPOSITION:
if ( !(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) ) { if ( lpIMC->cfCompForm.dwStyle != CFS_DEFAULT ) { SendMessage((HWND)lpIMC->hWnd, WM_IME_REPORT, IR_OPENCONVERT, 0L); }
*pTransMsg++ = *pTransMsgTemp; uiNewNum++; }
break;
case WM_IME_ENDCOMPOSITION:
if ( !(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) ) { if ( lpIMC->cfCompForm.dwStyle != CFS_DEFAULT ) { SendMessage((HWND)lpIMC->hWnd, WM_IME_REPORT, IR_CLOSECONVERT, 0L); }
*pTransMsg++ = *pTransMsgTemp; uiNewNum++;
} else {
HWND hWnd = (HWND)lpIMC->hWnd; HGLOBAL hUndet = 0L;
if (hUndet = GlobalAlloc(GHND | GMEM_SHARE, sizeof(UNDETERMINESTRUCT))) { if (! IsWindowUnicode(lpIMC->hWnd)) SendMessageA(hWnd,WM_IME_REPORT, IR_UNDETERMINE, (LPARAM)hUndet); else SendMessageW(hWnd,WM_IME_REPORT, IR_UNDETERMINE, (LPARAM)hUndet);
GlobalFree(hUndet); } }
break;
case WM_IME_NOTIFY:
switch (pTransMsgTemp->wParam) { case IMN_OPENCANDIDATE:
//
// When 3.1 Application want to set MCW_HIDDEN,
// the candidate window of Chicago IME go way
// from the restangle of the composition string
// that will be drawn by the application.
//
if (IsWindow((HWND)lpIMC->hWnd) && (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN)) { CANDIDATEFORM cfCandForm; DWORD i; DWORD dwNumCand = 0;
for (i = 0; i < 32; i++) { //
// Only the opened candidate should be updated.
//
if (!(pTransMsgTemp->lParam & (01L << i))) continue;
cfCandForm.dwIndex = i; cfCandForm.dwStyle = CFS_EXCLUDE; cfCandForm.ptCurrentPos = lpIMC->cfCompForm.ptCurrentPos; cfCandForm.rcArea = lpIMC->cfCompForm.rcArea; SendMessage(hDefIMEWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, (LPARAM)(LPCANDIDATEFORM)&cfCandForm); } }
break;
default : break; }
if (!(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN)) { *pTransMsg++ = *pTransMsgTemp; uiNewNum++; } else { //
// For win31 apps who set MCW_HIDDEN, we won't give them
// IMN_OPENCANDIDATE here. Instead, send it directly to the
// default IME window.
//
SendMessage( hDefIMEWnd, pTransMsgTemp->message, pTransMsgTemp->wParam, pTransMsgTemp->lParam ); }
break;
default : *pTransMsg++ = *pTransMsgTemp; uiNewNum++; break; }
pTransMsgTemp++; }
ImmLocalFree(pTransMsgBuf);
wtmsg2_j_10: return (uiNewNum); }
DWORD CompStrAToUndetA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPUNDETERMINESTRUCT lpUndetA, DWORD dwUndetABufferSize )
/*++
Routine Description:
Convert composition string (ANSI) to undetermine string (ANSI).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; UINT i;
dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) + DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(CHAR))) + DWORD_ALIGN((lpCompStrA->dwResultClauseLen+1)) + DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(CHAR))) + DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen+1)) + DWORD_ALIGN((lpCompStrA->dwCompAttrLen+1)) + DWORD_ALIGN(((lpCompStrA->dwCompStrLen+1) * sizeof(CHAR)));
if (lpUndetA == NULL) { return dwSize; }
if (dwSize > dwUndetABufferSize) { // lpUndetA buffer is too small.
return 0; }
// Set actual lpUndetA buffer size in dwSize.
dwSize = dwUndetABufferSize;
dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1)); lpUndetA->dwSize = dwSize;
if (dwGCS & GCS_COMPSTR) { if (dwSize < dwPos) { // lpUndetA buffer is too small.
return 0; } if (lpCompStrA->dwCompStrLen * sizeof(CHAR) > dwSize - dwPos) { // lpUndetA buffer is too small.
return 0; }
lpUndetA->uUndetTextLen = lpCompStrA->dwCompStrLen; lpUndetA->uUndetTextPos = dwPos; memcpy((PBYTE)lpUndetA + dwPos, (PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset, lpCompStrA->dwCompStrLen * sizeof(CHAR) ); *(LPSTR)((PBYTE)lpUndetA + dwPos + lpCompStrA->dwCompStrLen*sizeof(CHAR)) = '\0'; dwPos += DWORD_ALIGN(((lpUndetA->uUndetTextLen+1)*sizeof(CHAR)));
// Sometime Chicago IME does not generate GCS_COMPATTR
// with GCS_COMPSTR. But uUndetAttrPos should be filled
// when the UndetText is updated.
if (lpCompStrA->dwCompAttrLen && !(dwGCS & GCS_COMPATTR)) dwGCS |= GCS_COMPATTR; }
if (dwGCS & GCS_COMPATTR) { if (dwSize < dwPos) { // lpUndetA buffer is too small.
return 0; } if (lpCompStrA->dwCompAttrLen > dwSize - dwPos) { // lpUndetA buffer is too small.
return 0; }
lpUndetA->uUndetAttrPos = dwPos; memcpy((PBYTE)lpUndetA + dwPos, (PBYTE)lpCompStrA + lpCompStrA->dwCompAttrOffset, lpCompStrA->dwCompAttrLen ); dwPos += DWORD_ALIGN((lpUndetA->uUndetTextLen + 1)); }
if (dwGCS & GCS_CURSORPOS) { lpUndetA->uCursorPos = lpCompStrA->dwCursorPos; }
if (dwGCS & GCS_DELTASTART) { lpUndetA->uDeltaStart = lpCompStrA->dwDeltaStart; }
if (dwGCS & GCS_RESULTSTR) { if (dwSize < dwPos) { // lpUndetA buffer is too small.
return 0; } if (lpCompStrA->dwResultStrLen * sizeof(CHAR) > dwSize - dwPos) { // lpUndetA buffer is too small.
return 0; }
lpUndetA->uDetermineTextLen = lpCompStrA->dwResultStrLen; lpUndetA->uDetermineTextPos = dwPos; memcpy((PBYTE)lpUndetA + dwPos, (PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset, lpCompStrA->dwResultStrLen * sizeof(CHAR) ); *(LPSTR)((PBYTE)lpUndetA + dwPos + lpCompStrA->dwResultStrLen*sizeof(CHAR)) = '\0'; dwPos += DWORD_ALIGN(((lpUndetA->uDetermineTextLen + 1)*sizeof(CHAR))); }
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrA->dwResultClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseAPos;
if (dwSize < dwPos) { // lpUndetA buffer is too small.
return 0; }
dwClauseAPos = dwPos;
lpUndetA->uDetermineDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpUndetA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset); for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++) { *lpw++ = *lpdw++; dwClauseAPos += sizeof(*lpw); if (dwSize < dwClauseAPos) { // lpUndetA buffer is too small.
return 0; } }
dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1)); }
if (dwGCS & GCS_RESULTREADSTR) { if (dwSize < dwPos) { // lpUndetA buffer is too small.
return 0; } if (lpCompStrA->dwResultReadStrLen * sizeof(CHAR) > dwSize - dwPos) { // lpUndetA buffer is too small.
return 0; }
lpUndetA->uYomiTextLen = lpCompStrA->dwResultReadStrLen; lpUndetA->uYomiTextPos = dwPos; memcpy((PBYTE)lpUndetA + dwPos, (PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset, lpCompStrA->dwResultReadStrLen * sizeof(CHAR) ); *(LPSTR)((PBYTE)lpUndetA + dwPos + lpCompStrA->dwResultReadStrLen*sizeof(CHAR)) = '\0'; dwPos += DWORD_ALIGN(((lpUndetA->uYomiTextLen + 1)*sizeof(CHAR))); }
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrA->dwResultReadClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseAPos;
if (dwSize < dwPos) { // lpUndetA buffer is too small.
return 0; }
dwClauseAPos = dwPos;
lpUndetA->uYomiDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpUndetA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset); for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++) { *lpw++ = *lpdw++; dwClauseAPos += sizeof(*lpw); if (dwSize < dwClauseAPos) { // lpUndetA buffer is too small.
return 0; } }
dwPos += DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen + 1)); }
return dwSize; }
DWORD CompStrAToUndetW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPUNDETERMINESTRUCT lpUndetW, DWORD dwUndetWBufferSize )
/*++
Routine Description:
Convert composition string (ANSI) to undetermine string (Unicode).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; UINT i;
dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) + DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN((lpCompStrA->dwResultClauseLen+1)) + DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen+1)) + DWORD_ALIGN((lpCompStrA->dwCompAttrLen * 2)) + DWORD_ALIGN(((lpCompStrA->dwCompStrLen+1) * sizeof(WCHAR)));
if (lpUndetW == NULL) { return dwSize; }
if (dwSize > dwUndetWBufferSize) { // lpUndetW buffer is too small.
return 0; }
// Set actual lpUndetW buffer size in dwSize.
dwSize = dwUndetWBufferSize;
dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1)); lpUndetW->dwSize = dwSize;
if (dwGCS & GCS_COMPSTR) { if (dwSize < dwPos) { // lpUndetW buffer is too small.
return 0; }
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset), // src
(INT)lpCompStrA->dwCompStrLen, (LPWSTR)((PBYTE)lpUndetW + dwPos), // dest
(INT)(dwSize - dwPos)/sizeof(WCHAR)); // Specifies the size, in wide characters.
if (i >= (dwSize - dwPos)/sizeof(WCHAR)) { // lpUndetW buffer doesn't hold NULL character terminator.
return 0; }
((LPWSTR)((PBYTE)lpUndetW + dwPos))[i] = L'\0'; lpUndetW->uUndetTextLen = i; lpUndetW->uUndetTextPos = dwPos; dwPos += DWORD_ALIGN(((lpUndetW->uUndetTextLen + 1)*sizeof(WCHAR)));
// Sometime Chicago IME does not generate GCS_COMPATTR
// with GCS_COMPSTR. But uUndetAttrPos should be filled
// when the UndetText is updated.
if (lpCompStrA->dwCompAttrLen && !(dwGCS & GCS_COMPATTR)) dwGCS |= GCS_COMPATTR; }
if (dwGCS & GCS_COMPATTR) { if (lpUndetW->uUndetTextLen != 0) { LPWSTR lpwszUndetText; PBYTE lpAttrW; PBYTE lpAttrA; WCHAR wc; ULONG MultiByteSize; DWORD dwAttrWPos;
if (dwSize < dwPos) { // lpUndetW buffer is too small.
return 0; }
dwAttrWPos = dwPos;
lpwszUndetText = (LPWSTR)((PBYTE)lpUndetW + lpUndetW->uUndetTextPos); lpAttrA = (PBYTE)lpCompStrA + lpCompStrA->dwCompAttrOffset; lpAttrW = (PBYTE)lpUndetW + dwPos;
while (wc=*lpwszUndetText++) { RtlUnicodeToMultiByteSize(&MultiByteSize, &wc, sizeof(WCHAR)); if (MultiByteSize == 2) { *lpAttrW++ = *lpAttrA; lpAttrA += 2; } else { *lpAttrW++ = *lpAttrA++; }
dwAttrWPos += sizeof(*lpAttrW); if (dwSize < dwAttrWPos) { // lpUndetW buffer is too small.
return 0; } }
lpUndetW->uUndetAttrPos = dwPos; dwPos += DWORD_ALIGN((lpUndetW->uUndetTextLen + 1)); } }
if (dwGCS & GCS_CURSORPOS) { if (lpCompStrA->dwCursorPos != -1) { lpUndetW->uCursorPos = CalcCharacterPositionAtoW(lpCompStrA->dwCursorPos, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset), CP_ACP ); } else { lpUndetW->uCursorPos = lpCompStrA->dwCursorPos; } }
if (dwGCS & GCS_DELTASTART) { if (lpCompStrA->dwDeltaStart != -1) { lpUndetW->uDeltaStart = CalcCharacterPositionAtoW(lpCompStrA->dwDeltaStart, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset), CP_ACP ); } else { lpUndetW->uDeltaStart = lpCompStrA->dwDeltaStart; } }
if (dwGCS & GCS_RESULTSTR) { if (dwSize < dwPos) { // lpUndetW buffer is too small.
return 0; }
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset), // src
(INT)lpCompStrA->dwResultStrLen, (LPWSTR)((PBYTE)lpUndetW + dwPos), // dest
(INT)(dwSize - dwPos)/sizeof(WCHAR)); // Specifies the size, in wide characters.
if (i >= (dwSize - dwPos)/sizeof(WCHAR)) { // lpUndetW buffer doesn't hold NULL character terminator.
return 0; }
((LPWSTR)((PBYTE)lpUndetW + dwPos))[i] = L'\0'; lpUndetW->uDetermineTextLen = i; lpUndetW->uDetermineTextPos = dwPos; dwPos += DWORD_ALIGN(((lpUndetW->uDetermineTextLen + 1)*sizeof(WCHAR))); }
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrA->dwResultClauseLen > 0) ) { if (lpUndetW->uDetermineTextLen != 0) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseWPos;
if (dwSize < dwPos) { // lpUndetW buffer is too small.
return 0; }
dwClauseWPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpUndetW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset);
for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionAtoW(*lpdw++, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset), CP_ACP );
dwClauseWPos += sizeof(*lpw); if (dwSize < dwClauseWPos) { // lpUndetW buffer is too small.
return 0; } }
lpUndetW->uDetermineDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1)); } }
if (dwGCS & GCS_RESULTREADSTR) { if (dwSize < dwPos) { // lpUndetW buffer is too small.
return 0; }
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset), // src
(INT)lpCompStrA->dwResultReadStrLen, (LPWSTR)((PBYTE)lpUndetW + dwPos), // dest
(INT)(dwSize - dwPos)/sizeof(WCHAR)); // Specifies the size, in wide characters.
if (i >= (dwSize - dwPos)/sizeof(WCHAR)) { // lpUndetW buffer doesn't hold NULL character terminator.
return 0; }
((LPWSTR)((PBYTE)lpUndetW + dwPos))[i] = L'\0'; lpUndetW->uYomiTextLen = i; lpUndetW->uYomiTextPos = dwPos; dwPos += DWORD_ALIGN(((lpUndetW->uYomiTextLen + 1)*sizeof(WCHAR))); }
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrA->dwResultReadClauseLen > 0) ) { if (lpUndetW->uYomiTextLen != 0) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseWPos;
if (dwSize < dwPos) { // lpUndetW buffer is too small.
return 0; }
dwClauseWPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpUndetW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset);
for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionAtoW(*lpdw++, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset), CP_ACP );
dwClauseWPos += sizeof(*lpw); if (dwSize < dwClauseWPos) { // lpUndetW buffer is too small.
return 0; } }
lpUndetW->uYomiDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen + 1)); } }
return dwSize; }
DWORD CompStrAToStringExA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPSTRINGEXSTRUCT lpStringExA, DWORD dwStringExABufferSize )
/*++
Routine Description:
Convert composition string (ANSI) to StringEx (ANSI).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; UINT i;
dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) + DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(CHAR))) + DWORD_ALIGN(lpCompStrA->dwResultClauseLen+1) + DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(CHAR))) + DWORD_ALIGN(lpCompStrA->dwResultReadClauseLen+1);
if (lpStringExA == NULL) { return dwSize; }
if (dwSize > dwStringExABufferSize) { // lpStringExA buffer is too small.
return 0; }
// Set actual lpStringExA buffer size in dwSize.
dwSize = dwStringExABufferSize;
dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1); lpStringExA->dwSize = dwSize;
if (dwSize < dwPos) { // lpStringExA buffer is too small.
return 0; } if (lpCompStrA->dwResultStrLen * sizeof(CHAR) > dwSize - dwPos) { // lpStringExA buffer is too small.
return 0; }
lpStringExA->uDeterminePos = dwPos; memcpy((PBYTE)lpStringExA + dwPos, (PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset, lpCompStrA->dwResultStrLen * sizeof(CHAR) ); *(LPSTR)((PBYTE)lpStringExA + dwPos + lpCompStrA->dwResultStrLen*sizeof(CHAR)) = '\0'; dwPos += DWORD_ALIGN(((lpCompStrA->dwResultStrLen + 1)*sizeof(CHAR)));
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrA->dwResultClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseAPos;
if (dwSize < dwPos) { // lpStringExA buffer is too small.
return 0; }
dwClauseAPos = dwPos;
lpStringExA->uDetermineDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpStringExA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset); for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++) { *lpw++ = *lpdw++; dwClauseAPos += sizeof(*lpw); if (dwSize < dwClauseAPos) { // lpStringExA buffer is too small.
return 0; } }
dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1)); }
if (dwSize < dwPos) { // lpStringExA buffer is too small.
return 0; } if (lpCompStrA->dwResultReadStrLen * sizeof(CHAR) > dwSize - dwPos) { // lpStringExA buffer is too small.
return 0; }
lpStringExA->uYomiPos = dwPos; memcpy((PBYTE)lpStringExA + dwPos, (PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset, lpCompStrA->dwResultReadStrLen * sizeof(CHAR) ); *(LPSTR)((PBYTE)lpStringExA + dwPos + lpCompStrA->dwResultReadStrLen*sizeof(CHAR)) = '\0'; dwPos += DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen + 1)*sizeof(CHAR)));
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrA->dwResultReadClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseAPos;
if (dwSize < dwPos) { // lpStringExA buffer is too small.
return 0; }
dwClauseAPos = dwPos;
lpStringExA->uYomiDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpStringExA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset); for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++) { *lpw++ = *lpdw++; dwClauseAPos += sizeof(*lpw); if (dwSize < dwClauseAPos) { // lpStringExA buffer is too small.
return 0; } } }
return dwSize; }
DWORD CompStrAToStringExW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrA, LPSTRINGEXSTRUCT lpStringExW, DWORD dwStringExWBufferSize )
/*++
Routine Description:
Convert composition string (ANSI) to StringEx (Unicode).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; DWORD dwLen; UINT i;
dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) + (lpCompStrA->dwResultStrLen > 0 ? DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(WCHAR))) : 0) + (lpCompStrA->dwResultClauseLen > 0 ? DWORD_ALIGN(lpCompStrA->dwResultClauseLen+1) : 0) + (lpCompStrA->dwResultReadStrLen > 0 ? DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(WCHAR))) : 0)+ (lpCompStrA->dwResultReadClauseLen > 0 ? DWORD_ALIGN(lpCompStrA->dwResultReadClauseLen+1) : 0);
if (lpStringExW == NULL) { return dwSize; }
if (dwSize > dwStringExWBufferSize) { // lpStringExW buffer is too small.
return 0; }
// Set actual lpStringExW buffer size in dwSize.
dwSize = dwStringExWBufferSize;
dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1); lpStringExW->dwSize = dwSize;
if (lpCompStrA->dwResultStrLen > 0) { if (dwSize < dwPos) { // lpStringExW buffer is too small.
return 0; }
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset), // src
(INT)lpCompStrA->dwResultStrLen, (LPWSTR)((PBYTE)lpStringExW + dwPos), // dest
(INT)(dwSize - dwPos)/sizeof(WCHAR)); // Specifies the size, in wide characters.
if (i >= (dwSize - dwPos)/sizeof(WCHAR)) { // lpStringExW buffer doesn't hold NULL character terminator.
return 0; }
((LPWSTR)((PBYTE)lpStringExW + dwPos))[i] = L'\0'; dwLen = i; lpStringExW->uDeterminePos = dwPos; dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(WCHAR))); } else { dwLen = 0; lpStringExW->uDeterminePos = 0; }
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrA->dwResultClauseLen > 0) ) { if (dwLen != 0 && lpCompStrA->dwResultClauseLen > 0) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseWPos;
if (dwSize < dwPos) { // lpStringExW buffer is too small.
return 0; }
dwClauseWPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpStringExW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset);
for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionAtoW(*lpdw++, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset), CP_ACP );
dwClauseWPos += sizeof(*lpw); if (dwSize < dwClauseWPos) { // lpStringExW buffer is too small.
return 0; } }
lpStringExW->uDetermineDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1)); } }
if (lpCompStrA->dwResultReadStrLen > 0) { if (dwSize < dwPos) { // lpStringExW buffer is too small.
return 0; }
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset), // src
(INT)lpCompStrA->dwResultReadStrLen, (LPWSTR)((PBYTE)lpStringExW + dwPos), // dest
(INT)(dwSize - dwPos)/sizeof(WCHAR)); // Specifies the size, in wide characters.
if (i >= (dwSize - dwPos)/sizeof(WCHAR)) { // lpStringExW buffer doesn't hold NULL character terminator.
return 0; }
((LPWSTR)((PBYTE)lpStringExW + dwPos))[i] = L'\0'; dwLen = i; lpStringExW->uYomiPos = dwPos; dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(WCHAR))); } else { dwLen = 0; lpStringExW->uYomiPos = 0; }
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrA->dwResultReadClauseLen > 0) ) { if (dwLen != 0 && lpCompStrA->dwResultReadClauseLen > 0) { LPDWORD lpw; LPDWORD lpdw; DWORD dwClauseWPos;
if (dwSize < dwPos) { // lpStringExW buffer is too small.
return 0; }
dwClauseWPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpStringExW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset);
for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionAtoW(*lpdw++, (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset), CP_ACP );
dwClauseWPos += sizeof(*lpw); if (dwSize < dwClauseWPos) { // lpStringExW buffer is too small.
return 0; } }
lpStringExW->uYomiDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen + 1)); } }
return dwSize; }
DWORD CompStrAToStringA( LPCOMPOSITIONSTRING lpCompStrA, LPSTR lpStringA, DWORD dwStringABufferSize )
/*++
Routine Description:
Convert composition string (ANSI) to String (ANSI).
Arguments:
Return Value:
--*/
{ LPSTR lpszString; DWORD dwSize;
lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset); dwSize = lpCompStrA->dwResultStrLen;
if (lpStringA == NULL) { return ((dwSize + 1) * sizeof(CHAR)); }
if (dwSize > dwStringABufferSize) { // lpStringA buffer is too small.
return 0; }
memcpy((PBYTE)lpStringA, (PBYTE)lpszString, (dwSize * sizeof(CHAR)) ); lpStringA[dwSize] = '\0';
return ((dwSize + 1) * sizeof(CHAR)); }
DWORD CompStrAToStringW( LPCOMPOSITIONSTRING lpCompStrA, LPWSTR lpStringW, DWORD dwStringWBufferSize )
/*++
Routine Description:
Convert composition string (ANSI) to String (Unicode).
Arguments:
Return Value:
--*/
{ LPSTR lpszString; DWORD dwSize; UINT i;
lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)lpszString, // src
(INT)lpCompStrA->dwResultStrLen, (LPWSTR)lpStringW, // dest
(INT)0);
if (lpStringW == NULL) { dwSize = (i+1) * sizeof(WCHAR); } else { dwSize = (i+1) * sizeof(WCHAR);
if (dwSize > dwStringWBufferSize) { // lpStringW buffer is too small.
return 0; }
i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)lpszString, // src
(INT)lpCompStrA->dwResultStrLen, (LPWSTR)lpStringW, // dest
(INT)dwSize/sizeof(WCHAR)); // Specifies the size, in wide characters.
if (i >= dwSize/sizeof(WCHAR)) { // lpStringW buffer doesn't hold NULL character terminator.
return 0; }
lpStringW[i] = L'\0'; dwSize = (i+1) * sizeof(WCHAR); }
return dwSize; }
VOID CompStrAToCharA( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrA )
/*++
Routine Description:
Convert composition string (ANSI) to WM_CHAR (ANSI).
Arguments:
Return Value:
--*/
{ LPSTR lpszString; BOOL fDBCSWmChar = FALSE; WORD wDBCSChar; BYTE szAscii[3];
lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
// IR_DBCSCHAR: If the app reply to this message with TRUE, we can
// queue up double byte character in a WM_CHAR message.
if ( GetClientInfo()->dwExpWinVer >= 0x030A ) { fDBCSWmChar = (BOOL)SendMessageA( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L); }
// Send IR_STRINGSTART prior to anything.
PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
while(szAscii[0]=*lpszString) { if( *CharNextA(lpszString) == 0 ) { PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L ); } if( IsDBCSLeadByte( szAscii[0] ) ) { szAscii[1] = *((PBYTE)(lpszString+1));
// If fDBCSWmChar==TRUE, The app can recieve WM_CHARs which
// have double byte code in wParam.
if ( fDBCSWmChar ) { // It's necessary to swap bytes to put 1st byte into upper
// part of wParam, and 2nd byte into lower part.
wDBCSChar = MAKEWORD(szAscii[1], szAscii[0]); PostMessageA( hWnd, WM_CHAR, (WPARAM)wDBCSChar|WMCR_IR_DBCSCHAR, 1L ); } else { // Send each byte on a WM_CHAR
PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L); PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[1]), 1L); } } else { PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L); } lpszString = CharNextA(lpszString); } }
VOID CompStrAToCharW( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrA )
/*++
Routine Description:
Convert composition string (ANSI) to WM_CHAR (Unicode).
Arguments:
Return Value:
--*/
{ LPSTR lpszString; UINT i; BYTE c; WCHAR wszUnicode[2];
lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
// IR_DBCSCHAR: If the app reply to this message with TRUE, we can
// queue up double byte character in a WM_CHAR message.
// SendMessageW( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L);
// Send IR_STRINGSTART prior to anything.
PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
while(c=*lpszString) { if( *CharNextA(lpszString) == 0 ) { PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L ); } if( IsDBCSLeadByte( c ) ) { i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)lpszString, // src
(INT)2, (LPWSTR)wszUnicode, // dest
(INT)ARRAY_SIZE(wszUnicode)); } else { i = MultiByteToWideChar( CP_ACP, (DWORD)MB_PRECOMPOSED, (LPSTR)lpszString, // src
(INT)1, (LPWSTR)wszUnicode, // dest
(INT)ARRAY_SIZE(wszUnicode)); } if (i != 0) { PostMessageW( hWnd, WM_CHAR, (WPARAM)(wszUnicode[0]), 1L); } lpszString = CharNextA(lpszString); } }
DWORD CompStrWToUndetW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPUNDETERMINESTRUCT lpUndetW )
/*++
Routine Description:
Convert composition string (Unicode) to undetermine string (Unicode).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; UINT i;
dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) + DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN((lpCompStrW->dwResultClauseLen+1)) + DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen+1)) + DWORD_ALIGN((lpCompStrW->dwCompAttrLen+1)) + DWORD_ALIGN(((lpCompStrW->dwCompStrLen+1) * sizeof(WCHAR)));
if (lpUndetW == NULL) { return dwSize; }
dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1)); lpUndetW->dwSize = dwSize;
if (dwGCS & GCS_COMPSTR) { lpUndetW->uUndetTextLen = lpCompStrW->dwCompStrLen; lpUndetW->uUndetTextPos = dwPos; memcpy((PBYTE)lpUndetW + dwPos, (PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset, lpCompStrW->dwCompStrLen * sizeof(WCHAR) ); *(LPWSTR)((PBYTE)lpUndetW + dwPos + lpCompStrW->dwCompStrLen*sizeof(WCHAR)) = L'\0'; dwPos += DWORD_ALIGN(((lpUndetW->uUndetTextLen+1)*sizeof(WCHAR)));
// Sometime Chicago IME does not generate GCS_COMPATTR
// with GCS_COMPSTR. But uUndetAttrPos should be filled
// when the UndetText is updated.
if (lpCompStrW->dwCompAttrLen && !(dwGCS & GCS_COMPATTR)) dwGCS |= GCS_COMPATTR; }
if (dwGCS & GCS_COMPATTR) { lpUndetW->uUndetAttrPos = dwPos; memcpy((PBYTE)lpUndetW + dwPos, (PBYTE)lpCompStrW + lpCompStrW->dwCompAttrOffset, lpCompStrW->dwCompAttrLen ); dwPos += DWORD_ALIGN((lpUndetW->uUndetTextLen + 1)); }
if (dwGCS & GCS_CURSORPOS) { lpUndetW->uCursorPos = lpCompStrW->dwCursorPos; }
if (dwGCS & GCS_DELTASTART) { lpUndetW->uDeltaStart = lpCompStrW->dwDeltaStart; }
if (dwGCS & GCS_RESULTSTR) { lpUndetW->uDetermineTextLen = lpCompStrW->dwResultStrLen; lpUndetW->uDetermineTextPos = dwPos; memcpy((PBYTE)lpUndetW + dwPos, (PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset, lpCompStrW->dwResultStrLen * sizeof(WCHAR) ); *(LPWSTR)((PBYTE)lpUndetW + dwPos + lpCompStrW->dwResultStrLen*sizeof(WCHAR)) = L'\0'; dwPos += DWORD_ALIGN(((lpUndetW->uDetermineTextLen + 1)*sizeof(WCHAR))); }
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrW->dwResultClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw;
lpUndetW->uDetermineDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpUndetW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset); for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++) *lpw++ = *lpdw++;
dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1)); }
if (dwGCS & GCS_RESULTREADSTR) { lpUndetW->uYomiTextLen = lpCompStrW->dwResultReadStrLen; lpUndetW->uYomiTextPos = dwPos; memcpy((PBYTE)lpUndetW + dwPos, (PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset, lpCompStrW->dwResultReadStrLen * sizeof(WCHAR) ); *(LPWSTR)((PBYTE)lpUndetW + dwPos + lpCompStrW->dwResultReadStrLen*sizeof(WCHAR)) = L'\0'; dwPos += DWORD_ALIGN(((lpUndetW->uYomiTextLen + 1)*sizeof(WCHAR))); }
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrW->dwResultReadClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw;
lpUndetW->uYomiDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpUndetW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset); for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++) *lpw++ = *lpdw++;
dwPos += DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen + 1)); }
return dwSize; }
DWORD CompStrWToUndetA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPUNDETERMINESTRUCT lpUndetA )
/*++
Routine Description:
Convert composition string (Unicode) to undetermine string (ANSI).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; UINT i; BOOL bUDC;
dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) + DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN((lpCompStrW->dwResultClauseLen+1)) + DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen+1)) + DWORD_ALIGN((lpCompStrW->dwCompAttrLen * 2)) + DWORD_ALIGN(((lpCompStrW->dwCompStrLen+1) * sizeof(WCHAR)));
if (lpUndetA == NULL) { return dwSize; }
dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1)); lpUndetA->dwSize = dwSize;
if (dwGCS & GCS_COMPSTR) { i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset), // src
(INT)lpCompStrW->dwCompStrLen, (LPSTR)((PBYTE)lpUndetA + dwPos), // dest
(INT)dwSize - dwPos, (LPSTR)NULL, (LPBOOL)&bUDC); ((LPSTR)((PBYTE)lpUndetA + dwPos))[i] = '\0'; lpUndetA->uUndetTextLen = i; lpUndetA->uUndetTextPos = dwPos; dwPos += DWORD_ALIGN(((lpUndetA->uUndetTextLen + 1)*sizeof(CHAR)));
// Sometime Chicago IME does not generate GCS_COMPATTR
// with GCS_COMPSTR. But uUndetAttrPos should be filled
// when the UndetText is updated.
if (lpCompStrW->dwCompAttrLen && !(dwGCS & GCS_COMPATTR)) dwGCS |= GCS_COMPATTR; }
if (dwGCS & GCS_COMPATTR) { if (lpUndetA->uUndetTextLen != 0) { LPSTR lpszUndetText; PBYTE lpAttrW; PBYTE lpAttrA; BYTE c;
lpszUndetText = (LPSTR)((PBYTE)lpUndetA + lpUndetA->uUndetTextPos); lpAttrW = (PBYTE)lpCompStrW + lpCompStrW->dwCompAttrOffset; lpAttrA = (PBYTE)lpUndetA + dwPos;
while (c=*lpszUndetText++) { if (IsDBCSLeadByte(c)) { *lpAttrA++ = *lpAttrW; *lpAttrA++ = *lpAttrW; lpszUndetText++; } else { *lpAttrA++ = *lpAttrW; } lpAttrW++; }
lpUndetA->uUndetAttrPos = dwPos; dwPos += DWORD_ALIGN((lpUndetA->uUndetTextLen + 1)); } }
if (dwGCS & GCS_CURSORPOS) { if (lpCompStrW->dwCursorPos != -1) { lpUndetA->uCursorPos = CalcCharacterPositionWtoA(lpCompStrW->dwCursorPos, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset), CP_ACP ); } else { lpUndetA->uCursorPos = lpCompStrW->dwCursorPos; } }
if (dwGCS & GCS_DELTASTART) { if (lpCompStrW->dwDeltaStart != -1) { lpUndetA->uDeltaStart = CalcCharacterPositionWtoA(lpCompStrW->dwDeltaStart, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset), CP_ACP ); } else { lpUndetA->uDeltaStart = lpCompStrW->dwDeltaStart; } }
if (dwGCS & GCS_RESULTSTR) { i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset), // src
(INT)lpCompStrW->dwResultStrLen, (LPSTR)((PBYTE)lpUndetA + dwPos), // dest
(INT)dwSize - dwPos, (LPSTR)NULL, (LPBOOL)&bUDC); ((LPSTR)((PBYTE)lpUndetA + dwPos))[i] = '\0'; lpUndetA->uDetermineTextLen = i; lpUndetA->uDetermineTextPos = dwPos; dwPos += DWORD_ALIGN(((lpUndetA->uDetermineTextLen + 1)*sizeof(CHAR))); }
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrW->dwResultClauseLen > 0) ) { if (lpUndetA->uDetermineTextLen != 0) { LPDWORD lpw; LPDWORD lpdw;
lpw = (LPDWORD)((PBYTE)lpUndetA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset);
for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionWtoA(*lpdw++, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset), CP_ACP ); }
lpUndetA->uDetermineDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1)); } }
if (dwGCS & GCS_RESULTREADSTR) { i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset), // src
(INT)lpCompStrW->dwResultReadStrLen, (LPSTR)((PBYTE)lpUndetA + dwPos), // dest
(INT)dwSize - dwPos, (LPSTR)NULL, (LPBOOL)&bUDC); ((LPSTR)((PBYTE)lpUndetA + dwPos))[i] = '\0'; lpUndetA->uYomiTextLen = i; lpUndetA->uYomiTextPos = dwPos; dwPos += DWORD_ALIGN(((lpUndetA->uYomiTextLen + 1)*sizeof(CHAR))); }
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrW->dwResultReadClauseLen > 0) ) { if (lpUndetA->uYomiTextLen != 0) { LPDWORD lpw; LPDWORD lpdw;
lpw = (LPDWORD)((PBYTE)lpUndetA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset);
for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionWtoA(*lpdw++, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset), CP_ACP ); }
lpUndetA->uYomiDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen + 1)); } }
return dwSize; }
DWORD CompStrWToStringExW( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPSTRINGEXSTRUCT lpStringExW )
/*++
Routine Description:
Convert composition string (Unicode) to StringEx (Unicode).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; UINT i;
dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) + DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN(lpCompStrW->dwResultClauseLen+1) + DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) + DWORD_ALIGN(lpCompStrW->dwResultReadClauseLen+1);
if (lpStringExW == NULL) { return dwSize; }
dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1); lpStringExW->dwSize = dwSize;
lpStringExW->uDeterminePos = dwPos; memcpy((PBYTE)lpStringExW + dwPos, (PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset, lpCompStrW->dwResultStrLen * sizeof(WCHAR) ); *(LPWSTR)((PBYTE)lpStringExW + dwPos + lpCompStrW->dwResultStrLen*sizeof(WCHAR)) = L'\0'; dwPos += DWORD_ALIGN(((lpCompStrW->dwResultStrLen + 1)*sizeof(WCHAR)));
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrW->dwResultClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw;
lpStringExW->uDetermineDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpStringExW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset); for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++) *lpw++ = *lpdw++;
dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1)); }
lpStringExW->uYomiPos = dwPos; memcpy((PBYTE)lpStringExW + dwPos, (PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset, lpCompStrW->dwResultReadStrLen * sizeof(WCHAR) ); *(LPWSTR)((PBYTE)lpStringExW + dwPos + lpCompStrW->dwResultReadStrLen*sizeof(WCHAR)) = L'\0'; dwPos += DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen + 1)*sizeof(WCHAR)));
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrW->dwResultReadClauseLen > 0) ) { LPDWORD lpw; LPDWORD lpdw;
lpStringExW->uYomiDelimPos = dwPos;
lpw = (LPDWORD)((PBYTE)lpStringExW + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset); for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++) *lpw++ = *lpdw++; }
return dwSize; }
DWORD CompStrWToStringExA( DWORD dwGCS, LPCOMPOSITIONSTRING lpCompStrW, LPSTRINGEXSTRUCT lpStringExA )
/*++
Routine Description:
Convert composition string (Unicode) to StringEx (ANSI).
Arguments:
Return Value:
--*/
{ DWORD dwPos; DWORD dwSize; DWORD dwLen; UINT i; BOOL bUDC;
dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) + (lpCompStrW->dwResultStrLen > 0 ? DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) : 0) + (lpCompStrW->dwResultClauseLen > 0 ? DWORD_ALIGN(lpCompStrW->dwResultClauseLen+1) : 0) + (lpCompStrW->dwResultReadStrLen > 0 ? DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) : 0)+ (lpCompStrW->dwResultReadClauseLen > 0 ? DWORD_ALIGN(lpCompStrW->dwResultReadClauseLen+1) : 0);
if (lpStringExA == NULL) { return dwSize; }
dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1); lpStringExA->dwSize = dwSize;
if (lpCompStrW->dwResultStrLen > 0) { i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset), // src
(INT)lpCompStrW->dwResultStrLen, (LPSTR)((PBYTE)lpStringExA + dwPos), // dest
(INT)dwSize - dwPos, (LPSTR)NULL, (LPBOOL)&bUDC); ((LPSTR)((PBYTE)lpStringExA + dwPos))[i] = '\0'; dwLen = i; lpStringExA->uDeterminePos = dwPos; dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(CHAR))); } else { dwLen = 0; lpStringExA->uDeterminePos = 0; }
if ( (dwGCS & GCS_RESULTCLAUSE) && (lpCompStrW->dwResultClauseLen > 0) ) { if (dwLen != 0 && lpCompStrW->dwResultClauseLen > 0) { LPDWORD lpw; LPDWORD lpdw;
lpw = (LPDWORD)((PBYTE)lpStringExA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset);
for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionWtoA(*lpdw++, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset), CP_ACP ); }
lpStringExA->uDetermineDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1)); } }
if (lpCompStrW->dwResultReadStrLen > 0) { i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset), // src
(INT)lpCompStrW->dwResultReadStrLen, (LPSTR)((PBYTE)lpStringExA + dwPos), // dest
(INT)dwSize - dwPos, (LPSTR)NULL, (LPBOOL)&bUDC); ((LPSTR)((PBYTE)lpStringExA + dwPos))[i] = '\0'; dwLen = i; lpStringExA->uYomiPos = dwPos; dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(CHAR))); } else { dwLen = 0; lpStringExA->uYomiPos = 0; }
if ( (dwGCS & GCS_RESULTREADCLAUSE) && (lpCompStrW->dwResultReadClauseLen > 0) ) { if (dwLen != 0 && lpCompStrW->dwResultReadClauseLen > 0) { LPDWORD lpw; LPDWORD lpdw;
lpw = (LPDWORD)((PBYTE)lpStringExA + dwPos); lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset);
for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++) { *lpw++ = CalcCharacterPositionWtoA(*lpdw++, (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset), CP_ACP ); }
lpStringExA->uYomiDelimPos = dwPos; dwPos += DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen + 1)); } }
return dwSize; }
DWORD CompStrWToStringW( LPCOMPOSITIONSTRING lpCompStrW, LPWSTR lpStringW )
/*++
Routine Description:
Convert composition string (Unicode) to String (Unicode).
Arguments:
Return Value:
--*/
{ LPWSTR lpwszString; DWORD dwSize;
lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset); dwSize = lpCompStrW->dwResultStrLen;
if (lpStringW == NULL) { return ((dwSize + 1) * sizeof(WCHAR)); }
memcpy((PBYTE)lpStringW, (PBYTE)lpwszString, (dwSize * sizeof(WCHAR)) ); lpStringW[dwSize] = L'\0';
return ((dwSize + 1) * sizeof(WCHAR)); }
DWORD CompStrWToStringA( LPCOMPOSITIONSTRING lpCompStrW, LPSTR lpStringA )
/*++
Routine Description:
Convert composition string (Unicode) to String (ANSI).
Arguments:
Return Value:
--*/
{ LPWSTR lpwszString; DWORD dwSize; UINT i; BOOL bUDC;
lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)lpwszString, // src
(INT)lpCompStrW->dwResultStrLen, (LPSTR)lpStringA, // dest
(INT)0, (LPSTR)NULL, (LPBOOL)&bUDC);
if (lpStringA == NULL) { dwSize = (i+1) * sizeof(CHAR); } else { dwSize = (i+1) * sizeof(CHAR);
i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)lpwszString, // src
(INT)lpCompStrW->dwResultStrLen, (LPSTR)lpStringA, // dest
(INT)dwSize, (LPSTR)NULL, (LPBOOL)&bUDC);
lpStringA[i] = '\0'; dwSize = (i+1) * sizeof(CHAR); }
return dwSize; }
VOID CompStrWToCharW( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrW )
/*++
Routine Description:
Convert composition string (Unicode) to WM_CHAR (Unicode).
Arguments:
Return Value:
--*/
{ LPWSTR lpwszString;
lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
// IR_DBCSCHAR: If the app reply to this message with TRUE, we can
// queue up double byte character in a WM_CHAR message.
// SendMessageW( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L);
// Send IR_STRINGSTART prior to anything.
PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
while(*lpwszString) { if( *CharNextW(lpwszString) == 0 ) { PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L ); } PostMessageW( hWnd, WM_CHAR, *lpwszString, 1L); lpwszString = CharNextW(lpwszString); } }
VOID CompStrWToCharA( HWND hWnd, LPCOMPOSITIONSTRING lpCompStrW )
/*++
Routine Description:
Convert composition string (Unicode) to WM_CHAR (ANSI).
Arguments:
Return Value:
--*/
{ LPWSTR lpwszString; BOOL fDBCSWmChar = FALSE; WORD wDBCSChar; UINT i; BOOL bUDC; BYTE szAscii[3];
lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
//
// IR_DBCSCHAR: If the app reply to this message with TRUE, we can
// queue up double byte character in a WM_CHAR message.
//
//
if ( GetClientInfo()->dwExpWinVer >= 0x030A ) { fDBCSWmChar = (BOOL)SendMessageA( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L); }
//
// Send IR_STRINGSTART prior to anything.
//
PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
while (*lpwszString) {
if ( *CharNextW(lpwszString) == 0 ) { PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L ); }
i = WideCharToMultiByte( CP_ACP, (DWORD)0, (LPWSTR)lpwszString, // src
(INT)1, (LPSTR)szAscii, // dest
(INT)sizeof(szAscii), (LPSTR)NULL, (LPBOOL)&bUDC);
if (i != 0) {
if ( IsDBCSLeadByte( szAscii[0] ) ) {
//
// If fDBCSWmChar==TRUE, The app can recieve WM_CHARs which
// have double byte code in wParam.
//
if ( fDBCSWmChar ) { //
// It's necessary to swap bytes to put 1st byte into upper
// part of wParam, and 2nd byte into lower part.
//
wDBCSChar = MAKEWORD(szAscii[1], szAscii[0]); PostMessageA( hWnd, WM_CHAR, wDBCSChar|WMCR_IR_DBCSCHAR, 1L ); } else { //
// Send each byte on a WM_CHAR
//
PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L); PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[1]), 1L); } } else { PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L); } }
lpwszString = CharNextW(lpwszString); }
}
|