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

immime.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: immime.c (corresponds to Win95 ime.c) 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * IME DLL related functinality 00007 * 00008 * History: 00009 * 03-Jan-1996 wkwok Created 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 * parameter checking for each fields. 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 * This is ANSI IME. Ensure that it is usable under current system 00096 * codepage. 00097 */ 00098 if (pImeDpi->dwCodePage != GetACP() && pImeDpi->dwCodePage != CP_ACP) { 00099 // Note: in the future, if possible, these reference to dwCodepage 00100 // should be IMECodePage()... 00101 RIPMSG1(RIP_WARNING, "incompatible codepage(%d) for ANSI IME", pImeDpi->dwCodePage); 00102 return FALSE; 00103 } 00104 00105 /* 00106 * ANSI -> Unicode Class name. 00107 */ 00108 MultiByteToWideChar(IMECodePage(pImeDpi), 00109 (DWORD)MB_PRECOMPOSED, 00110 (LPSTR)ClassName, // src 00111 (INT)-1, 00112 pImeDpi->wszUIClass, // dest 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 // 4.0 IMEs don't have this entry. could be NULL. 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 * Update kernel side IMEINFOEX for this keyboard layout if 00192 * this is its first loading. 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 * Destroy IME first. 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 * Query the IME information. 00243 */ 00244 if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) { 00245 RIPMSG1(RIP_WARNING, "LoadImeDpi: ImmGetImeInfoEx(%lx) failed", hKL); 00246 return NULL; 00247 } 00248 00249 /* 00250 * Win95 behaviour: If there was an IME load error for this layout, 00251 * further attempt to load the same IME layout will be rejected. 00252 */ 00253 if (iiex.fLoadFlag == IMEF_LOADERROR) 00254 return NULL; 00255 00256 /* 00257 * Allocate a new IMEDPI for this layout. 00258 */ 00259 pImeDpi = (PIMEDPI)ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(IMEDPI)); 00260 if (pImeDpi == NULL) 00261 return NULL; 00262 00263 pImeDpi->hKL = hKL; 00264 00265 // get code page of IME 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 * Load up IME DLL. 00278 */ 00279 if (!LoadIME(&iiex, pImeDpi)) { 00280 ImmLocalFree(pImeDpi); 00281 return NULL; 00282 } 00283 00284 /* 00285 * Link in the newly allocated entry. 00286 */ 00287 RtlEnterCriticalSection(&gcsImeDpi); 00288 00289 pImeDpiT = ImmGetImeDpi(hKL); 00290 00291 if (pImeDpiT == NULL) { 00292 if (fLock) { 00293 /* 00294 * Newly loaded with lock, will unload upon unlock. 00295 */ 00296 pImeDpi->cLock = 1; 00297 pImeDpi->dwFlag |= IMEDPI_UNLOCKUNLOAD; 00298 } 00299 00300 /* 00301 * Update the global list for this new pImeDpi entry. 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 * The same IME has been loaded, discard this extra entry. 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 * Non IME based keyboard layout doesn't have IMEDPI. 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 * Non IME based keyboard layout doesn't have IMEDPI. 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 * Unlink it. 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 * Unload the IME DLL. 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 * Do nothing if no IME to be deactivated. 00431 */ 00432 if (!IS_IME_KBDLAYOUT(hklCurrent)) 00433 return TRUE; 00434 00435 /* 00436 * Deactivate IME based layout by activating a non-IME based 00437 * keyboard layout. 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 // Somehow it failed (probably a bad setup), let's try 00463 // 409 KL, which should be installed on all localized NTs. 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; // Rescan as list was updated. 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 * if already current active, do nothing 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 * Send out CPS_CANCEL or CPS_COMPLETE to every input 00528 * context assoicated to window(s) created by this thread. 00529 * Starting from SUR, we only assoicate input context to window created 00530 * by the same thread. 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 * This is the time to update the kernel side layout handles. 00544 * We must do this before sending WM_IME_SELECT. 00545 */ 00546 NtUserSetThreadLayoutHandles(hSelKL, hUnSelKL); 00547 } 00548 00549 /* 00550 * Unselect and select input context(s). 00551 */ 00552 sce.hSelKL = hSelKL; 00553 sce.hUnSelKL = hUnSelKL; 00554 ImmEnumInputContext(0, (IMCENUMPROC)SelectContextProc, (LPARAM)&sce); 00555 00556 /* 00557 * inform UI select after all hIMC select 00558 */ 00559 if (IsWindow(hWndDefaultIme)) 00560 SendMessage(hWndDefaultIme, WM_IME_SELECT, TRUE, (LPARAM)hSelKL); 00561 00562 return (TRUE); 00563 } 00564 00565 00566 /***************************************************************************\ 00567 * ImmConfigureIMEA 00568 * 00569 * Brings up the configuration dialogbox of the IME with the specified hKL. 00570 * 00571 * History: 00572 * 29-Feb-1995 wkwok Created 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 * Doesn't need A/W conversion. Calls directly to IME to 00606 * bring up the configuration dialogbox. 00607 */ 00608 // This message handles by Console IME. 00609 SendMessage(hWnd, WM_IME_SYSTEM, IMS_OPENPROPERTYWINDOW, 0L); 00610 fRet = (*pImeDpi->pfn.ImeConfigure)(hKL, hWnd, dwMode, lpData); 00611 // This message handles by Console IME. 00612 SendMessage(hWnd, WM_IME_SYSTEM, IMS_CLOSEPROPERTYWINDOW, 0L); 00613 ImmUnlockImeDpi(pImeDpi); 00614 return fRet; 00615 } 00616 00617 /* 00618 * ANSI caller, Unicode IME. Needs A/W conversion on lpData when 00619 * dwMode == IME_CONFIG_REGISTERWORD. In this case, lpData points 00620 * to a structure of REGISTERWORDA. 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 * ImmConfigureIMEW 00700 * 00701 * Brings up the configuration dialogbox of the IME with the specified hKL. 00702 * 00703 * History: 00704 * 29-Feb-1995 wkwok Created 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 * Doesn't need A/W conversion. Calls directly to IME to 00738 * bring up the configuration dialogbox. 00739 */ 00740 // This message handles by Console IME. 00741 SendMessage(hWnd, WM_IME_SYSTEM, IMS_OPENPROPERTYWINDOW, 0L); 00742 fRet = (*pImeDpi->pfn.ImeConfigure)(hKL, hWnd, dwMode, lpData); 00743 // This message handles by Console IME. 00744 SendMessage(hWnd, WM_IME_SYSTEM, IMS_CLOSEPROPERTYWINDOW, 0L); 00745 ImmUnlockImeDpi(pImeDpi); 00746 return fRet; 00747 } 00748 00749 /* 00750 * Unicode caller, ANSI IME. Needs A/W conversion on lpData when 00751 * dwMode == IME_CONFIG_REGISTERWORD. In this case, lpData points 00752 * to a structure of REGISTERWORDW. 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 * ImmEscapeA 00839 * 00840 * This API allows an application to access capabilities of a particular 00841 * IME with specified hKL not directly available thru. other IMM APIs. 00842 * This is necessary mainly for country specific functions or private 00843 * functions in IME. 00844 * 00845 * History: 00846 * 29-Feb-1995 wkwok Created 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 * Doesn't need A/W conversion. Calls directly to IME to 00867 * bring up the configuration dialogbox. 00868 */ 00869 lRet = (*pImeDpi->pfn.ImeEscape)(hImc, uSubFunc, lpData); 00870 ImmUnlockImeDpi(pImeDpi); 00871 return lRet; 00872 } 00873 00874 /* 00875 * ANSI caller, Unicode IME. Needs A/W conversion depending on 00876 * uSubFunc. 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, // src 00895 (INT)wcslen(wszData), 00896 (LPSTR)lpData, // dest 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, // src 00919 (INT)strlen(lpData), 00920 (LPWSTR)wszData, // dest 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, // src 00946 (INT)i, 00947 (LPSTR)szData, // dest 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 * ImmEscapeW 00989 * 00990 * This API allows an application to access capabilities of a particular 00991 * IME with specified hKL not directly available thru. other IMM APIs. 00992 * This is necessary mainly for country specific functions or private 00993 * functions in IME. 00994 * 00995 * History: 00996 * 29-Feb-1995 wkwok Created 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 * Doesn't need W/A conversion. Calls directly to IME to 01017 * bring up the configuration dialogbox. 01018 */ 01019 lRet = (*pImeDpi->pfn.ImeEscape)(hImc, uSubFunc, lpData); 01020 ImmUnlockImeDpi(pImeDpi); 01021 return lRet; 01022 } 01023 01024 /* 01025 * Unicode caller, ANSI IME. Needs W/A conversion depending on 01026 * uSubFunc. 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, // src 01044 (INT)strlen(szData), 01045 (LPWSTR)lpData, // dest 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, // src 01067 (INT)wcslen(lpData), 01068 (LPSTR)szData, // dest 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, // src 01096 i, 01097 (LPWSTR)wszData, // dest 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 { // dummy loop (execute just once) so that we can 'break' in case of unexpected errors 01165 dwData = IME_ESC_PENAUXDATA; 01166 if (!pImeDpi->pfn.ImeEscape(himc, IME_ESC_QUERY_SUPPORT, (LPVOID)&dwData)) { 01167 // 01168 // IME_ESC_PENAUXDATA is not supported by the current IME. 01169 // 01170 RIPMSG1(RIP_VERBOSE, "ImmPenAuxInput: IME(hkl=%08x) does not support IME_ESC_PENDATA", hkl); 01171 break; 01172 } 01173 01174 dwData = 0; // Be prepared for unexpected exodus 01175 01176 // 01177 // Makeup the IMEPENDATA structure. 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 // Setup the structure for IME. 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 // Invalid structure 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 // If it's ANSI IME, we need to translate the symbols 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 // Assuming little endian: 01220 WCSToMBEx(wCodePage, 01221 (LPCWSTR)(ImePenData.wd.lpSymbol + i), 1, 01222 &lpstr, 2, 01223 FALSE); 01224 ImmAssert(HIWORD(lpdwData[i]) == 0); 01225 01226 // Copy the high word (column #). 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 // Invalid structure 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 // Invalid structure 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 // Today we only support this for WM_COPYDATA 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 }

Generated on Sat May 15 19:40:21 2004 for test by doxygen 1.3.7