test: jtranmsg.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# jtranmsg.c

Go to the documentation of this file.

    00001 /**************************************************************************\
    00002 * Module Name: jtranmsg.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * This module contains all the code for the Japanese translation subroutine.
    00007 *
    00008 * History:
    00009 * 15-Aug-1995 kazum
    00010 \**************************************************************************/
    00011 #include "precomp.h"
    00012 #pragma hdrstop
    00013
    00014
    00015 UINT
    00016 JTransCompositionA(
    00017     LPINPUTCONTEXT lpIMC,
    00018     LPCOMPOSITIONSTRING lpCompStrA,
    00019     PTRANSMSG      pTransMsgSrc,
    00020     PTRANSMSG      pTransMsgDest
    00021     );
    00022
    00023 UINT
    00024 JTransCompositionW(
    00025     LPINPUTCONTEXT lpIMC,
    00026     LPCOMPOSITIONSTRING lpCompStrW,
    00027     PTRANSMSG      pTransMsgSrc,
    00028     PTRANSMSG      pTransMsgDest
    00029     );
    00030
    00031 DWORD
    00032 CompStrWToUndetW(
    00033     DWORD dwGCS,
    00034     LPCOMPOSITIONSTRING lpCompStrW,
    00035     LPUNDETERMINESTRUCT lpUndetW
    00036     );
    00037
    00038 DWORD
    00039 CompStrWToUndetA(
    00040     DWORD dwGCS,
    00041     LPCOMPOSITIONSTRING lpCompStrW,
    00042     LPUNDETERMINESTRUCT lpUndetA
    00043     );
    00044
    00045 DWORD
    00046 CompStrWToStringExW(
    00047     DWORD dwGCS,
    00048     LPCOMPOSITIONSTRING lpCompStrW,
    00049     LPSTRINGEXSTRUCT lpStringExW
    00050     );
    00051
    00052 DWORD
    00053 CompStrWToStringExA(
    00054     DWORD dwGCS,
    00055     LPCOMPOSITIONSTRING lpCompStrW,
    00056     LPSTRINGEXSTRUCT lpStringExA
    00057     );
    00058
    00059 DWORD
    00060 CompStrWToStringW(
    00061     LPCOMPOSITIONSTRING lpCompStrW,
    00062     LPWSTR lpStringW
    00063     );
    00064
    00065 DWORD
    00066 CompStrWToStringA(
    00067     LPCOMPOSITIONSTRING lpCompStrW,
    00068     LPSTR lpStringA
    00069     );
    00070
    00071 VOID
    00072 CompStrWToCharW(
    00073     HWND hWnd,
    00074     LPCOMPOSITIONSTRING lpCompStrW
    00075     );
    00076
    00077 VOID
    00078 CompStrWToCharA(
    00079     HWND hWnd,
    00080     LPCOMPOSITIONSTRING lpCompStrW
    00081     );
    00082
    00083 DWORD
    00084 CompStrAToUndetA(
    00085     DWORD dwGCS,
    00086     LPCOMPOSITIONSTRING lpCompStrA,
    00087     LPUNDETERMINESTRUCT lpUndetA
    00088     );
    00089
    00090 DWORD
    00091 CompStrAToUndetW(
    00092     DWORD dwGCS,
    00093     LPCOMPOSITIONSTRING lpCompStrA,
    00094     LPUNDETERMINESTRUCT lpUndetW
    00095     );
    00096
    00097 DWORD
    00098 CompStrAToStringExA(
    00099     DWORD dwGCS,
    00100     LPCOMPOSITIONSTRING lpCompStrA,
    00101     LPSTRINGEXSTRUCT lpStringExA
    00102     );
    00103
    00104 DWORD
    00105 CompStrAToStringExW(
    00106     DWORD dwGCS,
    00107     LPCOMPOSITIONSTRING lpCompStrA,
    00108     LPSTRINGEXSTRUCT lpStringExW
    00109     );
    00110
    00111 DWORD
    00112 CompStrAToStringA(
    00113     LPCOMPOSITIONSTRING lpCompStrA,
    00114     LPSTR lpStringA
    00115     );
    00116
    00117 DWORD
    00118 CompStrAToStringW(
    00119     LPCOMPOSITIONSTRING lpCompStrA,
    00120     LPWSTR lpStringW
    00121     );
    00122
    00123 VOID
    00124 CompStrAToCharA(
    00125     HWND hWnd,
    00126     LPCOMPOSITIONSTRING lpCompStrA
    00127     );
    00128
    00129 VOID
    00130 CompStrAToCharW(
    00131     HWND hWnd,
    00132     LPCOMPOSITIONSTRING lpCompStrA
    00133     );
    00134
    00135
    00136 UINT
    00137 JTransCompositionA(
    00138     LPINPUTCONTEXT lpIMC,
    00139     LPCOMPOSITIONSTRING lpCompStrA,
    00140     PTRANSMSG      pTransMsgSrc,
    00141     PTRANSMSG      pTransMsgDest
    00142     )
    00143 {
    00144     UINT i = 0;
    00145     int iNum = 0;
    00146     DWORD dwSize;
    00147     HWND hWnd;
    00148     WORD wTextLen = 0;
    00149     BOOL fDoneUndet = FALSE;
    00150     BOOL fDoneDet = FALSE;
    00151     DWORD dwGCS;
    00152     BOOL bAnsiWnd;
    00153
    00154     hWnd = (HWND)lpIMC->hWnd;
    00155
    00156     if (!IsWindow(hWnd))
    00157         return 0;
    00158
    00159     bAnsiWnd = (! IsWindowUnicode(hWnd)) ? TRUE : FALSE;
    00160
    00161     dwGCS = (DWORD)pTransMsgSrc->lParam;
    00162
    00163     if (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN)
    00164     {
    00165         if (bAnsiWnd) {
    00166             dwSize = CompStrAToUndetA(dwGCS, lpCompStrA, NULL);
    00167             if (dwSize != 0) {
    00168                 HGLOBAL hUndetA = NULL;
    00169                 LPUNDETERMINESTRUCT lpUndetA;
    00170
    00171                 if (hUndetA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00172                     if (lpUndetA = (LPUNDETERMINESTRUCT)GlobalLock(hUndetA)) {
    00173                         CompStrAToUndetA(dwGCS, lpCompStrA, lpUndetA);
    00174                         fDoneUndet = TRUE;
    00175                         GlobalUnlock(hUndetA);
    00176
    00177                         if (SendMessageA(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetA)) {
    00178                             GlobalFree(hUndetA);
    00179                             return 0;
    00180                         }
    00181                     }
    00182                     GlobalFree(hUndetA);
    00183                 }
    00184             }
    00185         }
    00186         else {
    00187             dwSize = CompStrAToUndetW(dwGCS, lpCompStrA, NULL);
    00188             if (dwSize != 0) {
    00189                 HGLOBAL hUndetW = NULL;
    00190                 LPUNDETERMINESTRUCT lpUndetW;
    00191
    00192                 if (hUndetW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00193                     if (lpUndetW = (LPUNDETERMINESTRUCT)GlobalLock(hUndetW)) {
    00194                         CompStrAToUndetW(dwGCS, lpCompStrA, lpUndetW);
    00195                         fDoneUndet = TRUE;
    00196                         GlobalUnlock(hUndetW);
    00197
    00198                         if (SendMessageW(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetW)) {
    00199                             GlobalFree(hUndetW);
    00200                             return 0;
    00201                         }
    00202                     }
    00203                     GlobalFree(hUndetW);
    00204                 }
    00205             }
    00206         }
    00207     }
    00208
    00209     //
    00210     // This is generate result string routine.
    00211     // This should be same as WINNLSSendString of WIN3.1.
    00212     //
    00213
    00214     if (dwGCS & GCS_RESULTSTR)
    00215     {
    00216         //
    00217         // Can we generate IR_STRINGEX ?
    00218         //
    00219
    00220         if (dwGCS & GCS_RESULTREADSTR)
    00221         {
    00222             if (bAnsiWnd) {
    00223                 dwSize = CompStrAToStringExA(dwGCS, lpCompStrA, NULL);
    00224                 if (dwSize != 0) {
    00225                     HGLOBAL hStringExA = NULL;
    00226                     LPSTRINGEXSTRUCT lpStringExA;
    00227
    00228                     if (hStringExA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00229                         if (lpStringExA = (LPSTRINGEXSTRUCT)GlobalLock(hStringExA)) {
    00230                             CompStrAToStringExA(dwGCS, lpCompStrA, lpStringExA);
    00231                             GlobalUnlock(hStringExA);
    00232
    00233                             if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExA))
    00234                             {
    00235                                 GlobalFree(hStringExA);
    00236                                 fDoneDet = TRUE;
    00237                                 goto jtc_exit_30;
    00238                             }
    00239                         }
    00240                         GlobalFree(hStringExA);
    00241                     }
    00242                 }
    00243             }
    00244             else {
    00245                 dwSize = CompStrAToStringExW(dwGCS, lpCompStrA, NULL);
    00246                 if (dwSize != 0) {
    00247                     HGLOBAL hStringExW = NULL;
    00248                     LPSTRINGEXSTRUCT lpStringExW;
    00249
    00250                     if (hStringExW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00251                         if (lpStringExW = (LPSTRINGEXSTRUCT)GlobalLock(hStringExW)) {
    00252                             CompStrAToStringExW(dwGCS, lpCompStrA, lpStringExW);
    00253                             GlobalUnlock(hStringExW);
    00254
    00255                             if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExW))
    00256                             {
    00257                                 GlobalFree(hStringExW);
    00258                                 fDoneDet = TRUE;
    00259                                 goto jtc_exit_30;
    00260                             }
    00261                         }
    00262                         GlobalFree(hStringExW);
    00263                     }
    00264                 }
    00265             }
    00266         }
    00267
    00268         //
    00269         // generate IR_STRING
    00270         //
    00271
    00272         if (bAnsiWnd) {
    00273             dwSize = CompStrAToStringA(lpCompStrA, NULL);
    00274             if (dwSize != 0) {
    00275                 HGLOBAL hStringA = NULL;
    00276                 LPSTR lpStringA;
    00277
    00278                 if (hStringA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00279                     if (lpStringA = (LPSTR)GlobalLock(hStringA)) {
    00280                         CompStrAToStringA(lpCompStrA, lpStringA);
    00281                         GlobalUnlock(hStringA);
    00282
    00283                         if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringA))
    00284                         {
    00285                             GlobalFree(hStringA);
    00286                             fDoneDet = TRUE;
    00287                             goto jtc_exit_30;
    00288                         }
    00289                     }
    00290                     GlobalFree(hStringA);
    00291                 }
    00292             }
    00293             else {
    00294                 return 0;
    00295             }
    00296         }
    00297         else {
    00298             dwSize = CompStrAToStringW(lpCompStrA, NULL);
    00299             if (dwSize != 0) {
    00300                 HGLOBAL hStringW = NULL;
    00301                 LPWSTR lpStringW;
    00302
    00303                 if (hStringW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00304                     if (lpStringW = (LPWSTR)GlobalLock(hStringW)) {
    00305                         CompStrAToStringW(lpCompStrA, lpStringW);
    00306                         GlobalUnlock(hStringW);
    00307
    00308                         if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringW))
    00309                         {
    00310                             GlobalFree(hStringW);
    00311                             fDoneDet = TRUE;
    00312                             goto jtc_exit_30;
    00313                         }
    00314                     }
    00315                     GlobalFree(hStringW);
    00316                 }
    00317             }
    00318             else {
    00319                 return 0;
    00320             }
    00321         }
    00322
    00323         //
    00324         // generate IR_DBCSCHAR/IR_STRINGSTART/WM_CHAR/IR_STRINGEND
    00325         //
    00326
    00327         if (bAnsiWnd) {
    00328             CompStrAToCharA(hWnd, lpCompStrA);
    00329         }
    00330         else {
    00331             CompStrAToCharW(hWnd, lpCompStrA);
    00332         }
    00333
    00334         fDoneDet = TRUE;
    00335     }
    00336
    00337
    00338     if (!fDoneUndet && !fDoneDet)
    00339     {
    00340         *pTransMsgDest = *pTransMsgSrc;
    00341         iNum++;
    00342     }
    00343
    00344 jtc_exit_30:
    00345
    00346     if (!fDoneUndet && fDoneDet && (dwGCS & GCS_COMPSTR))
    00347     {
    00348         pTransMsgDest->message = pTransMsgSrc->message;
    00349         pTransMsgDest->wParam  = pTransMsgSrc->wParam;
    00350         pTransMsgDest->lParam  = (LPARAM)(dwGCS & ~(GCS_RESULT | GCS_RESULTREAD));
    00351         iNum++;
    00352     }
    00353
    00354     return iNum;
    00355 }
    00356
    00357
    00358 UINT
    00359 JTransCompositionW(
    00360     LPINPUTCONTEXT lpIMC,
    00361     LPCOMPOSITIONSTRING lpCompStrW,
    00362     PTRANSMSG      pTransMsgSrc,
    00363     PTRANSMSG      pTransMsgDest
    00364     )
    00365 {
    00366     UINT i = 0;
    00367     int iNum = 0;
    00368     DWORD dwSize;
    00369     HWND hWnd;
    00370     WORD wTextLen = 0;
    00371     BOOL fDoneUndet = FALSE;
    00372     BOOL fDoneDet = FALSE;
    00373     DWORD dwGCS;
    00374     BOOL bAnsiWnd;
    00375
    00376     hWnd = (HWND)lpIMC->hWnd;
    00377
    00378     if (!IsWindow(hWnd))
    00379         return 0;
    00380
    00381     bAnsiWnd = (! IsWindowUnicode(hWnd)) ? TRUE : FALSE;
    00382
    00383     dwGCS = (DWORD)pTransMsgSrc->lParam;
    00384
    00385     if (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN)
    00386     {
    00387         if (bAnsiWnd) {
    00388             dwSize = CompStrWToUndetA(dwGCS, lpCompStrW, NULL);
    00389             if (dwSize != 0) {
    00390                 HGLOBAL hUndetA = NULL;
    00391                 LPUNDETERMINESTRUCT lpUndetA;
    00392
    00393                 if (hUndetA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00394                     if (lpUndetA = (LPUNDETERMINESTRUCT)GlobalLock(hUndetA)) {
    00395                         CompStrWToUndetA(dwGCS, lpCompStrW, lpUndetA);
    00396                         fDoneUndet = TRUE;
    00397                         GlobalUnlock(hUndetA);
    00398
    00399                         if (SendMessageA(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetA)) {
    00400                             GlobalFree(hUndetA);
    00401                             return 0;
    00402                         }
    00403                     }
    00404                     GlobalFree(hUndetA);
    00405                 }
    00406             }
    00407         }
    00408         else {
    00409             dwSize = CompStrWToUndetW(dwGCS, lpCompStrW, NULL);
    00410             if (dwSize != 0) {
    00411                 HGLOBAL hUndetW = NULL;
    00412                 LPUNDETERMINESTRUCT lpUndetW;
    00413
    00414                 if (hUndetW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00415                     if (lpUndetW = (LPUNDETERMINESTRUCT)GlobalLock(hUndetW)) {
    00416                         CompStrWToUndetW(dwGCS, lpCompStrW, lpUndetW);
    00417                         fDoneUndet = TRUE;
    00418                         GlobalUnlock(hUndetW);
    00419
    00420                         if (SendMessageW(hWnd,WM_IME_REPORT,IR_UNDETERMINE, (LPARAM)hUndetW)) {
    00421                             GlobalFree(hUndetW);
    00422                             return 0;
    00423                         }
    00424                     }
    00425                     GlobalFree(hUndetW);
    00426                 }
    00427             }
    00428         }
    00429     }
    00430
    00431     //
    00432     // This is generate result string routine.
    00433     // This should be same as WINNLSSendString of WIN3.1.
    00434     //
    00435
    00436     if (dwGCS & GCS_RESULTSTR)
    00437     {
    00438         //
    00439         // Can we generate IR_STRINGEX ?
    00440         //
    00441
    00442         if (dwGCS & GCS_RESULTREADSTR)
    00443         {
    00444             if (bAnsiWnd) {
    00445                 dwSize = CompStrWToStringExA(dwGCS, lpCompStrW, NULL);
    00446                 if (dwSize != 0) {
    00447                     HGLOBAL hStringExA = NULL;
    00448                     LPSTRINGEXSTRUCT lpStringExA;
    00449
    00450                     if (hStringExA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00451                         if (lpStringExA = (LPSTRINGEXSTRUCT)GlobalLock(hStringExA)) {
    00452                             CompStrWToStringExA(dwGCS, lpCompStrW, lpStringExA);
    00453                             GlobalUnlock(hStringExA);
    00454
    00455                             if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExA))
    00456                             {
    00457                                 GlobalFree(hStringExA);
    00458                                 fDoneDet = TRUE;
    00459                                 goto jtc_exit_30;
    00460                             }
    00461                         }
    00462                         GlobalFree(hStringExA);
    00463                     }
    00464                 }
    00465             }
    00466             else {
    00467                 dwSize = CompStrWToStringExW(dwGCS, lpCompStrW, NULL);
    00468                 if (dwSize != 0) {
    00469                     HGLOBAL hStringExW = NULL;
    00470                     LPSTRINGEXSTRUCT lpStringExW;
    00471
    00472                     if (hStringExW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00473                         if (lpStringExW = (LPSTRINGEXSTRUCT)GlobalLock(hStringExW)) {
    00474                             CompStrWToStringExW(dwGCS, lpCompStrW, lpStringExW);
    00475                             GlobalUnlock(hStringExW);
    00476
    00477                             if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRINGEX, (LPARAM)hStringExW))
    00478                             {
    00479                                 GlobalFree(hStringExW);
    00480                                 fDoneDet = TRUE;
    00481                                 goto jtc_exit_30;
    00482                             }
    00483                         }
    00484                         GlobalFree(hStringExW);
    00485                     }
    00486                 }
    00487             }
    00488         }
    00489
    00490         //
    00491         // generate IR_STRING
    00492         //
    00493
    00494         if (bAnsiWnd) {
    00495             dwSize = CompStrWToStringA(lpCompStrW, NULL);
    00496             if (dwSize != 0) {
    00497                 HGLOBAL hStringA = NULL;
    00498                 LPSTR lpStringA;
    00499
    00500                 if (hStringA = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00501                     if (lpStringA = (LPSTR)GlobalLock(hStringA)) {
    00502                         CompStrWToStringA(lpCompStrW, lpStringA);
    00503                         GlobalUnlock(hStringA);
    00504
    00505                         if (SendMessageA(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringA))
    00506                         {
    00507                             GlobalFree(hStringA);
    00508                             fDoneDet = TRUE;
    00509                             goto jtc_exit_30;
    00510                         }
    00511                     }
    00512                     GlobalFree(hStringA);
    00513                 }
    00514             }
    00515             else {
    00516                 return 0;
    00517             }
    00518         }
    00519         else {
    00520             dwSize = CompStrWToStringW(lpCompStrW, NULL);
    00521             if (dwSize != 0) {
    00522                 HGLOBAL hStringW = NULL;
    00523                 LPWSTR lpStringW;
    00524
    00525                 if (hStringW = GlobalAlloc(GHND | GMEM_SHARE, dwSize)) {
    00526                     if (lpStringW = (LPWSTR)GlobalLock(hStringW)) {
    00527                         CompStrWToStringW(lpCompStrW, lpStringW);
    00528                         GlobalUnlock(hStringW);
    00529
    00530                         if (SendMessageW(hWnd,WM_IME_REPORT,IR_STRING, (LPARAM)hStringW))
    00531                         {
    00532                             GlobalFree(hStringW);
    00533                             fDoneDet = TRUE;
    00534                             goto jtc_exit_30;
    00535                         }
    00536                     }
    00537                     GlobalFree(hStringW);
    00538                 }
    00539             }
    00540             else {
    00541                 return 0;
    00542             }
    00543         }
    00544
    00545         //
    00546         // generate IR_DBCSCHAR/IR_STRINGSTART/WM_CHAR/IR_STRINGEND
    00547         //
    00548
    00549         if (bAnsiWnd) {
    00550             CompStrWToCharA(hWnd, lpCompStrW);
    00551         }
    00552         else {
    00553             CompStrWToCharW(hWnd, lpCompStrW);
    00554         }
    00555
    00556         fDoneDet = TRUE;
    00557     }
    00558
    00559
    00560     if (!fDoneUndet && !fDoneDet)
    00561     {
    00562         *pTransMsgDest = *pTransMsgSrc;
    00563         iNum++;
    00564     }
    00565
    00566 jtc_exit_30:
    00567
    00568     if (!fDoneUndet && fDoneDet && (dwGCS & GCS_COMPSTR))
    00569     {
    00570         pTransMsgDest->message = pTransMsgSrc->message;
    00571         pTransMsgDest->wParam  = pTransMsgSrc->wParam;
    00572         pTransMsgDest->lParam  = (LPARAM)(dwGCS & ~(GCS_RESULT | GCS_RESULTREAD));
    00573         iNum++;
    00574     }
    00575
    00576     return iNum;
    00577 }
    00578
    00579
    00580
    00581 UINT
    00582 WINNLSTranslateMessageJ(
    00583     UINT                uiNumMsg,
    00584     PTRANSMSG           pTransMsg,
    00585     LPINPUTCONTEXT      lpIMC,
    00586     LPCOMPOSITIONSTRING lpCompStr,
    00587     BOOL bAnsiIMC
    00588     )
    00589
    00590 /*++
    00591
    00592 Routine Description:
    00593
    00594 Arguments:
    00595
    00596 Return Value:
    00597
    00598 --*/
    00599
    00600 {
    00601     PTRANSMSG       pTransMsgBuf, pTransMsgTemp;
    00602     UINT            uiNewNum = 0;
    00603     UINT            uiTempNum;
    00604     DWORD           dwTempSize;
    00605     HWND            hDefIMEWnd;
    00606     UINT            i;
    00607     BOOL            bAnsiWnd;
    00608
    00609     hDefIMEWnd = ImmGetDefaultIMEWnd((HWND)lpIMC->hWnd);
    00610
    00611     bAnsiWnd = (! IsWindowUnicode(lpIMC->hWnd)) ? TRUE : FALSE;
    00612
    00613     dwTempSize = uiNumMsg * sizeof(TRANSMSG);
    00614
    00615     //
    00616     // Allocate one more TRANSMSG and ZEROINIT the whole thing!
    00617     //
    00618
    00619     pTransMsgBuf = (PTRANSMSG)ImmLocalAlloc( HEAP_ZERO_MEMORY,
    00620                                              dwTempSize + sizeof(TRANSMSG)
    00621                                            );
    00622     if ( pTransMsgBuf == NULL )
    00623         goto wtmsg2_j_10;
    00624
    00625     RtlCopyMemory(pTransMsgBuf, pTransMsg, dwTempSize);
    00626     pTransMsgTemp = pTransMsgBuf;
    00627
    00628     //
    00629     // When MCW_HIDDEN mode, WM_IME_ENDCOMPOSITION will be translated to
    00630     // IR_UNDETERMINE with 0 string. So that, this message have to be
    00631     // generated after all messages.
    00632     //
    00633
    00634     if (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) {
    00635
    00636         for (i = 0; i < uiNumMsg; i++, pTransMsgTemp++) {
    00637             if (pTransMsgTemp->message == WM_IME_ENDCOMPOSITION) {
    00638                 break;
    00639             }
    00640         }
    00641
    00642         if (pTransMsgTemp->message == WM_IME_ENDCOMPOSITION) {
    00643
    00644             PTRANSMSG pTransMsgSrc = pTransMsgTemp + 1;
    00645
    00646             while (pTransMsgSrc->message != 0) {
    00647                 *pTransMsgTemp++ = *pTransMsgSrc++;
    00648             }
    00649
    00650             pTransMsgTemp->message = WM_IME_ENDCOMPOSITION;
    00651             pTransMsgTemp->wParam  = 0L;
    00652             pTransMsgTemp->lParam  = 0L;
    00653
    00654         }
    00655
    00656         pTransMsgTemp = pTransMsgBuf;
    00657     }
    00658
    00659     while (pTransMsgTemp->message != 0) {
    00660
    00661         switch (pTransMsgTemp->message)
    00662         {
    00663             case WM_IME_COMPOSITION:
    00664
    00665                 if (bAnsiIMC)
    00666                     uiTempNum = JTransCompositionA(lpIMC,lpCompStr,pTransMsgTemp,pTransMsg);
    00667                 else
    00668                     uiTempNum = JTransCompositionW(lpIMC,lpCompStr,pTransMsgTemp,pTransMsg);
    00669
    00670                 uiNewNum  += uiTempNum;
    00671                 pTransMsg += uiTempNum;
    00672
    00673                 if ( !(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) )
    00674                 {
    00675                     if ( lpIMC->cfCompForm.dwStyle != CFS_DEFAULT ) {
    00676                         SendMessage((HWND)lpIMC->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0L);
    00677                     }
    00678                 }
    00679
    00680                 break;
    00681
    00682             case WM_IME_STARTCOMPOSITION:
    00683
    00684                 if ( !(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) )
    00685                 {
    00686                     if ( lpIMC->cfCompForm.dwStyle != CFS_DEFAULT ) {
    00687                         SendMessage((HWND)lpIMC->hWnd, WM_IME_REPORT, IR_OPENCONVERT, 0L);
    00688                     }
    00689
    00690                     *pTransMsg++ = *pTransMsgTemp;
    00691                     uiNewNum++;
    00692                 }
    00693
    00694                 break;
    00695
    00696             case WM_IME_ENDCOMPOSITION:
    00697
    00698                 if ( !(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN) )
    00699                 {
    00700                     if ( lpIMC->cfCompForm.dwStyle != CFS_DEFAULT ) {
    00701                         SendMessage((HWND)lpIMC->hWnd, WM_IME_REPORT, IR_CLOSECONVERT, 0L);
    00702                     }
    00703
    00704                     *pTransMsg++ = *pTransMsgTemp;
    00705                     uiNewNum++;
    00706
    00707                 }
    00708                 else {
    00709
    00710                     HWND hWnd = (HWND)lpIMC->hWnd;
    00711                     HGLOBAL hUndet = 0L;
    00712
    00713                     if (hUndet = GlobalAlloc(GHND | GMEM_SHARE, sizeof(UNDETERMINESTRUCT)))
    00714                     {
    00715                         if (! IsWindowUnicode(lpIMC->hWnd))
    00716                             SendMessageA(hWnd,WM_IME_REPORT, IR_UNDETERMINE, (LPARAM)hUndet);
    00717                         else
    00718                             SendMessageW(hWnd,WM_IME_REPORT, IR_UNDETERMINE, (LPARAM)hUndet);
    00719
    00720                         GlobalFree(hUndet);
    00721                     }
    00722                 }
    00723
    00724                 break;
    00725
    00726             case WM_IME_NOTIFY:
    00727
    00728                 switch (pTransMsgTemp->wParam)
    00729                 {
    00730                     case IMN_OPENCANDIDATE:
    00731
    00732                         //
    00733                         // When 3.1 Application want to set MCW_HIDDEN,
    00734                         // the candidate window of Chicago IME go way
    00735                         // from the restangle of the composition string
    00736                         // that will be drawn by the application.
    00737                         //
    00738
    00739                         if (IsWindow((HWND)lpIMC->hWnd) &&
    00740                             (lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN)) {
    00741                             CANDIDATEFORM cfCandForm;
    00742                             DWORD i;
    00743                             DWORD dwNumCand = 0;
    00744
    00745                             for (i = 0; i < 32; i++)
    00746                             {
    00747                                 //
    00748                                 // Only the opened candidate should be updated.
    00749                                 //
    00750                                 if (!(pTransMsgTemp->lParam & (01L << i)))
    00751                                     continue;
    00752
    00753                                 cfCandForm.dwIndex = i;
    00754                                 cfCandForm.dwStyle = CFS_EXCLUDE;
    00755                                 cfCandForm.ptCurrentPos = lpIMC->cfCompForm.ptCurrentPos;
    00756                                 cfCandForm.rcArea       = lpIMC->cfCompForm.rcArea;
    00757                                 SendMessage(hDefIMEWnd, WM_IME_CONTROL, IMC_SETCANDIDATEPOS,
    00758                                                (LPARAM)(LPCANDIDATEFORM)&cfCandForm);
    00759                             }
    00760                         }
    00761
    00762                         break;
    00763
    00764                     default :
    00765                         break;
    00766                 }
    00767
    00768                 if (!(lpIMC->fdw31Compat & F31COMPAT_MCWHIDDEN)) {
    00769                     *pTransMsg++ = *pTransMsgTemp;
    00770                     uiNewNum++;
    00771                 }
    00772                 else {
    00773                     //
    00774                     // For win31 apps who set MCW_HIDDEN, we won't give them
    00775                     // IMN_OPENCANDIDATE here. Instead, send it directly to the
    00776                     // default IME window.
    00777                     //
    00778                     SendMessage( hDefIMEWnd,
    00779                                  pTransMsgTemp->message,
    00780                                  pTransMsgTemp->wParam,
    00781                                  pTransMsgTemp->lParam
    00782                                );
    00783                 }
    00784
    00785                 break;
    00786
    00787             default :
    00788                 *pTransMsg++ = *pTransMsgTemp;
    00789                 uiNewNum++;
    00790                 break;
    00791         }
    00792
    00793         pTransMsgTemp++;
    00794     }
    00795
    00796     ImmLocalFree(pTransMsgBuf);
    00797
    00798 wtmsg2_j_10:
    00799     return (uiNewNum);
    00800 }
    00801
    00802
    00803 DWORD
    00804 CompStrAToUndetA(
    00805     DWORD dwGCS,
    00806     LPCOMPOSITIONSTRING lpCompStrA,
    00807     LPUNDETERMINESTRUCT lpUndetA
    00808     )
    00809
    00810 /*++
    00811
    00812 Routine Description:
    00813
    00814     Convert composition string (ANSI) to undetermine string (ANSI).
    00815
    00816 Arguments:
    00817
    00818 Return Value:
    00819
    00820 --*/
    00821
    00822 {
    00823     DWORD dwPos;
    00824     DWORD dwSize;
    00825     UINT  i;
    00826
    00827     dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) +
    00828              DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(CHAR))) +
    00829              DWORD_ALIGN((lpCompStrA->dwResultClauseLen+1)) +
    00830              DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(CHAR))) +
    00831              DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen+1)) +
    00832              DWORD_ALIGN((lpCompStrA->dwCompAttrLen+1)) +
    00833              DWORD_ALIGN(((lpCompStrA->dwCompStrLen+1) * sizeof(CHAR)));
    00834
    00835     if (lpUndetA == NULL) {
    00836         return dwSize;
    00837     }
    00838
    00839     dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1));
    00840     lpUndetA->dwSize = dwSize;
    00841
    00842     if (dwGCS & GCS_COMPSTR)
    00843     {
    00844         lpUndetA->uUndetTextLen = lpCompStrA->dwCompStrLen;
    00845         lpUndetA->uUndetTextPos = dwPos;
    00846         memcpy((PBYTE)lpUndetA   + dwPos,
    00847                (PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset,
    00848                lpCompStrA->dwCompStrLen * sizeof(CHAR)
    00849               );
    00850         *(LPSTR)((PBYTE)lpUndetA + dwPos + lpCompStrA->dwCompStrLen*sizeof(CHAR)) = '\0';
    00851         dwPos += DWORD_ALIGN(((lpUndetA->uUndetTextLen+1)*sizeof(CHAR)));
    00852
    00853         // Sometime Chicago IME does not generate GCS_COMPATTR
    00854         // with GCS_COMPSTR. But uUndetAttrPos should be filled
    00855         // when the UndetText is updated.
    00856         if (lpCompStrA->dwCompAttrLen && !(dwGCS & GCS_COMPATTR))
    00857             dwGCS |= GCS_COMPATTR;
    00858     }
    00859
    00860     if (dwGCS & GCS_COMPATTR)
    00861     {
    00862         lpUndetA->uUndetAttrPos = dwPos;
    00863         memcpy((PBYTE)lpUndetA   + dwPos,
    00864                (PBYTE)lpCompStrA + lpCompStrA->dwCompAttrOffset,
    00865                lpCompStrA->dwCompAttrLen
    00866               );
    00867         dwPos += DWORD_ALIGN((lpUndetA->uUndetTextLen + 1));
    00868     }
    00869
    00870     if (dwGCS & GCS_CURSORPOS)
    00871     {
    00872         lpUndetA->uCursorPos = lpCompStrA->dwCursorPos;
    00873     }
    00874
    00875     if (dwGCS & GCS_DELTASTART)
    00876     {
    00877         lpUndetA->uDeltaStart = lpCompStrA->dwDeltaStart;
    00878     }
    00879
    00880     if (dwGCS & GCS_RESULTSTR)
    00881     {
    00882         lpUndetA->uDetermineTextLen = lpCompStrA->dwResultStrLen;
    00883         lpUndetA->uDetermineTextPos = dwPos;
    00884         memcpy((PBYTE)lpUndetA   + dwPos,
    00885                (PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset,
    00886                lpCompStrA->dwResultStrLen * sizeof(CHAR)
    00887               );
    00888         *(LPSTR)((PBYTE)lpUndetA + dwPos + lpCompStrA->dwResultStrLen*sizeof(CHAR)) = '\0';
    00889         dwPos += DWORD_ALIGN(((lpUndetA->uDetermineTextLen + 1)*sizeof(CHAR)));
    00890     }
    00891
    00892     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    00893          (lpCompStrA->dwResultClauseLen > 0) )
    00894     {
    00895         LPDWORD lpw;
    00896         LPDWORD lpdw;
    00897
    00898         lpUndetA->uDetermineDelimPos = dwPos;
    00899
    00900         lpw  = (LPDWORD)((PBYTE)lpUndetA + dwPos);
    00901         lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset);
    00902         for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++)
    00903             *lpw++ = *lpdw++;
    00904
    00905         dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1));
    00906     }
    00907
    00908     if (dwGCS & GCS_RESULTREADSTR)
    00909     {
    00910         lpUndetA->uYomiTextLen = lpCompStrA->dwResultReadStrLen;
    00911         lpUndetA->uYomiTextPos = dwPos;
    00912         memcpy((PBYTE)lpUndetA   + dwPos,
    00913                (PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset,
    00914                lpCompStrA->dwResultReadStrLen * sizeof(CHAR)
    00915               );
    00916         *(LPSTR)((PBYTE)lpUndetA + dwPos + lpCompStrA->dwResultReadStrLen*sizeof(CHAR)) = '\0';
    00917         dwPos += DWORD_ALIGN(((lpUndetA->uYomiTextLen + 1)*sizeof(CHAR)));
    00918     }
    00919
    00920     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    00921          (lpCompStrA->dwResultReadClauseLen > 0) )
    00922     {
    00923         LPDWORD lpw;
    00924         LPDWORD lpdw;
    00925
    00926         lpUndetA->uYomiDelimPos = dwPos;
    00927
    00928         lpw  = (LPDWORD)((PBYTE)lpUndetA + dwPos);
    00929         lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset);
    00930         for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++)
    00931             *lpw++ = *lpdw++;
    00932
    00933         dwPos += DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen + 1));
    00934     }
    00935
    00936     return dwSize;
    00937 }
    00938
    00939 DWORD
    00940 CompStrAToUndetW(
    00941     DWORD dwGCS,
    00942     LPCOMPOSITIONSTRING lpCompStrA,
    00943     LPUNDETERMINESTRUCT lpUndetW
    00944     )
    00945
    00946 /*++
    00947
    00948 Routine Description:
    00949
    00950     Convert composition string (ANSI) to undetermine string (Unicode).
    00951
    00952 Arguments:
    00953
    00954 Return Value:
    00955
    00956 --*/
    00957
    00958 {
    00959     DWORD dwPos;
    00960     DWORD dwSize;
    00961     UINT  i;
    00962
    00963     dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) +
    00964              DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(WCHAR))) +
    00965              DWORD_ALIGN((lpCompStrA->dwResultClauseLen+1)) +
    00966              DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(WCHAR))) +
    00967              DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen+1)) +
    00968              DWORD_ALIGN((lpCompStrA->dwCompAttrLen * 2)) +
    00969              DWORD_ALIGN(((lpCompStrA->dwCompStrLen+1) * sizeof(WCHAR)));
    00970
    00971     if (lpUndetW == NULL) {
    00972         return dwSize;
    00973     }
    00974
    00975     dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1));
    00976     lpUndetW->dwSize = dwSize;
    00977
    00978     if (dwGCS & GCS_COMPSTR)
    00979     {
    00980         i = MultiByteToWideChar( CP_ACP,
    00981                                 (DWORD)MB_PRECOMPOSED,
    00982                                 (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset),  // src
    00983                                 (INT)lpCompStrA->dwCompStrLen,
    00984                                 (LPWSTR)((PBYTE)lpUndetW + dwPos),                         // dest
    00985                                 (INT)dwSize - dwPos);
    00986         ((LPWSTR)((PBYTE)lpUndetW + dwPos))[i] = L'\0';
    00987         lpUndetW->uUndetTextLen = i;
    00988         lpUndetW->uUndetTextPos = dwPos;
    00989         dwPos += DWORD_ALIGN(((lpUndetW->uUndetTextLen + 1)*sizeof(WCHAR)));
    00990
    00991         // Sometime Chicago IME does not generate GCS_COMPATTR
    00992         // with GCS_COMPSTR. But uUndetAttrPos should be filled
    00993         // when the UndetText is updated.
    00994         if (lpCompStrA->dwCompAttrLen && !(dwGCS & GCS_COMPATTR))
    00995             dwGCS |= GCS_COMPATTR;
    00996     }
    00997
    00998     if (dwGCS & GCS_COMPATTR)
    00999     {
    01000         if (lpUndetW->uUndetTextLen != 0) {
    01001             LPWSTR lpwszUndetText;
    01002             PBYTE  lpAttrW;
    01003             PBYTE  lpAttrA;
    01004             WCHAR  wc;
    01005             ULONG  MultiByteSize;
    01006
    01007             lpwszUndetText = (LPWSTR)((PBYTE)lpUndetW + lpUndetW->uUndetTextPos);
    01008             lpAttrA = (PBYTE)lpCompStrA + lpCompStrA->dwCompAttrOffset;
    01009             lpAttrW = (PBYTE)lpUndetW   + dwPos;
    01010
    01011             while (wc=*lpwszUndetText++) {
    01012                 RtlUnicodeToMultiByteSize(&MultiByteSize, &wc, sizeof(WCHAR));
    01013                 if (MultiByteSize == 2) {
    01014                     *lpAttrW++ = *lpAttrA;
    01015                     lpAttrA += 2;
    01016                 }
    01017                 else {
    01018                     *lpAttrW++ = *lpAttrA++;
    01019                 }
    01020             }
    01021
    01022             lpUndetW->uUndetAttrPos = dwPos;
    01023             dwPos += DWORD_ALIGN((lpUndetW->uUndetTextLen + 1));
    01024         }
    01025     }
    01026
    01027     if (dwGCS & GCS_CURSORPOS)
    01028     {
    01029         if (lpCompStrA->dwCursorPos != -1) {
    01030             lpUndetW->uCursorPos = CalcCharacterPositionAtoW(lpCompStrA->dwCursorPos,
    01031                                                              (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset),
    01032                                                              CP_ACP
    01033                                                             );
    01034         }
    01035         else {
    01036             lpUndetW->uCursorPos = lpCompStrA->dwCursorPos;
    01037         }
    01038     }
    01039
    01040     if (dwGCS & GCS_DELTASTART)
    01041     {
    01042         if (lpCompStrA->dwDeltaStart != -1) {
    01043             lpUndetW->uDeltaStart = CalcCharacterPositionAtoW(lpCompStrA->dwDeltaStart,
    01044                                                               (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwCompStrOffset),
    01045                                                               CP_ACP
    01046                                                              );
    01047         }
    01048         else {
    01049             lpUndetW->uDeltaStart = lpCompStrA->dwDeltaStart;
    01050         }
    01051     }
    01052
    01053     if (dwGCS & GCS_RESULTSTR)
    01054     {
    01055         i = MultiByteToWideChar( CP_ACP,
    01056                                 (DWORD)MB_PRECOMPOSED,
    01057                                 (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset),  // src
    01058                                 (INT)lpCompStrA->dwResultStrLen,
    01059                                 (LPWSTR)((PBYTE)lpUndetW + dwPos),                           // dest
    01060                                 (INT)dwSize - dwPos);
    01061         ((LPWSTR)((PBYTE)lpUndetW + dwPos))[i] = L'\0';
    01062         lpUndetW->uDetermineTextLen = i;
    01063         lpUndetW->uDetermineTextPos = dwPos;
    01064         dwPos += DWORD_ALIGN(((lpUndetW->uDetermineTextLen + 1)*sizeof(WCHAR)));
    01065     }
    01066
    01067     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    01068          (lpCompStrA->dwResultClauseLen > 0) )
    01069     {
    01070         if (lpUndetW->uDetermineTextLen != 0) {
    01071             LPDWORD lpw;
    01072             LPDWORD lpdw;
    01073
    01074             lpw  = (LPDWORD)((PBYTE)lpUndetW + dwPos);
    01075             lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset);
    01076
    01077             for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++) {
    01078                 *lpw++ = CalcCharacterPositionAtoW(*lpdw++,
    01079                                                    (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset),
    01080                                                    CP_ACP
    01081                                                   );
    01082             }
    01083
    01084             lpUndetW->uDetermineDelimPos = dwPos;
    01085             dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1));
    01086         }
    01087     }
    01088
    01089     if (dwGCS & GCS_RESULTREADSTR)
    01090     {
    01091         i = MultiByteToWideChar( CP_ACP,
    01092                                 (DWORD)MB_PRECOMPOSED,
    01093                                 (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset),  // src
    01094                                 (INT)lpCompStrA->dwResultReadStrLen,
    01095                                 (LPWSTR)((PBYTE)lpUndetW + dwPos),                               // dest
    01096                                 (INT)dwSize - dwPos);
    01097         ((LPWSTR)((PBYTE)lpUndetW + dwPos))[i] = L'\0';
    01098         lpUndetW->uYomiTextLen = i;
    01099         lpUndetW->uYomiTextPos = dwPos;
    01100         dwPos += DWORD_ALIGN(((lpUndetW->uYomiTextLen + 1)*sizeof(WCHAR)));
    01101     }
    01102
    01103     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    01104          (lpCompStrA->dwResultReadClauseLen > 0) )
    01105     {
    01106         if (lpUndetW->uYomiTextLen != 0) {
    01107             LPDWORD lpw;
    01108             LPDWORD lpdw;
    01109
    01110             lpw  = (LPDWORD)((PBYTE)lpUndetW + dwPos);
    01111             lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset);
    01112
    01113             for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++) {
    01114                 *lpw++ = CalcCharacterPositionAtoW(*lpdw++,
    01115                                                    (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset),
    01116                                                    CP_ACP
    01117                                                   );
    01118             }
    01119
    01120             lpUndetW->uYomiDelimPos = dwPos;
    01121             dwPos += DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen + 1));
    01122         }
    01123     }
    01124
    01125     return dwSize;
    01126 }
    01127
    01128
    01129 DWORD
    01130 CompStrAToStringExA(
    01131     DWORD dwGCS,
    01132     LPCOMPOSITIONSTRING lpCompStrA,
    01133     LPSTRINGEXSTRUCT lpStringExA
    01134     )
    01135
    01136 /*++
    01137
    01138 Routine Description:
    01139
    01140     Convert composition string (ANSI) to StringEx (ANSI).
    01141
    01142 Arguments:
    01143
    01144 Return Value:
    01145
    01146 --*/
    01147
    01148 {
    01149     DWORD dwPos;
    01150     DWORD dwSize;
    01151     UINT  i;
    01152
    01153     dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) +
    01154              DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(CHAR))) +
    01155              DWORD_ALIGN(lpCompStrA->dwResultClauseLen+1) +
    01156              DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(CHAR))) +
    01157              DWORD_ALIGN(lpCompStrA->dwResultReadClauseLen+1);
    01158
    01159     if (lpStringExA == NULL) {
    01160         return dwSize;
    01161     }
    01162
    01163     dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1);
    01164     lpStringExA->dwSize = dwSize;
    01165
    01166     lpStringExA->uDeterminePos = dwPos;
    01167     memcpy((PBYTE)lpStringExA + dwPos,
    01168            (PBYTE)lpCompStrA  + lpCompStrA->dwResultStrOffset,
    01169            lpCompStrA->dwResultStrLen * sizeof(CHAR)
    01170           );
    01171     *(LPSTR)((PBYTE)lpStringExA + dwPos + lpCompStrA->dwResultStrLen*sizeof(CHAR)) = '\0';
    01172     dwPos += DWORD_ALIGN(((lpCompStrA->dwResultStrLen + 1)*sizeof(CHAR)));
    01173
    01174     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    01175          (lpCompStrA->dwResultClauseLen > 0) )
    01176     {
    01177         LPDWORD lpw;
    01178         LPDWORD lpdw;
    01179
    01180         lpStringExA->uDetermineDelimPos = dwPos;
    01181
    01182         lpw  = (LPDWORD)((PBYTE)lpStringExA + dwPos);
    01183         lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset);
    01184         for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++)
    01185             *lpw++ = *lpdw++;
    01186
    01187         dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1));
    01188     }
    01189
    01190     lpStringExA->uYomiPos = dwPos;
    01191     memcpy((PBYTE)lpStringExA + dwPos,
    01192            (PBYTE)lpCompStrA  + lpCompStrA->dwResultReadStrOffset,
    01193            lpCompStrA->dwResultReadStrLen * sizeof(CHAR)
    01194           );
    01195     *(LPSTR)((PBYTE)lpStringExA + dwPos + lpCompStrA->dwResultReadStrLen*sizeof(CHAR)) = '\0';
    01196     dwPos += DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen + 1)*sizeof(CHAR)));
    01197
    01198     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    01199          (lpCompStrA->dwResultReadClauseLen > 0) )
    01200     {
    01201         LPDWORD lpw;
    01202         LPDWORD lpdw;
    01203
    01204         lpStringExA->uYomiDelimPos = dwPos;
    01205
    01206         lpw  = (LPDWORD)((PBYTE)lpStringExA + dwPos);
    01207         lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset);
    01208         for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++)
    01209             *lpw++ = *lpdw++;
    01210     }
    01211
    01212     return dwSize;
    01213 }
    01214
    01215 DWORD
    01216 CompStrAToStringExW(
    01217     DWORD dwGCS,
    01218     LPCOMPOSITIONSTRING lpCompStrA,
    01219     LPSTRINGEXSTRUCT lpStringExW
    01220     )
    01221
    01222 /*++
    01223
    01224 Routine Description:
    01225
    01226     Convert composition string (ANSI) to StringEx (Unicode).
    01227
    01228 Arguments:
    01229
    01230 Return Value:
    01231
    01232 --*/
    01233
    01234 {
    01235     DWORD dwPos;
    01236     DWORD dwSize;
    01237     DWORD dwLen;
    01238     UINT  i;
    01239
    01240     dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) +
    01241              (lpCompStrA->dwResultStrLen > 0 ? DWORD_ALIGN(((lpCompStrA->dwResultStrLen+1) * sizeof(WCHAR))) : 0) +
    01242              (lpCompStrA->dwResultClauseLen > 0 ? DWORD_ALIGN(lpCompStrA->dwResultClauseLen+1) : 0) +
    01243              (lpCompStrA->dwResultReadStrLen > 0 ? DWORD_ALIGN(((lpCompStrA->dwResultReadStrLen+1) * sizeof(WCHAR))) : 0)+
    01244              (lpCompStrA->dwResultReadClauseLen > 0 ? DWORD_ALIGN(lpCompStrA->dwResultReadClauseLen+1) : 0);
    01245
    01246     if (lpStringExW == NULL) {
    01247         return dwSize;
    01248     }
    01249
    01250     dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1);
    01251     lpStringExW->dwSize = dwSize;
    01252
    01253     if (lpCompStrA->dwResultStrLen > 0) {
    01254         i = MultiByteToWideChar( CP_ACP,
    01255                                 (DWORD)MB_PRECOMPOSED,
    01256                                 (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset),  // src
    01257                                 (INT)lpCompStrA->dwResultStrLen,
    01258                                 (LPWSTR)((PBYTE)lpStringExW + dwPos),                        // dest
    01259                                 (INT)dwSize - dwPos);
    01260         ((LPWSTR)((PBYTE)lpStringExW + dwPos))[i] = L'\0';
    01261         dwLen = i;
    01262         lpStringExW->uDeterminePos = dwPos;
    01263         dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(WCHAR)));
    01264     } else {
    01265         dwLen = 0;
    01266         lpStringExW->uDeterminePos = 0;
    01267     }
    01268
    01269     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    01270          (lpCompStrA->dwResultClauseLen > 0) )
    01271     {
    01272         if (dwLen != 0 && lpCompStrA->dwResultClauseLen > 0) {
    01273             LPDWORD lpw;
    01274             LPDWORD lpdw;
    01275
    01276             lpw  = (LPDWORD)((PBYTE)lpStringExW + dwPos);
    01277             lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultClauseOffset);
    01278
    01279             for (i = 0; i < (lpCompStrA->dwResultClauseLen / sizeof(DWORD)); i++) {
    01280                 *lpw++ = CalcCharacterPositionAtoW(*lpdw++,
    01281                                                    (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset),
    01282                                                    CP_ACP
    01283                                                   );
    01284             }
    01285
    01286             lpStringExW->uDetermineDelimPos = dwPos;
    01287             dwPos += DWORD_ALIGN((lpCompStrA->dwResultClauseLen + 1));
    01288         }
    01289     }
    01290
    01291     if (lpCompStrA->dwResultReadStrLen > 0) {
    01292         i = MultiByteToWideChar( CP_ACP,
    01293                                 (DWORD)MB_PRECOMPOSED,
    01294                                 (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset),  // src
    01295                                 (INT)lpCompStrA->dwResultReadStrLen,
    01296                                 (LPWSTR)((PBYTE)lpStringExW + dwPos),                            // dest
    01297                                 (INT)dwSize - dwPos);
    01298         ((LPWSTR)((PBYTE)lpStringExW + dwPos))[i] = L'\0';
    01299         dwLen = i;
    01300         lpStringExW->uYomiPos = dwPos;
    01301         dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(WCHAR)));
    01302     } else {
    01303         dwLen = 0;
    01304         lpStringExW->uYomiPos = 0;
    01305     }
    01306
    01307     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    01308          (lpCompStrA->dwResultReadClauseLen > 0) )
    01309     {
    01310         if (dwLen != 0 && lpCompStrA->dwResultReadClauseLen > 0) {
    01311             LPDWORD lpw;
    01312             LPDWORD lpdw;
    01313
    01314             lpw  = (LPDWORD)((PBYTE)lpStringExW + dwPos);
    01315             lpdw = (LPDWORD)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadClauseOffset);
    01316
    01317             for (i = 0; i < (lpCompStrA->dwResultReadClauseLen / sizeof(DWORD)); i++) {
    01318                 *lpw++ = CalcCharacterPositionAtoW(*lpdw++,
    01319                                                    (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultReadStrOffset),
    01320                                                    CP_ACP
    01321                                                   );
    01322             }
    01323
    01324             lpStringExW->uYomiDelimPos = dwPos;
    01325             dwPos += DWORD_ALIGN((lpCompStrA->dwResultReadClauseLen + 1));
    01326         }
    01327     }
    01328
    01329     return dwSize;
    01330 }
    01331
    01332 DWORD
    01333 CompStrAToStringA(
    01334     LPCOMPOSITIONSTRING lpCompStrA,
    01335     LPSTR lpStringA
    01336     )
    01337
    01338 /*++
    01339
    01340 Routine Description:
    01341
    01342     Convert composition string (ANSI) to String (ANSI).
    01343
    01344 Arguments:
    01345
    01346 Return Value:
    01347
    01348 --*/
    01349
    01350 {
    01351     LPSTR lpszString;
    01352     DWORD dwSize;
    01353
    01354     lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
    01355     dwSize = lpCompStrA->dwResultStrLen;
    01356
    01357     if (lpStringA == NULL) {
    01358         return ((dwSize + 1) * sizeof(CHAR));
    01359     }
    01360
    01361     memcpy((PBYTE)lpStringA,
    01362            (PBYTE)lpszString,
    01363            (dwSize * sizeof(CHAR))
    01364           );
    01365     lpStringA[dwSize] = '\0';
    01366
    01367     return ((dwSize + 1) * sizeof(CHAR));
    01368 }
    01369
    01370 DWORD
    01371 CompStrAToStringW(
    01372     LPCOMPOSITIONSTRING lpCompStrA,
    01373     LPWSTR lpStringW
    01374     )
    01375
    01376 /*++
    01377
    01378 Routine Description:
    01379
    01380     Convert composition string (ANSI) to String (Unicode).
    01381
    01382 Arguments:
    01383
    01384 Return Value:
    01385
    01386 --*/
    01387
    01388 {
    01389     LPSTR lpszString;
    01390     DWORD dwSize;
    01391     UINT  i;
    01392
    01393     lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
    01394
    01395     i = MultiByteToWideChar( CP_ACP,
    01396                             (DWORD)MB_PRECOMPOSED,
    01397                             (LPSTR)lpszString,              // src
    01398                             (INT)lpCompStrA->dwResultStrLen,
    01399                             (LPWSTR)lpStringW,              // dest
    01400                             (INT)0);
    01401
    01402     if (lpStringW == NULL) {
    01403         dwSize = (i+1) * sizeof(WCHAR);
    01404     }
    01405     else {
    01406         dwSize = (i+1) * sizeof(WCHAR);
    01407
    01408         i = MultiByteToWideChar( CP_ACP,
    01409                                 (DWORD)MB_PRECOMPOSED,
    01410                                 (LPSTR)lpszString,              // src
    01411                                 (INT)lpCompStrA->dwResultStrLen,
    01412                                 (LPWSTR)lpStringW,              // dest
    01413                                 (INT)dwSize);
    01414
    01415         lpStringW[i] = L'\0';
    01416         dwSize = (i+1) * sizeof(WCHAR);
    01417     }
    01418
    01419     return dwSize;
    01420 }
    01421
    01422 VOID
    01423 CompStrAToCharA(
    01424     HWND hWnd,
    01425     LPCOMPOSITIONSTRING lpCompStrA
    01426     )
    01427
    01428 /*++
    01429
    01430 Routine Description:
    01431
    01432     Convert composition string (ANSI) to WM_CHAR (ANSI).
    01433
    01434 Arguments:
    01435
    01436 Return Value:
    01437
    01438 --*/
    01439
    01440 {
    01441     LPSTR lpszString;
    01442     BOOL  fDBCSWmChar = FALSE;
    01443     WORD  wDBCSChar;
    01444     BYTE  szAscii[3];
    01445
    01446     lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
    01447
    01448     // IR_DBCSCHAR: If the app reply to this message with TRUE, we can
    01449     // queue up double byte character in a WM_CHAR message.
    01450     if ( GetClientInfo()->dwExpWinVer >= 0x030A ) {
    01451         fDBCSWmChar = (BOOL)SendMessageA( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L);
    01452     }
    01453
    01454     // Send IR_STRINGSTART prior to anything.
    01455     PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
    01456
    01457
    01458     while(szAscii[0]=*lpszString)
    01459     {
    01460         if( *CharNextA(lpszString) == 0 )
    01461         {
    01462             PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L );
    01463         }
    01464         if( IsDBCSLeadByte( szAscii[0] ) )
    01465         {
    01466             szAscii[1] = *((PBYTE)(lpszString+1));
    01467
    01468             //  If fDBCSWmChar==TRUE, The app can recieve WM_CHARs which
    01469             // have double byte code in wParam.
    01470             if ( fDBCSWmChar )
    01471             {
    01472                 // It's necessary to swap bytes to put 1st byte into upper
    01473                 // part of wParam, and 2nd byte into lower part.
    01474                 wDBCSChar = MAKEWORD(szAscii[1], szAscii[0]);
    01475                 PostMessageA( hWnd, WM_CHAR, (WPARAM)wDBCSChar|WMCR_IR_DBCSCHAR, 1L );
    01476             }
    01477             else
    01478             {
    01479                 // Send each byte on a WM_CHAR
    01480                 PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L);
    01481                 PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[1]), 1L);
    01482             }
    01483         }
    01484         else
    01485         {
    01486             PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L);
    01487         }
    01488         lpszString = CharNextA(lpszString);
    01489     }
    01490 }
    01491
    01492 VOID
    01493 CompStrAToCharW(
    01494     HWND hWnd,
    01495     LPCOMPOSITIONSTRING lpCompStrA
    01496     )
    01497
    01498 /*++
    01499
    01500 Routine Description:
    01501
    01502     Convert composition string (ANSI) to WM_CHAR (Unicode).
    01503
    01504 Arguments:
    01505
    01506 Return Value:
    01507
    01508 --*/
    01509
    01510 {
    01511     LPSTR lpszString;
    01512     UINT  i;
    01513     BYTE  c;
    01514     WORD  wszUnicode[2];
    01515
    01516     lpszString = (LPSTR)((PBYTE)lpCompStrA + lpCompStrA->dwResultStrOffset);
    01517
    01518     // IR_DBCSCHAR: If the app reply to this message with TRUE, we can
    01519     // queue up double byte character in a WM_CHAR message.
    01520     // SendMessageW( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L);
    01521
    01522     // Send IR_STRINGSTART prior to anything.
    01523     PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
    01524
    01525
    01526     while(c=*lpszString)
    01527     {
    01528         if( *CharNextA(lpszString) == 0 )
    01529         {
    01530             PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L );
    01531         }
    01532         if( IsDBCSLeadByte( c ) ) {
    01533             i = MultiByteToWideChar( CP_ACP,
    01534                                     (DWORD)MB_PRECOMPOSED,
    01535                                     (LPSTR)lpszString,  // src
    01536                                     (INT)2,
    01537                                     (LPWSTR)wszUnicode, // dest
    01538                                     (INT)sizeof(wszUnicode));
    01539         }
    01540         else {
    01541             i = MultiByteToWideChar( CP_ACP,
    01542                                     (DWORD)MB_PRECOMPOSED,
    01543                                     (LPSTR)lpszString,  // src
    01544                                     (INT)1,
    01545                                     (LPWSTR)wszUnicode, // dest
    01546                                     (INT)sizeof(wszUnicode));
    01547         }
    01548         if (i != 0) {
    01549             PostMessageW( hWnd, WM_CHAR, (WPARAM)(wszUnicode[0]), 1L);
    01550         }
    01551         lpszString = CharNextA(lpszString);
    01552     }
    01553 }
    01554
    01555 DWORD
    01556 CompStrWToUndetW(
    01557     DWORD dwGCS,
    01558     LPCOMPOSITIONSTRING lpCompStrW,
    01559     LPUNDETERMINESTRUCT lpUndetW
    01560     )
    01561
    01562 /*++
    01563
    01564 Routine Description:
    01565
    01566     Convert composition string (Unicode) to undetermine string (Unicode).
    01567
    01568 Arguments:
    01569
    01570 Return Value:
    01571
    01572 --*/
    01573
    01574 {
    01575     DWORD dwPos;
    01576     DWORD dwSize;
    01577     UINT  i;
    01578
    01579     dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) +
    01580              DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) +
    01581              DWORD_ALIGN((lpCompStrW->dwResultClauseLen+1)) +
    01582              DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) +
    01583              DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen+1)) +
    01584              DWORD_ALIGN((lpCompStrW->dwCompAttrLen+1)) +
    01585              DWORD_ALIGN(((lpCompStrW->dwCompStrLen+1) * sizeof(WCHAR)));
    01586
    01587     if (lpUndetW == NULL) {
    01588         return dwSize;
    01589     }
    01590
    01591     dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1));
    01592     lpUndetW->dwSize = dwSize;
    01593
    01594     if (dwGCS & GCS_COMPSTR)
    01595     {
    01596         lpUndetW->uUndetTextLen = lpCompStrW->dwCompStrLen;
    01597         lpUndetW->uUndetTextPos = dwPos;
    01598         memcpy((PBYTE)lpUndetW   + dwPos,
    01599                (PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset,
    01600                lpCompStrW->dwCompStrLen * sizeof(WCHAR)
    01601               );
    01602         *(LPWSTR)((PBYTE)lpUndetW + dwPos + lpCompStrW->dwCompStrLen*sizeof(WCHAR)) = L'\0';
    01603         dwPos += DWORD_ALIGN(((lpUndetW->uUndetTextLen+1)*sizeof(WCHAR)));
    01604
    01605         // Sometime Chicago IME does not generate GCS_COMPATTR
    01606         // with GCS_COMPSTR. But uUndetAttrPos should be filled
    01607         // when the UndetText is updated.
    01608         if (lpCompStrW->dwCompAttrLen && !(dwGCS & GCS_COMPATTR))
    01609             dwGCS |= GCS_COMPATTR;
    01610     }
    01611
    01612     if (dwGCS & GCS_COMPATTR)
    01613     {
    01614         lpUndetW->uUndetAttrPos = dwPos;
    01615         memcpy((PBYTE)lpUndetW   + dwPos,
    01616                (PBYTE)lpCompStrW + lpCompStrW->dwCompAttrOffset,
    01617                lpCompStrW->dwCompAttrLen
    01618               );
    01619         dwPos += DWORD_ALIGN((lpUndetW->uUndetTextLen + 1));
    01620     }
    01621
    01622     if (dwGCS & GCS_CURSORPOS)
    01623     {
    01624         lpUndetW->uCursorPos = lpCompStrW->dwCursorPos;
    01625     }
    01626
    01627     if (dwGCS & GCS_DELTASTART)
    01628     {
    01629         lpUndetW->uDeltaStart = lpCompStrW->dwDeltaStart;
    01630     }
    01631
    01632     if (dwGCS & GCS_RESULTSTR)
    01633     {
    01634         lpUndetW->uDetermineTextLen = lpCompStrW->dwResultStrLen;
    01635         lpUndetW->uDetermineTextPos = dwPos;
    01636         memcpy((PBYTE)lpUndetW   + dwPos,
    01637                (PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset,
    01638                lpCompStrW->dwResultStrLen * sizeof(WCHAR)
    01639               );
    01640         *(LPWSTR)((PBYTE)lpUndetW + dwPos + lpCompStrW->dwResultStrLen*sizeof(WCHAR)) = L'\0';
    01641         dwPos += DWORD_ALIGN(((lpUndetW->uDetermineTextLen + 1)*sizeof(WCHAR)));
    01642     }
    01643
    01644     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    01645          (lpCompStrW->dwResultClauseLen > 0) )
    01646     {
    01647         LPDWORD lpw;
    01648         LPDWORD lpdw;
    01649
    01650         lpUndetW->uDetermineDelimPos = dwPos;
    01651
    01652         lpw  = (LPDWORD)((PBYTE)lpUndetW + dwPos);
    01653         lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset);
    01654         for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++)
    01655             *lpw++ = *lpdw++;
    01656
    01657         dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1));
    01658     }
    01659
    01660     if (dwGCS & GCS_RESULTREADSTR)
    01661     {
    01662         lpUndetW->uYomiTextLen = lpCompStrW->dwResultReadStrLen;
    01663         lpUndetW->uYomiTextPos = dwPos;
    01664         memcpy((PBYTE)lpUndetW   + dwPos,
    01665                (PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset,
    01666                lpCompStrW->dwResultReadStrLen * sizeof(WCHAR)
    01667               );
    01668         *(LPWSTR)((PBYTE)lpUndetW + dwPos + lpCompStrW->dwResultReadStrLen*sizeof(WCHAR)) = L'\0';
    01669         dwPos += DWORD_ALIGN(((lpUndetW->uYomiTextLen + 1)*sizeof(WCHAR)));
    01670     }
    01671
    01672     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    01673          (lpCompStrW->dwResultReadClauseLen > 0) )
    01674     {
    01675         LPDWORD lpw;
    01676         LPDWORD lpdw;
    01677
    01678         lpUndetW->uYomiDelimPos = dwPos;
    01679
    01680         lpw  = (LPDWORD)((PBYTE)lpUndetW + dwPos);
    01681         lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset);
    01682         for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++)
    01683             *lpw++ = *lpdw++;
    01684
    01685         dwPos += DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen + 1));
    01686     }
    01687
    01688     return dwSize;
    01689 }
    01690
    01691 DWORD
    01692 CompStrWToUndetA(
    01693     DWORD dwGCS,
    01694     LPCOMPOSITIONSTRING lpCompStrW,
    01695     LPUNDETERMINESTRUCT lpUndetA
    01696     )
    01697
    01698 /*++
    01699
    01700 Routine Description:
    01701
    01702     Convert composition string (Unicode) to undetermine string (ANSI).
    01703
    01704 Arguments:
    01705
    01706 Return Value:
    01707
    01708 --*/
    01709
    01710 {
    01711     DWORD dwPos;
    01712     DWORD dwSize;
    01713     UINT  i;
    01714     BOOL bUDC;
    01715
    01716     dwSize = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT)+1)) +
    01717              DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) +
    01718              DWORD_ALIGN((lpCompStrW->dwResultClauseLen+1)) +
    01719              DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) +
    01720              DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen+1)) +
    01721              DWORD_ALIGN((lpCompStrW->dwCompAttrLen * 2)) +
    01722              DWORD_ALIGN(((lpCompStrW->dwCompStrLen+1) * sizeof(WCHAR)));
    01723
    01724     if (lpUndetA == NULL) {
    01725         return dwSize;
    01726     }
    01727
    01728     dwPos = DWORD_ALIGN((sizeof(UNDETERMINESTRUCT) + 1));
    01729     lpUndetA->dwSize = dwSize;
    01730
    01731     if (dwGCS & GCS_COMPSTR)
    01732     {
    01733         i = WideCharToMultiByte( CP_ACP,
    01734                                 (DWORD)0,
    01735                                 (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset),  // src
    01736                                 (INT)lpCompStrW->dwCompStrLen,
    01737                                 (LPSTR)((PBYTE)lpUndetA + dwPos),                           // dest
    01738                                 (INT)dwSize - dwPos,
    01739                                 (LPSTR)NULL,
    01740                                 (LPBOOL)&bUDC);
    01741         ((LPSTR)((PBYTE)lpUndetA + dwPos))[i] = '\0';
    01742         lpUndetA->uUndetTextLen = i;
    01743         lpUndetA->uUndetTextPos = dwPos;
    01744         dwPos += DWORD_ALIGN(((lpUndetA->uUndetTextLen + 1)*sizeof(CHAR)));
    01745
    01746         // Sometime Chicago IME does not generate GCS_COMPATTR
    01747         // with GCS_COMPSTR. But uUndetAttrPos should be filled
    01748         // when the UndetText is updated.
    01749         if (lpCompStrW->dwCompAttrLen && !(dwGCS & GCS_COMPATTR))
    01750             dwGCS |= GCS_COMPATTR;
    01751     }
    01752
    01753     if (dwGCS & GCS_COMPATTR)
    01754     {
    01755         if (lpUndetA->uUndetTextLen != 0) {
    01756             LPSTR  lpszUndetText;
    01757             PBYTE  lpAttrW;
    01758             PBYTE  lpAttrA;
    01759             BYTE   c;
    01760
    01761             lpszUndetText  = (LPSTR)((PBYTE)lpUndetA + lpUndetA->uUndetTextPos);
    01762             lpAttrW = (PBYTE)lpCompStrW + lpCompStrW->dwCompAttrOffset;
    01763             lpAttrA = (PBYTE)lpUndetA   + dwPos;
    01764
    01765             while (c=*lpszUndetText++) {
    01766                 if (IsDBCSLeadByte(c)) {
    01767                     *lpAttrA++ = *lpAttrW;
    01768                     *lpAttrA++ = *lpAttrW;
    01769                     lpszUndetText++;
    01770                 }
    01771                 else {
    01772                     *lpAttrA++ = *lpAttrW;
    01773                 }
    01774                 lpAttrW++;
    01775             }
    01776
    01777             lpUndetA->uUndetAttrPos = dwPos;
    01778             dwPos += DWORD_ALIGN((lpUndetA->uUndetTextLen + 1));
    01779         }
    01780     }
    01781
    01782     if (dwGCS & GCS_CURSORPOS)
    01783     {
    01784         if (lpCompStrW->dwCursorPos != -1) {
    01785             lpUndetA->uCursorPos = CalcCharacterPositionWtoA(lpCompStrW->dwCursorPos,
    01786                                                              (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset),
    01787                                                              CP_ACP
    01788                                                             );
    01789         }
    01790         else {
    01791             lpUndetA->uCursorPos = lpCompStrW->dwCursorPos;
    01792         }
    01793     }
    01794
    01795     if (dwGCS & GCS_DELTASTART)
    01796     {
    01797         if (lpCompStrW->dwDeltaStart != -1) {
    01798             lpUndetA->uDeltaStart = CalcCharacterPositionWtoA(lpCompStrW->dwDeltaStart,
    01799                                                               (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwCompStrOffset),
    01800                                                               CP_ACP
    01801                                                              );
    01802         }
    01803         else {
    01804             lpUndetA->uDeltaStart = lpCompStrW->dwDeltaStart;
    01805         }
    01806     }
    01807
    01808     if (dwGCS & GCS_RESULTSTR)
    01809     {
    01810         i = WideCharToMultiByte( CP_ACP,
    01811                                 (DWORD)0,
    01812                                 (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset),  // src
    01813                                 (INT)lpCompStrW->dwResultStrLen,
    01814                                 (LPSTR)((PBYTE)lpUndetA + dwPos),                             // dest
    01815                                 (INT)dwSize - dwPos,
    01816                                 (LPSTR)NULL,
    01817                                 (LPBOOL)&bUDC);
    01818         ((LPSTR)((PBYTE)lpUndetA + dwPos))[i] = '\0';
    01819         lpUndetA->uDetermineTextLen = i;
    01820         lpUndetA->uDetermineTextPos = dwPos;
    01821         dwPos += DWORD_ALIGN(((lpUndetA->uDetermineTextLen + 1)*sizeof(CHAR)));
    01822     }
    01823
    01824     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    01825          (lpCompStrW->dwResultClauseLen > 0) )
    01826     {
    01827         if (lpUndetA->uDetermineTextLen != 0) {
    01828             LPDWORD lpw;
    01829             LPDWORD lpdw;
    01830
    01831             lpw  = (LPDWORD)((PBYTE)lpUndetA + dwPos);
    01832             lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset);
    01833
    01834             for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++) {
    01835                 *lpw++ = CalcCharacterPositionWtoA(*lpdw++,
    01836                                                    (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset),
    01837                                                    CP_ACP
    01838                                                   );
    01839             }
    01840
    01841             lpUndetA->uDetermineDelimPos = dwPos;
    01842             dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1));
    01843         }
    01844     }
    01845
    01846     if (dwGCS & GCS_RESULTREADSTR)
    01847     {
    01848         i = WideCharToMultiByte( CP_ACP,
    01849                                 (DWORD)0,
    01850                                 (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset),  // src
    01851                                 (INT)lpCompStrW->dwResultReadStrLen,
    01852                                 (LPSTR)((PBYTE)lpUndetA + dwPos),                                 // dest
    01853                                 (INT)dwSize - dwPos,
    01854                                 (LPSTR)NULL,
    01855                                 (LPBOOL)&bUDC);
    01856         ((LPSTR)((PBYTE)lpUndetA + dwPos))[i] = '\0';
    01857         lpUndetA->uYomiTextLen = i;
    01858         lpUndetA->uYomiTextPos = dwPos;
    01859         dwPos += DWORD_ALIGN(((lpUndetA->uYomiTextLen + 1)*sizeof(CHAR)));
    01860     }
    01861
    01862     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    01863          (lpCompStrW->dwResultReadClauseLen > 0) )
    01864     {
    01865         if (lpUndetA->uYomiTextLen != 0) {
    01866             LPDWORD lpw;
    01867             LPDWORD lpdw;
    01868
    01869             lpw  = (LPDWORD)((PBYTE)lpUndetA + dwPos);
    01870             lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset);
    01871
    01872             for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++) {
    01873                 *lpw++ = CalcCharacterPositionWtoA(*lpdw++,
    01874                                                    (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset),
    01875                                                    CP_ACP
    01876                                                   );
    01877             }
    01878
    01879             lpUndetA->uYomiDelimPos = dwPos;
    01880             dwPos += DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen + 1));
    01881         }
    01882     }
    01883
    01884     return dwSize;
    01885 }
    01886
    01887
    01888 DWORD
    01889 CompStrWToStringExW(
    01890     DWORD dwGCS,
    01891     LPCOMPOSITIONSTRING lpCompStrW,
    01892     LPSTRINGEXSTRUCT lpStringExW
    01893     )
    01894
    01895 /*++
    01896
    01897 Routine Description:
    01898
    01899     Convert composition string (Unicode) to StringEx (Unicode).
    01900
    01901 Arguments:
    01902
    01903 Return Value:
    01904
    01905 --*/
    01906
    01907 {
    01908     DWORD dwPos;
    01909     DWORD dwSize;
    01910     UINT  i;
    01911
    01912     dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) +
    01913              DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) +
    01914              DWORD_ALIGN(lpCompStrW->dwResultClauseLen+1) +
    01915              DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) +
    01916              DWORD_ALIGN(lpCompStrW->dwResultReadClauseLen+1);
    01917
    01918     if (lpStringExW == NULL) {
    01919         return dwSize;
    01920     }
    01921
    01922     dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1);
    01923     lpStringExW->dwSize = dwSize;
    01924
    01925     lpStringExW->uDeterminePos = dwPos;
    01926     memcpy((PBYTE)lpStringExW + dwPos,
    01927            (PBYTE)lpCompStrW  + lpCompStrW->dwResultStrOffset,
    01928            lpCompStrW->dwResultStrLen * sizeof(WCHAR)
    01929           );
    01930     *(LPWSTR)((PBYTE)lpStringExW + dwPos + lpCompStrW->dwResultStrLen*sizeof(WCHAR)) = L'\0';
    01931     dwPos += DWORD_ALIGN(((lpCompStrW->dwResultStrLen + 1)*sizeof(WCHAR)));
    01932
    01933     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    01934          (lpCompStrW->dwResultClauseLen > 0) )
    01935     {
    01936         LPDWORD lpw;
    01937         LPDWORD lpdw;
    01938
    01939         lpStringExW->uDetermineDelimPos = dwPos;
    01940
    01941         lpw  = (LPDWORD)((PBYTE)lpStringExW + dwPos);
    01942         lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset);
    01943         for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++)
    01944             *lpw++ = *lpdw++;
    01945
    01946         dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1));
    01947     }
    01948
    01949     lpStringExW->uYomiPos = dwPos;
    01950     memcpy((PBYTE)lpStringExW + dwPos,
    01951            (PBYTE)lpCompStrW  + lpCompStrW->dwResultReadStrOffset,
    01952            lpCompStrW->dwResultReadStrLen * sizeof(WCHAR)
    01953           );
    01954     *(LPWSTR)((PBYTE)lpStringExW + dwPos + lpCompStrW->dwResultReadStrLen*sizeof(WCHAR)) = L'\0';
    01955     dwPos += DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen + 1)*sizeof(WCHAR)));
    01956
    01957     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    01958          (lpCompStrW->dwResultReadClauseLen > 0) )
    01959     {
    01960         LPDWORD lpw;
    01961         LPDWORD lpdw;
    01962
    01963         lpStringExW->uYomiDelimPos = dwPos;
    01964
    01965         lpw  = (LPDWORD)((PBYTE)lpStringExW + dwPos);
    01966         lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset);
    01967         for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++)
    01968             *lpw++ = *lpdw++;
    01969     }
    01970
    01971     return dwSize;
    01972 }
    01973
    01974 DWORD
    01975 CompStrWToStringExA(
    01976     DWORD dwGCS,
    01977     LPCOMPOSITIONSTRING lpCompStrW,
    01978     LPSTRINGEXSTRUCT lpStringExA
    01979     )
    01980
    01981 /*++
    01982
    01983 Routine Description:
    01984
    01985     Convert composition string (Unicode) to StringEx (ANSI).
    01986
    01987 Arguments:
    01988
    01989 Return Value:
    01990
    01991 --*/
    01992
    01993 {
    01994     DWORD dwPos;
    01995     DWORD dwSize;
    01996     DWORD dwLen;
    01997     UINT  i;
    01998     BOOL bUDC;
    01999
    02000     dwSize = DWORD_ALIGN((sizeof(STRINGEXSTRUCT)+1)) +
    02001              (lpCompStrW->dwResultStrLen > 0 ? DWORD_ALIGN(((lpCompStrW->dwResultStrLen+1) * sizeof(WCHAR))) : 0) +
    02002              (lpCompStrW->dwResultClauseLen > 0 ? DWORD_ALIGN(lpCompStrW->dwResultClauseLen+1) : 0) +
    02003              (lpCompStrW->dwResultReadStrLen > 0 ? DWORD_ALIGN(((lpCompStrW->dwResultReadStrLen+1) * sizeof(WCHAR))) : 0)+
    02004              (lpCompStrW->dwResultReadClauseLen > 0 ? DWORD_ALIGN(lpCompStrW->dwResultReadClauseLen+1) : 0);
    02005
    02006     if (lpStringExA == NULL) {
    02007         return dwSize;
    02008     }
    02009
    02010     dwPos = DWORD_ALIGN(sizeof(STRINGEXSTRUCT) + 1);
    02011     lpStringExA->dwSize = dwSize;
    02012
    02013     if (lpCompStrW->dwResultStrLen > 0) {
    02014         i = WideCharToMultiByte( CP_ACP,
    02015                                 (DWORD)0,
    02016                                 (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset),  // src
    02017                                 (INT)lpCompStrW->dwResultStrLen,
    02018                                 (LPSTR)((PBYTE)lpStringExA + dwPos),                          // dest
    02019                                 (INT)dwSize - dwPos,
    02020                                 (LPSTR)NULL,
    02021                                 (LPBOOL)&bUDC);
    02022         ((LPSTR)((PBYTE)lpStringExA + dwPos))[i] = '\0';
    02023         dwLen = i;
    02024         lpStringExA->uDeterminePos = dwPos;
    02025         dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(CHAR)));
    02026     } else {
    02027         dwLen = 0;
    02028         lpStringExA->uDeterminePos = 0;
    02029     }
    02030
    02031     if ( (dwGCS & GCS_RESULTCLAUSE) &&
    02032          (lpCompStrW->dwResultClauseLen > 0) )
    02033     {
    02034         if (dwLen != 0 && lpCompStrW->dwResultClauseLen > 0) {
    02035             LPDWORD lpw;
    02036             LPDWORD lpdw;
    02037
    02038             lpw  = (LPDWORD)((PBYTE)lpStringExA + dwPos);
    02039             lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultClauseOffset);
    02040
    02041             for (i = 0; i < (lpCompStrW->dwResultClauseLen / sizeof(DWORD)); i++) {
    02042                 *lpw++ = CalcCharacterPositionWtoA(*lpdw++,
    02043                                                    (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset),
    02044                                                    CP_ACP
    02045                                                   );
    02046             }
    02047
    02048             lpStringExA->uDetermineDelimPos = dwPos;
    02049             dwPos += DWORD_ALIGN((lpCompStrW->dwResultClauseLen + 1));
    02050         }
    02051     }
    02052
    02053     if (lpCompStrW->dwResultReadStrLen > 0) {
    02054         i = WideCharToMultiByte( CP_ACP,
    02055                                 (DWORD)0,
    02056                                 (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset),  // src
    02057                                 (INT)lpCompStrW->dwResultReadStrLen,
    02058                                 (LPSTR)((PBYTE)lpStringExA + dwPos),                              // dest
    02059                                 (INT)dwSize - dwPos,
    02060                                 (LPSTR)NULL,
    02061                                 (LPBOOL)&bUDC);
    02062         ((LPSTR)((PBYTE)lpStringExA + dwPos))[i] = '\0';
    02063         dwLen = i;
    02064         lpStringExA->uYomiPos = dwPos;
    02065         dwPos += DWORD_ALIGN(((dwLen + 1)*sizeof(CHAR)));
    02066     } else {
    02067         dwLen = 0;
    02068         lpStringExA->uYomiPos = 0;
    02069     }
    02070
    02071     if ( (dwGCS & GCS_RESULTREADCLAUSE) &&
    02072          (lpCompStrW->dwResultReadClauseLen > 0) )
    02073     {
    02074         if (dwLen != 0 && lpCompStrW->dwResultReadClauseLen > 0) {
    02075             LPDWORD lpw;
    02076             LPDWORD lpdw;
    02077
    02078             lpw  = (LPDWORD)((PBYTE)lpStringExA + dwPos);
    02079             lpdw = (LPDWORD)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadClauseOffset);
    02080
    02081             for (i = 0; i < (lpCompStrW->dwResultReadClauseLen / sizeof(DWORD)); i++) {
    02082                 *lpw++ = CalcCharacterPositionWtoA(*lpdw++,
    02083                                                    (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultReadStrOffset),
    02084                                                    CP_ACP
    02085                                                   );
    02086             }
    02087
    02088             lpStringExA->uYomiDelimPos = dwPos;
    02089             dwPos += DWORD_ALIGN((lpCompStrW->dwResultReadClauseLen + 1));
    02090         }
    02091     }
    02092
    02093     return dwSize;
    02094 }
    02095
    02096 DWORD
    02097 CompStrWToStringW(
    02098     LPCOMPOSITIONSTRING lpCompStrW,
    02099     LPWSTR lpStringW
    02100     )
    02101
    02102 /*++
    02103
    02104 Routine Description:
    02105
    02106     Convert composition string (Unicode) to String (Unicode).
    02107
    02108 Arguments:
    02109
    02110 Return Value:
    02111
    02112 --*/
    02113
    02114 {
    02115     LPWSTR lpwszString;
    02116     DWORD dwSize;
    02117
    02118     lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
    02119     dwSize = lpCompStrW->dwResultStrLen;
    02120
    02121     if (lpStringW == NULL) {
    02122         return ((dwSize + 1) * sizeof(WCHAR));
    02123     }
    02124
    02125     memcpy((PBYTE)lpStringW,
    02126            (PBYTE)lpwszString,
    02127            (dwSize * sizeof(WCHAR))
    02128           );
    02129     lpStringW[dwSize] = L'\0';
    02130
    02131     return ((dwSize + 1) * sizeof(WCHAR));
    02132 }
    02133
    02134 DWORD
    02135 CompStrWToStringA(
    02136     LPCOMPOSITIONSTRING lpCompStrW,
    02137     LPSTR lpStringA
    02138     )
    02139
    02140 /*++
    02141
    02142 Routine Description:
    02143
    02144     Convert composition string (Unicode) to String (ANSI).
    02145
    02146 Arguments:
    02147
    02148 Return Value:
    02149
    02150 --*/
    02151
    02152 {
    02153     LPWSTR lpwszString;
    02154     DWORD dwSize;
    02155     UINT  i;
    02156     BOOL bUDC;
    02157
    02158     lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
    02159
    02160     i = WideCharToMultiByte( CP_ACP,
    02161                             (DWORD)0,
    02162                             (LPWSTR)lpwszString,                             // src
    02163                             (INT)lpCompStrW->dwResultStrLen,
    02164                             (LPSTR)lpStringA,                                // dest
    02165                             (INT)0,
    02166                             (LPSTR)NULL,
    02167                             (LPBOOL)&bUDC);
    02168
    02169     if (lpStringA == NULL) {
    02170         dwSize = (i+1) * sizeof(CHAR);
    02171     }
    02172     else {
    02173         dwSize = (i+1) * sizeof(CHAR);
    02174
    02175         i = WideCharToMultiByte( CP_ACP,
    02176                                 (DWORD)0,
    02177                                 (LPWSTR)lpwszString,                             // src
    02178                                 (INT)lpCompStrW->dwResultStrLen,
    02179                                 (LPSTR)lpStringA,                                // dest
    02180                                 (INT)dwSize,
    02181                                 (LPSTR)NULL,
    02182                                 (LPBOOL)&bUDC);
    02183
    02184         lpStringA[i] = '\0';
    02185         dwSize = (i+1) * sizeof(CHAR);
    02186     }
    02187
    02188     return dwSize;
    02189 }
    02190
    02191 VOID
    02192 CompStrWToCharW(
    02193     HWND hWnd,
    02194     LPCOMPOSITIONSTRING lpCompStrW
    02195     )
    02196
    02197 /*++
    02198
    02199 Routine Description:
    02200
    02201     Convert composition string (Unicode) to WM_CHAR (Unicode).
    02202
    02203 Arguments:
    02204
    02205 Return Value:
    02206
    02207 --*/
    02208
    02209 {
    02210     LPWSTR lpwszString;
    02211
    02212     lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
    02213
    02214     // IR_DBCSCHAR: If the app reply to this message with TRUE, we can
    02215     // queue up double byte character in a WM_CHAR message.
    02216     // SendMessageW( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L);
    02217
    02218     // Send IR_STRINGSTART prior to anything.
    02219     PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
    02220
    02221
    02222     while(*lpwszString)
    02223     {
    02224         if( *CharNextW(lpwszString) == 0 )
    02225         {
    02226             PostMessageW( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L );
    02227         }
    02228         PostMessageW( hWnd, WM_CHAR, *lpwszString, 1L);
    02229         lpwszString = CharNextW(lpwszString);
    02230     }
    02231 }
    02232
    02233 VOID
    02234 CompStrWToCharA(
    02235     HWND hWnd,
    02236     LPCOMPOSITIONSTRING lpCompStrW
    02237     )
    02238
    02239 /*++
    02240
    02241 Routine Description:
    02242
    02243     Convert composition string (Unicode) to WM_CHAR (ANSI).
    02244
    02245 Arguments:
    02246
    02247 Return Value:
    02248
    02249 --*/
    02250
    02251 {
    02252     LPWSTR lpwszString;
    02253     BOOL   fDBCSWmChar = FALSE;
    02254     WORD   wDBCSChar;
    02255     UINT   i;
    02256     BOOL   bUDC;
    02257     BYTE   szAscii[3];
    02258
    02259     lpwszString = (LPWSTR)((PBYTE)lpCompStrW + lpCompStrW->dwResultStrOffset);
    02260
    02261     //
    02262     // IR_DBCSCHAR: If the app reply to this message with TRUE, we can
    02263     // queue up double byte character in a WM_CHAR message.
    02264     //
    02265     //
    02266
    02267     if ( GetClientInfo()->dwExpWinVer >= 0x030A ) {
    02268        fDBCSWmChar = (BOOL)SendMessageA( hWnd,WM_IME_REPORT,IR_DBCSCHAR, 0L);
    02269     }
    02270
    02271     //
    02272     // Send IR_STRINGSTART prior to anything.
    02273     //
    02274
    02275     PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGSTART, 0L );
    02276
    02277
    02278     while (*lpwszString) {
    02279
    02280        if ( *CharNextW(lpwszString) == 0 ) {
    02281            PostMessageA( hWnd, WM_IME_REPORT, IR_STRINGEND, 0L );
    02282        }
    02283
    02284        i = WideCharToMultiByte( CP_ACP,
    02285                                 (DWORD)0,
    02286                                 (LPWSTR)lpwszString,  // src
    02287                                 (INT)1,
    02288                                 (LPSTR)szAscii,       // dest
    02289                                 (INT)sizeof(szAscii),
    02290                                 (LPSTR)NULL,
    02291                                 (LPBOOL)&bUDC);
    02292
    02293         if (i != 0) {
    02294
    02295             if ( IsDBCSLeadByte( szAscii[0] ) ) {
    02296
    02297                //
    02298                //  If fDBCSWmChar==TRUE, The app can recieve WM_CHARs which
    02299                // have double byte code in wParam.
    02300                //
    02301
    02302                if ( fDBCSWmChar )
    02303                {
    02304                    //
    02305                    // It's necessary to swap bytes to put 1st byte into upper
    02306                    // part of wParam, and 2nd byte into lower part.
    02307                    //
    02308
    02309                    wDBCSChar = MAKEWORD(szAscii[1], szAscii[0]);
    02310                    PostMessageA( hWnd, WM_CHAR, wDBCSChar|WMCR_IR_DBCSCHAR, 1L );
    02311                }
    02312                else
    02313                {
    02314                    //
    02315                    // Send each byte on a WM_CHAR
    02316                    //
    02317
    02318                    PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L);
    02319                    PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[1]), 1L);
    02320                }
    02321            }
    02322            else
    02323            {
    02324                PostMessageA( hWnd, WM_CHAR, (WPARAM)(szAscii[0]), 1L);
    02325            }
    02326        }
    02327
    02328        lpwszString = CharNextW(lpwszString);
    02329    }
    02330
    02331 }