00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
#include "precomp.h"
00013 
#pragma hdrstop
00014 
00015 typedef struct tagSELECTCONTEXT_ENUM {
00016     HKL 
hSelKL;
00017     HKL 
hUnSelKL;
00018 } 
SCE, *
PSCE;
00019 
00020 
00021 BOOL NotifyIMEProc(
00022     HIMC hImc,
00023     LPARAM lParam)
00024 {
00025     UserAssert(lParam == CPS_COMPLETE || lParam == CPS_CANCEL);
00026     
ImmNotifyIME(hImc, NI_COMPOSITIONSTR, (
DWORD)lParam, 0);
00027     
return TRUE;
00028 }
00029 
00030 
00031 BOOL SelectContextProc(
00032     HIMC hImc,
00033     PSCE psce)
00034 {
00035     
SelectInputContext(psce->
hSelKL, psce->
hUnSelKL, hImc);
00036     
return TRUE;
00037 }
00038 
00039 
00040 BOOL InquireIme(
00041     
PIMEDPI pImeDpi)
00042 {
00043     WNDCLASS    wc;
00044     
BYTE        ClassName[
IM_UI_CLASS_SIZE * 
sizeof(WCHAR)];
00045     
DWORD       dwSystemInfoFlags;
00046     PIMEINFO    pImeInfo = &pImeDpi->
ImeInfo;
00047 
00048     dwSystemInfoFlags = (
NtUserGetThreadState(UserThreadStateIsWinlogonThread))
00049                       ? IME_SYSINFO_WINLOGON : 0;
00050 
00051     
if (
GetClientInfo()->dwTIFlags & 
TIF_16BIT)
00052         dwSystemInfoFlags |= IME_SYSINFO_WOW16;
00053 
00054     (*pImeDpi->
pfn.
ImeInquire.w)(pImeInfo, (PVOID)ClassName, dwSystemInfoFlags);
00055 
00056     
00057 
00058 
00059     
if (pImeInfo->dwPrivateDataSize == 0)
00060         pImeInfo->dwPrivateDataSize = 
sizeof(
UINT);
00061 
00062     
if (pImeInfo->fdwProperty & ~(IME_PROP_ALL)) {
00063         RIPMSG0(RIP_WARNING, 
"wrong property");
00064         
return FALSE;
00065     }
00066 
00067     
if (pImeInfo->fdwConversionCaps & ~(IME_CMODE_ALL)) {
00068         RIPMSG0(RIP_WARNING, 
"wrong conversion capabilities");
00069         
return FALSE;
00070     }
00071 
00072     
if (pImeInfo->fdwSentenceCaps & ~(IME_SMODE_ALL)) {
00073         RIPMSG0(RIP_WARNING, 
"wrong sentence capabilities");
00074         
return FALSE;
00075     }
00076 
00077     
if (pImeInfo->fdwUICaps & ~(UI_CAP_ALL)) {
00078         RIPMSG0(RIP_WARNING, 
"wrong UI capabilities");
00079         
return FALSE;
00080     }
00081 
00082     
if (pImeInfo->fdwSCSCaps & ~(SCS_CAP_ALL)) {
00083         RIPMSG0(RIP_WARNING, 
"wrong set comp string capabilities");
00084         
return FALSE;
00085     }
00086 
00087     
if (pImeInfo->fdwSelectCaps & ~(SELECT_CAP_ALL)) {
00088         RIPMSG0(RIP_WARNING, 
"wrong select capabilities");
00089         
return FALSE;
00090     }
00091 
00092     
if (!(pImeInfo->fdwProperty & IME_PROP_UNICODE)) {
00093 
00094         
00095 
00096 
00097 
00098         
if (pImeDpi->
dwCodePage != GetACP() && pImeDpi->
dwCodePage != CP_ACP) {
00099             
00100             
00101             RIPMSG1(RIP_WARNING, 
"incompatible codepage(%d) for ANSI IME", pImeDpi->
dwCodePage);
00102             
return FALSE;
00103         }
00104 
00105         
00106 
00107 
00108         MultiByteToWideChar(
IMECodePage(pImeDpi),
00109                             (
DWORD)MB_PRECOMPOSED,
00110                             (LPSTR)ClassName,               
00111                             (
INT)-1,
00112                             pImeDpi->
wszUIClass,            
00113                             
IM_UI_CLASS_SIZE);
00114     } 
else {
00115         RtlCopyMemory(pImeDpi->
wszUIClass, ClassName, 
sizeof(ClassName));
00116     }
00117     pImeDpi->
wszUIClass[
IM_UI_CLASS_SIZE-1] = 
L'\0';
00118 
00119     
if (!GetClassInfoW((HINSTANCE)pImeDpi->
hInst, pImeDpi->
wszUIClass, &wc)) {
00120         RIPMSG1(RIP_WARNING, 
"UI class (%ws) not found in this IME", pImeDpi->
wszUIClass);
00121         
return FALSE;
00122     } 
else if (wc.cbWndExtra < 
sizeof(
DWORD) * 2) {
00123         RIPMSG0(RIP_WARNING, 
"UI class cbWndExtra problem");
00124         
return FALSE;
00125     }
00126 
00127     
return TRUE;
00128 }
00129 
00130 
00131 BOOL LoadIME(
00132     
PIMEINFOEX piiex,
00133     
PIMEDPI    pImeDpi)
00134 {
00135     WCHAR wszImeFile[
MAX_PATH];
00136     
BOOL  fSuccess;
00137 
00138     
GetSystemPathName(wszImeFile, piiex->
wszImeFile, 
MAX_PATH);
00139 
00140     pImeDpi->
hInst = LoadLibraryW(wszImeFile);
00141 
00142     
if (!pImeDpi->
hInst) {
00143         RIPMSG1(RIP_WARNING, 
"LoadIME: LoadLibraryW(%ws) failed", wszImeFile);
00144         
goto LoadIME_ErrOut;
00145     }
00146 
00147 
#define GET_IMEPROCT(x) \
00148 
    if (!(pImeDpi->pfn.##x.t = (PVOID) GetProcAddress(pImeDpi->hInst, #x))) { \
00149 
        RIPMSG1(RIP_WARNING, "LoadIME: " #x " not supported in %ws", wszImeFile);           \
00150 
        goto LoadIME_ErrOut; }
00151 
00152 
#define GET_IMEPROC(x) \
00153 
    if (!(pImeDpi->pfn.##x = (PVOID) GetProcAddress(pImeDpi->hInst, #x))) {   \
00154 
        RIPMSG1(RIP_WARNING, "LoadIME: " #x " not supported in %ws", wszImeFile);           \
00155 
        goto LoadIME_ErrOut; }
00156 
00157     
GET_IMEPROCT(ImeInquire);
00158     
GET_IMEPROCT(ImeConversionList);
00159     
GET_IMEPROCT(ImeRegisterWord);
00160     
GET_IMEPROCT(ImeUnregisterWord);
00161     
GET_IMEPROCT(ImeGetRegisterWordStyle);
00162     
GET_IMEPROCT(ImeEnumRegisterWord);
00163     
GET_IMEPROC (ImeConfigure);
00164     
GET_IMEPROC (ImeDestroy);
00165     
GET_IMEPROC (ImeEscape);
00166     
GET_IMEPROC (ImeProcessKey);
00167     
GET_IMEPROC (ImeSelect);
00168     
GET_IMEPROC (ImeSetActiveContext);
00169     
GET_IMEPROC (ImeToAsciiEx);
00170     
GET_IMEPROC (NotifyIME);
00171     
GET_IMEPROC (ImeSetCompositionString);
00172 
00173     
00174     pImeDpi->
pfn.
ImeGetImeMenuItems = (PVOID)GetProcAddress(pImeDpi->
hInst, 
"ImeGetImeMenuItems");
00175 
00176 
#undef GET_IMEPROCT
00177 
#undef GET_IMEPROC
00178 
00179     
if (!
InquireIme(pImeDpi)) {
00180         RIPMSG0(RIP_WARNING, 
"LoadIME: InquireIme failed");
00181 LoadIME_ErrOut:
00182         FreeLibrary(pImeDpi->
hInst);
00183         pImeDpi->
hInst = 
NULL;
00184         fSuccess = 
FALSE;
00185     }
00186     
else {
00187         fSuccess = 
TRUE;
00188     }
00189 
00190     
00191 
00192 
00193 
00194     
if (piiex->
fLoadFlag == 
IMEF_NONLOAD) {
00195         
if (fSuccess) {
00196             RtlCopyMemory((
PBYTE)&piiex->
ImeInfo,
00197                           (
PBYTE)&pImeDpi->
ImeInfo, 
sizeof(IMEINFO));
00198             RtlCopyMemory((
PBYTE)piiex->
wszUIClass,
00199                           (
PBYTE)pImeDpi->
wszUIClass, 
sizeof(pImeDpi->
wszUIClass));
00200             piiex->
fLoadFlag = 
IMEF_LOADED;
00201         }
00202         
else {
00203             piiex->
fLoadFlag = 
IMEF_LOADERROR;
00204         }
00205         
NtUserSetImeInfoEx(piiex);
00206     }
00207 
00208     
return fSuccess;
00209 }
00210 
00211 
00212 VOID UnloadIME(
00213     
PIMEDPI pImeDpi,
00214     BOOL    fTerminateIme)
00215 {
00216     
if (pImeDpi->
hInst == 
NULL) {
00217         RIPMSG0(RIP_WARNING, 
"UnloadIME: No IME's hInst.");
00218         
return;
00219     }
00220 
00221     
if (fTerminateIme) {
00222         
00223 
00224 
00225         (*pImeDpi->
pfn.
ImeDestroy)(0);
00226     }
00227 
00228     FreeLibrary(pImeDpi->
hInst);
00229     pImeDpi->
hInst = 
NULL;
00230 
00231     
return;
00232 }
00233 
00234 PIMEDPI LoadImeDpi(
00235     HKL  hKL,
00236     BOOL fLock)
00237 {
00238     
PIMEDPI        pImeDpi, pImeDpiT;
00239     
IMEINFOEX      iiex;
00240 
00241     
00242 
00243 
00244     
if (!
ImmGetImeInfoEx(&iiex, 
ImeInfoExKeyboardLayout, &hKL)) {
00245         RIPMSG1(RIP_WARNING, 
"LoadImeDpi: ImmGetImeInfoEx(%lx) failed", hKL);
00246         
return NULL;
00247     }
00248 
00249     
00250 
00251 
00252 
00253     
if (iiex.
fLoadFlag == 
IMEF_LOADERROR)
00254         
return NULL;
00255 
00256     
00257 
00258 
00259     pImeDpi = (
PIMEDPI)
ImmLocalAlloc(HEAP_ZERO_MEMORY, 
sizeof(
IMEDPI));
00260     
if (pImeDpi == 
NULL)
00261         
return NULL;
00262 
00263     pImeDpi->
hKL = hKL;
00264 
00265     
00266     {
00267         CHARSETINFO cs;
00268         
if (TranslateCharsetInfo((
DWORD*)LOWORD(HandleToUlong(hKL)), &cs, TCI_SRCLOCALE)) {
00269             pImeDpi->
dwCodePage = cs.ciACP;
00270         }
00271         
else {
00272             pImeDpi->
dwCodePage = CP_ACP;
00273         }
00274     }
00275 
00276     
00277 
00278 
00279     
if (!
LoadIME(&iiex, pImeDpi)) {
00280         
ImmLocalFree(pImeDpi);
00281         
return NULL;
00282     }
00283 
00284     
00285 
00286 
00287     RtlEnterCriticalSection(&
gcsImeDpi);
00288 
00289     pImeDpiT = 
ImmGetImeDpi(hKL);
00290 
00291     
if (pImeDpiT == 
NULL) {
00292         
if (fLock) {
00293             
00294 
00295 
00296             pImeDpi->
cLock = 1;
00297             pImeDpi->
dwFlag |= 
IMEDPI_UNLOCKUNLOAD;
00298         }
00299 
00300         
00301 
00302 
00303         pImeDpi->
pNext = 
gpImeDpi;
00304         
gpImeDpi = pImeDpi;
00305 
00306         RtlLeaveCriticalSection(&
gcsImeDpi);
00307     }
00308     
else {
00309 
00310         
if (!fLock) {
00311             pImeDpiT->
dwFlag &= ~
IMEDPI_UNLOCKUNLOAD;
00312         }
00313 
00314         
00315 
00316 
00317         RtlLeaveCriticalSection(&
gcsImeDpi);
00318         
UnloadIME(pImeDpi, 
FALSE);
00319         
ImmLocalFree(pImeDpi);
00320         pImeDpi = pImeDpiT;
00321     }
00322 
00323     
return pImeDpi;
00324 }
00325 
00326 
00327 PIMEDPI FindOrLoadImeDpi(
00328     HKL  hKL)
00329 {
00330     
PIMEDPI pImeDpi;
00331 
00332     
00333 
00334 
00335     
if (!
IS_IME_KBDLAYOUT(hKL))
00336         
return (
PIMEDPI)
NULL;
00337 
00338     pImeDpi = 
ImmLockImeDpi(hKL);
00339     
if (pImeDpi == 
NULL)
00340         pImeDpi = 
LoadImeDpi(hKL, 
TRUE);
00341 
00342     
return pImeDpi;
00343 }
00344 
00345 
00346 BOOL WINAPI 
ImmLoadIME(
00347     HKL hKL)
00348 {
00349     
PIMEDPI pImeDpi;
00350 
00351     
00352 
00353 
00354     
if (!
IS_IME_KBDLAYOUT(hKL))
00355         
return FALSE;
00356 
00357     pImeDpi = 
ImmGetImeDpi(hKL);
00358     
if (pImeDpi == 
NULL)
00359         pImeDpi = 
LoadImeDpi(hKL, 
FALSE);
00360 
00361     
return (pImeDpi != 
NULL);
00362 }
00363 
00364 
00365 BOOL WINAPI 
ImmUnloadIME(
00366     HKL hKL)
00367 {
00368     
PIMEDPI pImeDpi, pImeDpiT;
00369 
00370     RtlEnterCriticalSection(&
gcsImeDpi);
00371 
00372     pImeDpi = 
gpImeDpi;
00373 
00374     
while (pImeDpi != 
NULL && pImeDpi->
hKL != hKL)
00375         pImeDpi = pImeDpi->
pNext;
00376 
00377     
if (pImeDpi == 
NULL) {
00378         RtlLeaveCriticalSection(&
gcsImeDpi);
00379         
return TRUE;
00380     }
00381     
else if (pImeDpi->
cLock != 0) {
00382         pImeDpi->
dwFlag |= 
IMEDPI_UNLOADED;
00383         RtlLeaveCriticalSection(&
gcsImeDpi);
00384         
return FALSE;
00385     }
00386 
00387     
00388 
00389 
00390     
if (
gpImeDpi == pImeDpi) {
00391         
gpImeDpi = pImeDpi->
pNext;
00392     }
00393     
else {
00394         pImeDpiT = 
gpImeDpi;
00395 
00396         
while (pImeDpiT != 
NULL && pImeDpiT->
pNext != pImeDpi)
00397             pImeDpiT = pImeDpiT->
pNext;
00398 
00399         
if (pImeDpiT != 
NULL)
00400             pImeDpiT->
pNext = pImeDpi->
pNext;
00401     }
00402 
00403     
00404 
00405 
00406     
UnloadIME(pImeDpi, 
TRUE);
00407 
00408     
ImmLocalFree(pImeDpi);
00409 
00410     RtlLeaveCriticalSection(&
gcsImeDpi);
00411 
00412     
return TRUE;
00413 }
00414 
00415 
00416 BOOL WINAPI 
ImmFreeLayout(
00417     DWORD  dwFlag)
00418 {
00419     
PIMEDPI pImeDpi;
00420     HKL   *phklRoot, hklCurrent;
00421     WCHAR  pwszNonImeKLID[KL_NAMELENGTH];
00422     
UINT   nLayouts, uNonImeKLID = 0, i;
00423 
00424     hklCurrent = 
GetKeyboardLayout(0);
00425 
00426     
switch (dwFlag) {
00427 
00428     
case IFL_DEACTIVATEIME:
00429         
00430 
00431 
00432         
if (!
IS_IME_KBDLAYOUT(hklCurrent))
00433             
return TRUE;
00434 
00435         
00436 
00437 
00438 
00439         uNonImeKLID = (
UINT)LANGIDFROMLCID(GetSystemDefaultLCID());
00440 
00441         nLayouts = GetKeyboardLayoutList(0, 
NULL);
00442 
00443         
if (nLayouts != 0) {
00444             phklRoot = 
ImmLocalAlloc(0, nLayouts * 
sizeof(HKL));
00445             
if (phklRoot == 
NULL)
00446                 
return FALSE;
00447 
00448             nLayouts = GetKeyboardLayoutList(nLayouts, phklRoot);
00449 
00450             
for (i = 0; i < nLayouts && 
IS_IME_KBDLAYOUT(phklRoot[i]); i++) ;
00451 
00452             
if (i < nLayouts)
00453                 uNonImeKLID = HandleToUlong(phklRoot[i]) & 0xffff;
00454 
00455             
ImmLocalFree(phklRoot);
00456         }
00457 
00458         wsprintf(pwszNonImeKLID, 
L"%08x", uNonImeKLID);
00459 
00460         
if (
LoadKeyboardLayoutW(pwszNonImeKLID, KLF_ACTIVATE) == 
NULL) {
00461             RIPMSG1(RIP_WARNING, 
"ImmFreeLayout: LoadKeyboardLayoutW(%S, KLF_ACTIVATE) failed. Trying 00000409", pwszNonImeKLID);
00462             
00463             
00464             
if (
LoadKeyboardLayoutW(
L"00000409", KLF_ACTIVATE | KLF_FAILSAFE) == 
NULL) {
00465                 RIPMSG0(RIP_WARNING, 
"LoadKeyboardLayoutW(00000409) failed either. will try NULL.");
00466             }
00467         }
00468 
00469         
break;
00470 
00471     
case IFL_UNLOADIME:
00472         RtlEnterCriticalSection(&
gcsImeDpi);
00473 UnloadImeDpiLoop:
00474         
for (pImeDpi = 
gpImeDpi; pImeDpi != 
NULL; pImeDpi = pImeDpi->
pNext) {
00475             
if (
ImmUnloadIME(pImeDpi->
hKL))
00476                 
goto UnloadImeDpiLoop;        
00477         }
00478         RtlLeaveCriticalSection(&
gcsImeDpi);
00479         
break;
00480 
00481     
default:
00482         {
00483             HKL hklFlag = (HKL)LongToHandle( dwFlag );
00484             
if (
IS_IME_KBDLAYOUT(hklFlag) && hklFlag != hklCurrent) {
00485                 
ImmUnloadIME(hklFlag);
00486             }
00487         }
00488         
break;
00489     }
00490 
00491     
return TRUE;
00492 }
00493 
00494 
00495 BOOL WINAPI 
ImmActivateLayout(
00496     HKL    hSelKL)
00497 {
00498     HKL     hUnSelKL;
00499     HWND    hWndDefaultIme;
00500     
SCE     sce;
00501     
DWORD   dwCPS;
00502     
PIMEDPI pImeDpi;
00503     BOOLEAN fOptimizeActivation = 
TRUE;
00504 
00505     hUnSelKL = 
GetKeyboardLayout(0);
00506 
00507     {
00508         
PCLIENTINFO pClientInfo = 
GetClientInfo();
00509 
00510         
if (pClientInfo->
CI_flags & 
CI_INPUTCONTEXT_REINIT) {
00511             fOptimizeActivation = 
FALSE;
00512         }
00513     }
00514 
00515     
00516 
00517 
00518     
if (hUnSelKL == hSelKL && fOptimizeActivation)
00519         
return TRUE;
00520 
00521     
ImmLoadIME(hSelKL);
00522 
00523     
if (hUnSelKL != hSelKL) {
00524         pImeDpi = 
ImmLockImeDpi(hUnSelKL);
00525         
if (pImeDpi != 
NULL) {
00526             
00527 
00528 
00529 
00530 
00531 
00532             dwCPS = (pImeDpi->
ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT) ? CPS_COMPLETE : CPS_CANCEL;
00533             
ImmUnlockImeDpi(pImeDpi);
00534             
ImmEnumInputContext(0, 
NotifyIMEProc, dwCPS);
00535         }
00536 
00537         hWndDefaultIme = 
ImmGetDefaultIMEWnd(
NULL);
00538 
00539         
if (
IsWindow(hWndDefaultIme))
00540             
SendMessage(hWndDefaultIme, WM_IME_SELECT, 
FALSE, (LPARAM)hUnSelKL);
00541 
00542         
00543 
00544 
00545 
00546         
NtUserSetThreadLayoutHandles(hSelKL, hUnSelKL);
00547     }
00548 
00549     
00550 
00551 
00552     sce.
hSelKL   = hSelKL;
00553     sce.
hUnSelKL = hUnSelKL;
00554     
ImmEnumInputContext(0, (IMCENUMPROC)
SelectContextProc, (LPARAM)&sce);
00555 
00556     
00557 
00558 
00559     
if (
IsWindow(hWndDefaultIme))
00560         
SendMessage(hWndDefaultIme, WM_IME_SELECT, 
TRUE, (LPARAM)hSelKL);
00561 
00562     
return (
TRUE);
00563 }
00564 
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 
00573 
00574 
00575 BOOL WINAPI 
ImmConfigureIMEA(
00576     HKL    hKL,
00577     HWND   hWnd,
00578     DWORD  dwMode,
00579     LPVOID lpData)
00580 {
00581     
PWND    pWnd;
00582     
PIMEDPI pImeDpi;
00583     
BOOL    fRet = 
FALSE;
00584 
00585     
if ((pWnd = 
ValidateHwnd(
hWnd)) == (
PWND)
NULL) {
00586         RIPMSG1(RIP_WARNING,
00587               
"ImmConfigureIMEA: invalid window handle %x", 
hWnd);
00588         
return FALSE;
00589     }
00590 
00591     
if (!
TestWindowProcess(pWnd)) {
00592         RIPMSG1(RIP_WARNING,
00593               
"ImmConfigureIMEA: hWnd=%lx belongs to different process!", 
hWnd);
00594         
return FALSE;
00595     }
00596 
00597     pImeDpi = 
FindOrLoadImeDpi(hKL);
00598     
if (pImeDpi == 
NULL) {
00599         RIPMSG0(RIP_WARNING, 
"ImmConfigureIMEA: no pImeDpi entry.");
00600         
return FALSE;
00601     }
00602 
00603     
if (!(pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData == 
NULL) {
00604         
00605 
00606 
00607 
00608             
00609             
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_OPENPROPERTYWINDOW, 0
L);
00610         fRet = (*pImeDpi->
pfn.
ImeConfigure)(hKL, 
hWnd, dwMode, lpData);
00611             
00612             
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_CLOSEPROPERTYWINDOW, 0
L);
00613         
ImmUnlockImeDpi(pImeDpi);
00614         
return fRet;
00615     }
00616 
00617     
00618 
00619 
00620 
00621 
00622     
switch (dwMode) {
00623     
case IME_CONFIG_REGISTERWORD:
00624         {
00625             LPREGISTERWORDA lpRegisterWordA;
00626             REGISTERWORDW   RegisterWordW;
00627             
LPVOID          lpBuffer;
00628             ULONG           cbBuffer;
00629             
INT             i;
00630 
00631             lpRegisterWordA = (LPREGISTERWORDA)lpData;
00632             cbBuffer = 0;
00633             lpBuffer = 
NULL;
00634 
00635             
if (lpRegisterWordA->lpReading != 
NULL)
00636                 cbBuffer += 
strlen(lpRegisterWordA->lpReading) + 1;
00637 
00638             
if (lpRegisterWordA->lpWord != 
NULL)
00639                 cbBuffer += 
strlen(lpRegisterWordA->lpWord) + 1;
00640 
00641             
if (cbBuffer != 0) {
00642                 cbBuffer *= 
sizeof(WCHAR);
00643                 
if ((lpBuffer = 
ImmLocalAlloc(0, cbBuffer)) == 
NULL) {
00644                     RIPMSG0(RIP_WARNING, 
"ImmConfigureIMEA: memory failure.");
00645                     
break;
00646                 }
00647             }
00648 
00649             
if (lpRegisterWordA->lpReading != 
NULL) {
00650                 RegisterWordW.lpReading = lpBuffer;
00651                 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
00652                                         (
DWORD)MB_PRECOMPOSED,
00653                                         (LPSTR)lpRegisterWordA->lpReading,
00654                                         (
INT)
strlen(lpRegisterWordA->lpReading),
00655                                         (LPWSTR)RegisterWordW.lpReading,
00656                                         (
INT)(cbBuffer/
sizeof(WCHAR)));
00657                 RegisterWordW.lpReading[i] = 
L'\0';
00658                 cbBuffer -= (i * 
sizeof(WCHAR));
00659             }
00660             
else {
00661                 RegisterWordW.lpReading = 
NULL;
00662             }
00663 
00664             
if (lpRegisterWordA->lpWord != 
NULL) {
00665                 
if (RegisterWordW.lpReading != 
NULL)
00666                     RegisterWordW.lpWord = &RegisterWordW.lpReading[i+1];
00667                 
else
00668                     RegisterWordW.lpWord = lpBuffer;
00669                 i = MultiByteToWideChar(
IMECodePage(pImeDpi),
00670                                         (
DWORD)MB_PRECOMPOSED,
00671                                         (LPSTR)lpRegisterWordA->lpWord,
00672                                         (
INT)
strlen(lpRegisterWordA->lpWord),
00673                                         (LPWSTR)RegisterWordW.lpWord,
00674                                         (
INT)(cbBuffer/
sizeof(WCHAR)));
00675                 RegisterWordW.lpWord[i] = 
L'\0';
00676             }
00677             
else
00678                 RegisterWordW.lpWord = 
NULL;
00679 
00680             fRet = 
ImmConfigureIMEW(hKL, 
hWnd, dwMode, &RegisterWordW);
00681 
00682             
if (lpBuffer != 
NULL)
00683                 
ImmLocalFree(lpBuffer);
00684 
00685             
break;
00686         }
00687     
default:
00688         fRet = 
ImmConfigureIMEW(hKL, 
hWnd, dwMode, lpData);
00689         
break;
00690     }
00691 
00692     
ImmUnlockImeDpi(pImeDpi);
00693 
00694     
return fRet;
00695 }
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 
00707 BOOL WINAPI 
ImmConfigureIMEW(
00708     HKL    hKL,
00709     HWND   hWnd,
00710     DWORD  dwMode,
00711     LPVOID lpData)
00712 {
00713     
PWND    pWnd;
00714     
PIMEDPI pImeDpi;
00715     
BOOL    fRet = 
FALSE;
00716 
00717     
if ((pWnd = 
ValidateHwnd(
hWnd)) == (
PWND)
NULL) {
00718         RIPMSG1(RIP_WARNING,
00719               
"ImmConfigureIMEA: invalid window handle %x", 
hWnd);
00720         
return FALSE;
00721     }
00722 
00723     
if (!
TestWindowProcess(pWnd)) {
00724         RIPMSG1(RIP_WARNING,
00725               
"ImmConfigureIMEA: hWnd=%lx belongs to different process!", 
hWnd);
00726         
return FALSE;
00727     }
00728 
00729     pImeDpi = 
FindOrLoadImeDpi(hKL);
00730     
if (pImeDpi == 
NULL) {
00731         RIPMSG0(RIP_WARNING, 
"ImmConfigureIMEA: no pImeDpi entry.");
00732         
return FALSE;
00733     }
00734 
00735     
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData == 
NULL) {
00736         
00737 
00738 
00739 
00740             
00741             
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_OPENPROPERTYWINDOW, 0
L);
00742         fRet = (*pImeDpi->
pfn.
ImeConfigure)(hKL, 
hWnd, dwMode, lpData);
00743             
00744             
SendMessage(
hWnd, WM_IME_SYSTEM, IMS_CLOSEPROPERTYWINDOW, 0
L);
00745         
ImmUnlockImeDpi(pImeDpi);
00746         
return fRet;
00747     }
00748 
00749     
00750 
00751 
00752 
00753 
00754     
switch (dwMode) {
00755     
case IME_CONFIG_REGISTERWORD:
00756         {
00757             LPREGISTERWORDW lpRegisterWordW;
00758             REGISTERWORDA   RegisterWordA;
00759             
LPVOID          lpBuffer;
00760             ULONG           cbBuffer;
00761             
BOOL            bUDC;
00762             
INT             i;
00763 
00764             lpRegisterWordW = (LPREGISTERWORDW)lpData;
00765             cbBuffer = 0;
00766             lpBuffer = 
NULL;
00767 
00768             
if (lpRegisterWordW->lpReading != 
NULL)
00769                 cbBuffer += wcslen(lpRegisterWordW->lpReading) + 1;
00770 
00771             
if (lpRegisterWordW->lpWord != 
NULL)
00772                 cbBuffer += wcslen(lpRegisterWordW->lpWord) + 1;
00773 
00774             
if (cbBuffer != 0) {
00775                 cbBuffer *= 
sizeof(WCHAR);
00776                 
if ((lpBuffer = 
ImmLocalAlloc(0, cbBuffer)) == 
NULL) {
00777                     RIPMSG0(RIP_WARNING, 
"ImmConfigureIMEW: memory failure.");
00778                     
break;
00779                 }
00780             }
00781 
00782             
if (lpRegisterWordW->lpReading != 
NULL) {
00783                 RegisterWordA.lpReading = lpBuffer;
00784                 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00785                                         (
DWORD)0,
00786                                         (LPWSTR)lpRegisterWordW->lpReading,
00787                                         (
INT)wcslen(lpRegisterWordW->lpReading),
00788                                         (LPSTR)RegisterWordA.lpReading,
00789                                         (
INT)cbBuffer,
00790                                         (LPSTR)
NULL,
00791                                         (LPBOOL)&bUDC);
00792                 RegisterWordA.lpReading[i] = 
'\0';
00793                 cbBuffer -= (i * 
sizeof(
CHAR));
00794             }
00795             
else {
00796                 RegisterWordA.lpReading = 
NULL;
00797             }
00798 
00799             
if (lpRegisterWordW->lpWord != 
NULL) {
00800                 
if (RegisterWordA.lpReading != 
NULL)
00801                     RegisterWordA.lpWord = &RegisterWordA.lpReading[i+1];
00802                 
else
00803                     RegisterWordA.lpWord = lpBuffer;
00804                 i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00805                                         (
DWORD)0,
00806                                         (LPWSTR)lpRegisterWordW->lpWord,
00807                                         (
INT)wcslen(lpRegisterWordW->lpWord),
00808                                         (LPSTR)RegisterWordA.lpWord,
00809                                         (
INT)cbBuffer,
00810                                         (LPSTR)
NULL,
00811                                         (LPBOOL)&bUDC);
00812                 RegisterWordA.lpWord[i] = 
'\0';
00813             }
00814             
else
00815                 RegisterWordA.lpWord = 
NULL;
00816 
00817             fRet = 
ImmConfigureIMEA(hKL, 
hWnd, dwMode, &RegisterWordA);
00818 
00819             
if (lpBuffer != 
NULL)
00820                 
ImmLocalFree(lpBuffer);
00821 
00822             
break;
00823         }
00824     
default:
00825         fRet = 
ImmConfigureIMEA(hKL, 
hWnd, dwMode, lpData);
00826         
break;
00827     }
00828 
00829     
ImmUnlockImeDpi(pImeDpi);
00830 
00831     
return fRet;
00832 }
00833 
00834 
00835 #define IME_T_EUDC_DIC_SIZE 80  // the Traditional Chinese EUDC dictionary
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 LRESULT WINAPI 
ImmEscapeA(
00850     HKL    hKL,
00851     HIMC   hImc,
00852     UINT   uSubFunc,
00853     LPVOID lpData)
00854 {
00855     
PIMEDPI pImeDpi;
00856     LRESULT lRet = 0;
00857 
00858     pImeDpi = 
FindOrLoadImeDpi(hKL);
00859     
if (pImeDpi == 
NULL) {
00860         RIPMSG0(RIP_WARNING, 
"ImmEscapeA: no pImeDpi entry.");
00861         
return lRet;
00862     }
00863 
00864     
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) == 0 || lpData == 
NULL) {
00865         
00866 
00867 
00868 
00869         lRet = (*pImeDpi->
pfn.
ImeEscape)(hImc, uSubFunc, lpData);
00870         
ImmUnlockImeDpi(pImeDpi);
00871         
return lRet;
00872     }
00873 
00874     
00875 
00876 
00877 
00878     
switch (uSubFunc) {
00879     
case IME_ESC_GET_EUDC_DICTIONARY:
00880     
case IME_ESC_IME_NAME:
00881     
case IME_ESC_GETHELPFILENAME:
00882         {
00883             WCHAR wszData[
IME_T_EUDC_DIC_SIZE];
00884             
BOOL  bUDC;
00885             
INT   i;
00886 
00887             lRet = 
ImmEscapeW(hKL, hImc, uSubFunc, (
LPVOID)wszData);
00888 
00889             
if (lRet != 0) {
00890 
00891                 
try {
00892                     i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00893                                             (
DWORD)0,
00894                                             (LPWSTR)wszData,         
00895                                             (
INT)wcslen(wszData),
00896                                             (LPSTR)lpData,           
00897                                             (
INT)
IME_T_EUDC_DIC_SIZE,
00898                                             (LPSTR)
NULL,
00899                                             (LPBOOL)&bUDC);
00900                     ((LPSTR)lpData)[i] = 
'\0';
00901                 }
00902                 except (
EXCEPTION_EXECUTE_HANDLER) {
00903                     lRet = 0;
00904                 }
00905             }
00906 
00907             
break;
00908         }
00909 
00910     
case IME_ESC_SET_EUDC_DICTIONARY:
00911     
case IME_ESC_HANJA_MODE:
00912         {
00913             WCHAR wszData[
IME_T_EUDC_DIC_SIZE];
00914             
INT   i;
00915 
00916             i = MultiByteToWideChar(
IMECodePage(pImeDpi),
00917                                     (
DWORD)MB_PRECOMPOSED,
00918                                     (LPSTR)lpData,             
00919                                     (
INT)
strlen(lpData),
00920                                     (LPWSTR)wszData,          
00921                                     (
INT)
sizeof(wszData)/
sizeof(WCHAR));
00922             wszData[i] = 
L'\0';
00923 
00924             lRet = 
ImmEscapeW(hKL, hImc, uSubFunc, (
LPVOID)wszData);
00925 
00926             
break;
00927         }
00928 
00929     
case IME_ESC_SEQUENCE_TO_INTERNAL:
00930         {
00931             
CHAR    szData[4];
00932             WCHAR   wszData[4];
00933             
INT     i = 0;
00934 
00935             lRet = 
ImmEscapeW(hKL, hImc, uSubFunc, lpData);
00936 
00937             
if (HIWORD(lRet))
00938                 wszData[i++] = HIWORD(lRet);
00939 
00940             
if (LOWORD(lRet))
00941                 wszData[i++] = LOWORD(lRet);
00942 
00943             i = WideCharToMultiByte(
IMECodePage(pImeDpi),
00944                                     (
DWORD)0,
00945                                     (LPWSTR)wszData,        
00946                                     (
INT)i,
00947                                     (LPSTR)szData,          
00948                                     (
INT)
sizeof(szData),
00949                                     (LPSTR)
NULL,
00950                                     (LPBOOL)
NULL);
00951 
00952             
switch (i) {
00953             
case 1:
00954                 lRet = MAKELONG(MAKEWORD(szData[0], 0), 0);
00955                 
break;
00956 
00957             
case 2:
00958                 lRet = MAKELONG(MAKEWORD(szData[1], szData[0]), 0);
00959                 
break;
00960 
00961             
case 3:
00962                 lRet = MAKELONG(MAKEWORD(szData[2], szData[1]), MAKEWORD(szData[0], 0));
00963                 
break;
00964 
00965             
case 4:
00966                 lRet = MAKELONG(MAKEWORD(szData[3], szData[2]), MAKEWORD(szData[1], szData[0]));
00967                 
break;
00968 
00969             
default:
00970                 lRet = 0;
00971                 
break;
00972             }
00973 
00974             
break;
00975         }
00976     
default:
00977         lRet = 
ImmEscapeW(hKL, hImc, uSubFunc, lpData);
00978         
break;
00979     }
00980 
00981     
ImmUnlockImeDpi(pImeDpi);
00982 
00983     
return lRet;
00984 }
00985 
00986 
00987 
00988 
00989 
00990 
00991 
00992 
00993 
00994 
00995 
00996 
00997 
00998 
00999 LRESULT WINAPI 
ImmEscapeW(
01000     HKL    hKL,
01001     HIMC   hImc,
01002     UINT   uSubFunc,
01003     LPVOID lpData)
01004 {
01005     
PIMEDPI pImeDpi;
01006     LRESULT lRet = 0;
01007 
01008     pImeDpi = 
FindOrLoadImeDpi(hKL);
01009     
if (pImeDpi == 
NULL) {
01010         RIPMSG0(RIP_WARNING, 
"ImmEscapeW: no pImeDpi entry.");
01011         
return lRet;
01012     }
01013 
01014     
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData == 
NULL) {
01015         
01016 
01017 
01018 
01019         lRet = (*pImeDpi->
pfn.
ImeEscape)(hImc, uSubFunc, lpData);
01020         
ImmUnlockImeDpi(pImeDpi);
01021         
return lRet;
01022     }
01023 
01024     
01025 
01026 
01027 
01028     
switch (uSubFunc) {
01029     
case IME_ESC_GET_EUDC_DICTIONARY:
01030     
case IME_ESC_IME_NAME:
01031     
case IME_ESC_GETHELPFILENAME:
01032         {
01033             
CHAR szData[
IME_T_EUDC_DIC_SIZE];
01034             
INT  i;
01035 
01036             lRet = 
ImmEscapeA(hKL, hImc, uSubFunc, (
LPVOID)szData);
01037 
01038             
if (lRet != 0) {
01039 
01040                 
try {
01041                     i = MultiByteToWideChar(
IMECodePage(pImeDpi),
01042                                             (
DWORD)MB_PRECOMPOSED,
01043                                             (LPSTR)szData,          
01044                                             (
INT)
strlen(szData),
01045                                             (LPWSTR)lpData,         
01046                                             (
INT)
IME_T_EUDC_DIC_SIZE);
01047                     ((LPWSTR)lpData)[i] = 
L'\0';
01048                 }
01049                 except (
EXCEPTION_EXECUTE_HANDLER) {
01050                     lRet = 0;
01051                 }
01052             }
01053 
01054             
break;
01055         }
01056 
01057     
case IME_ESC_SET_EUDC_DICTIONARY:
01058     
case IME_ESC_HANJA_MODE:
01059         {
01060             
CHAR szData[
IME_T_EUDC_DIC_SIZE];
01061             
BOOL bUDC;
01062             
INT  i;
01063 
01064             i = WideCharToMultiByte(
IMECodePage(pImeDpi),
01065                                     (
DWORD)0,
01066                                     (LPWSTR)lpData,          
01067                                     (
INT)wcslen(lpData),
01068                                     (LPSTR)szData,          
01069                                     (
INT)
sizeof(szData),
01070                                     (LPSTR)
NULL,
01071                                     (LPBOOL)&bUDC);
01072             szData[i] = 
'\0';
01073 
01074             lRet = 
ImmEscapeA(hKL, hImc, uSubFunc, (
LPVOID)szData);
01075 
01076             
break;
01077         }
01078 
01079     
case IME_ESC_SEQUENCE_TO_INTERNAL:
01080         {
01081             
CHAR    szData[4];
01082             WCHAR   wszData[4];
01083             
INT     i = 0;
01084 
01085             lRet = 
ImmEscapeA(hKL, hImc, uSubFunc, lpData);
01086 
01087             
if (
HIBYTE(LOWORD(lRet)))
01088                 szData[i++] = 
HIBYTE(LOWORD(lRet));
01089 
01090             
if (
LOBYTE(LOWORD(lRet)))
01091                 szData[i++] = 
LOBYTE(LOWORD(lRet));
01092 
01093             i = MultiByteToWideChar(
IMECodePage(pImeDpi),
01094                                     (
DWORD)MB_PRECOMPOSED,
01095                                     (LPSTR)szData,            
01096                                     i,
01097                                     (LPWSTR)wszData,          
01098                                     (
INT)
sizeof(wszData)/
sizeof(WCHAR));
01099 
01100             
switch (i) {
01101             
case 1:
01102                 lRet = MAKELONG(wszData[0], 0);
01103                 
break;
01104 
01105             
case 2:
01106                 lRet = MAKELONG(wszData[1], wszData[0]);
01107                 
break;
01108 
01109             
default:
01110                 lRet = 0;
01111                 
break;
01112             }
01113 
01114             
break;
01115         }
01116 
01117     
default:
01118         lRet = 
ImmEscapeA(hKL, hImc, uSubFunc, lpData);
01119         
break;
01120     }
01121 
01122     
ImmUnlockImeDpi(pImeDpi);
01123 
01124     
return lRet;
01125 }
01126 
01127 
01128 BOOL WINAPI 
ImmPenAuxInput(HWND hwndSender, LPVOID lpData)
01129 {
01130     
PIMEDPI pImeDpi = 
NULL;
01131     PCOPYDATASTRUCT lpCopyData = (PCOPYDATASTRUCT)lpData;
01132     PENINPUTDATA* lpPenInputData = (
LPVOID)lpCopyData->lpData;
01133     IMEPENDATA ImePenData;
01134     HWND hwnd;
01135     HIMC himc;
01136     HKL hkl;
01137     
DWORD dwData = 0 ;
01138     LPDWORD lpdwData = 
NULL;
01139 
01140     UNREFERENCED_PARAMETER(hwndSender);
01141 
01142     
if (lpCopyData->dwData != LM_IMM_MAGIC || lpCopyData->cbData < 
sizeof(PENINPUTDATA)) {
01143         RIPMSG0(RIP_WARNING, 
"ImmPenAuxInput: invalid COPYDATASTRUCT signagure.");
01144         
return FALSE;
01145     }
01146 
01147     
if (lpPenInputData->dwVersion != 0) {
01148         RIPMSG0(RIP_WARNING, 
"ImmPenAuxInput: invalid Pendata version.");
01149         
return FALSE;
01150     }
01151 
01152     hwnd = 
GetFocus();
01153     hkl = 
GetKeyboardLayout(0);
01154     
if (hwnd == 
NULL || hkl == 
NULL || (himc = 
ImmGetContext(hwnd)) == 
NULL) {
01155         RIPMSG0(RIP_WARNING, 
"ImmPenAuxInput: hwnd, hkl or himc cannot be aquired.");
01156         
return FALSE;
01157     }
01158 
01159     
if ((pImeDpi = 
FindOrLoadImeDpi(hkl)) == 
NULL) {
01160         RIPMSG0(RIP_WARNING, 
"ImmPenAuxInput: IME DPI cannot be found.");
01161         
return FALSE;
01162     }
01163 
01164     
do {    
01165         dwData = IME_ESC_PENAUXDATA;
01166         
if (!pImeDpi->
pfn.
ImeEscape(himc, IME_ESC_QUERY_SUPPORT, (
LPVOID)&dwData)) {
01167             
01168             
01169             
01170             RIPMSG1(RIP_VERBOSE, 
"ImmPenAuxInput: IME(hkl=%08x) does not support IME_ESC_PENDATA", hkl);
01171             
break;
01172         }
01173 
01174         dwData = 0; 
01175 
01176         
01177         
01178         
01179 
01180         RtlZeroMemory(&ImePenData, 
sizeof ImePenData);
01181 
01182         ImePenData.dwCount = lpPenInputData->cnt;
01183 
01184         
if (lpPenInputData->flags & ~(LMDATA_SYMBOL_DWORD | LMDATA_SKIP_WORD | LMDATA_SCORE_WORD)) {
01185             RIPMSG1(RIP_WARNING, 
"ImmPenAuxInput: flag out of range (0x%08x)", lpPenInputData->flags);
01186         }
01187 
01188         
01189         
01190         
01191 
01192         
if (lpPenInputData->flags & LMDATA_SYMBOL_DWORD) {
01193             
if (lpPenInputData->dwOffsetSymbols > lpCopyData->cbData ||
01194                     lpPenInputData->dwOffsetSymbols + lpPenInputData->cnt * 
sizeof(
DWORD) > lpCopyData->cbData) {
01195                 
01196                 
01197                 
01198                 RIPMSG1(RIP_WARNING, 
"ImmPenAuxInput: illegal dwOffsetSymbols (0x%x)", lpPenInputData->dwOffsetSymbols);
01199                 
break;
01200             }
01201             ImePenData.wd.lpSymbol = (
LPVOID)&lpPenInputData->ab[lpPenInputData->dwOffsetSymbols];
01202             ImePenData.dwFlags |= IME_PEN_SYMBOL;
01203 
01204             
01205             
01206             
01207             
if ((pImeDpi->
ImeInfo.fdwProperty & IME_PROP_UNICODE) == 0) {
01208                 
USHORT wCodePage = (
USHORT)
GetKeyboardLayoutCP(hkl);
01209                 
int i;
01210 
01211                 lpdwData = 
ImmLocalAlloc(HEAP_ZERO_MEMORY, 
sizeof *lpdwData * ImePenData.dwCount);
01212                 
if (lpdwData == 
NULL) {
01213                     RIPMSG0(RIP_WARNING, 
"ImmPenAuxInput: could not allocate lpdwData");
01214                     
break;
01215                 }
01216                 
for (i = 0; i < (
int)ImePenData.dwCount; ++i) {
01217                     LPSTR lpstr = (LPSTR)(lpdwData + i);
01218 
01219                     
01220                     WCSToMBEx(wCodePage,
01221                               (LPCWSTR)(ImePenData.wd.lpSymbol + i), 1,
01222                               &lpstr, 2,
01223                               
FALSE);
01224                     
ImmAssert(HIWORD(lpdwData[i]) == 0);
01225 
01226                     
01227                     lpdwData[i] |= (ImePenData.wd.lpSymbol[i] & ~0xffff);
01228                 }
01229                 ImePenData.wd.lpSymbol = lpdwData;
01230             }
01231 
01232         }
01233 
01234         
if (lpPenInputData->flags & LMDATA_SKIP_WORD) {
01235             
if (lpPenInputData->dwOffsetSkip > lpCopyData->cbData ||
01236                     lpPenInputData->dwOffsetSkip + lpPenInputData->cnt * 
sizeof(WORD) > lpCopyData->cbData) {
01237                 
01238                 
01239                 
01240                 RIPMSG1(RIP_WARNING, 
"ImmPenAuxInput: illegal dwOffsetSkip (0x%x)", lpPenInputData->dwOffsetSkip);
01241                 
break;
01242             }
01243             ImePenData.wd.lpSkip = (
LPVOID)&lpPenInputData->ab[lpPenInputData->dwOffsetSkip];
01244             ImePenData.dwFlags |= IME_PEN_SKIP;
01245         }
01246 
01247         
if (lpPenInputData->flags & LMDATA_SCORE_WORD) {
01248             
if (lpPenInputData->dwOffsetScore > lpCopyData->cbData ||
01249                     lpPenInputData->dwOffsetScore + lpPenInputData->cnt * 
sizeof(WORD) > lpCopyData->cbData) {
01250                 
01251                 
01252                 
01253                 RIPMSG1(RIP_WARNING, 
"ImmPenAuxInput: illegal dwOffsetScore (0x%x)", lpPenInputData->dwOffsetScore);
01254                 
break;
01255             }
01256             ImePenData.wd.lpScore = (
LPVOID)&lpPenInputData->ab[lpPenInputData->dwOffsetScore];
01257             ImePenData.dwFlags |= IME_PEN_SCORE;
01258         }
01259         dwData = (
DWORD)pImeDpi->
pfn.
ImeEscape(himc, IME_ESC_PENAUXDATA, &ImePenData);
01260     } 
while (
FALSE);
01261 
01262     
if (lpdwData) {
01263         
ImmLocalFree(lpdwData);
01264     }
01265 
01266     
ImmAssert(pImeDpi);
01267     
ImmUnlockImeDpi(pImeDpi);
01268 
01269     
return dwData;
01270 }
01271 
01272 LRESULT WINAPI 
ImmSendMessageToActiveDefImeWndW(
01273     UINT msg,
01274     WPARAM wParam,
01275     LPARAM lParam)
01276 {
01277     HWND hwndIme;
01278 
01279     
01280     
01281     
01282     
if (
msg != WM_COPYDATA) {
01283         
return 0;
01284     }
01285 
01286     hwndIme = 
NtUserQueryWindow((HWND)wParam, WindowActiveDefaultImeWindow);
01287     
if (hwndIme == 
NULL) {
01288         
return 0;
01289     }
01290 
01291     
return SendMessage(hwndIme, 
msg, wParam, lParam);
01292 }
01293 
01294 BOOL WINAPI 
ImmNotifyIME(
01295     HIMC  hImc,
01296     DWORD dwAction,
01297     DWORD dwIndex,
01298     DWORD dwValue)
01299 {
01300     
PIMEDPI pImeDpi;
01301     
BOOL    bRet;
01302 
01303     
if (hImc != 
NULL_HIMC &&
01304             
GetInputContextThread(hImc) != GetCurrentThreadId()) {
01305         RIPMSG1(RIP_WARNING,
01306               
"ImmNotifyIME: Invalid input context access %lx.", hImc);
01307         
return FALSE;
01308     }
01309 
01310     pImeDpi = 
ImmLockImeDpi(
GetKeyboardLayout(0));
01311     
if (pImeDpi == 
NULL)
01312         
return FALSE;
01313 
01314     bRet = (*pImeDpi->
pfn.
NotifyIME)(hImc, dwAction, dwIndex, dwValue);
01315 
01316     
ImmUnlockImeDpi(pImeDpi);
01317 
01318     
return bRet;
01319 }