You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2638 lines
80 KiB
2638 lines
80 KiB
/**************************************************************************\
|
|
* 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);
|
|
}
|
|
|
|
}
|