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

misc.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: misc.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * 00007 * History: 00008 * 03-Jan-1996 wkwok Created 00009 \**************************************************************************/ 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 #ifdef HIRO_DEBUG 00015 #define D(x) x 00016 #else 00017 #define D(x) 00018 #endif 00019 00020 00021 /**************************************************************************\ 00022 * ImmGetDefaultIMEWnd 00023 * 00024 * 03-Jan-1996 wkwok Created 00025 \**************************************************************************/ 00026 00027 HWND WINAPI ImmGetDefaultIMEWnd( 00028 HWND hWnd) 00029 { 00030 if (!IS_IME_ENABLED()) { 00031 return NULL; 00032 } 00033 if (hWnd == NULL) { 00034 /* 00035 * Query default IME window of current thread. 00036 */ 00037 return (HWND)NtUserGetThreadState(UserThreadStateDefaultImeWindow); 00038 } 00039 00040 return (HWND)NtUserQueryWindow(hWnd, WindowDefaultImeWindow); 00041 } 00042 00043 00044 /**************************************************************************\ 00045 * ImmDisableIME 00046 * 00047 * 13-Sep-1996 wkwok Created 00048 \**************************************************************************/ 00049 00050 BOOL WINAPI ImmDisableIME(DWORD dwThreadId) 00051 { 00052 #ifdef LATER // hiro 00053 if (dwThreadId == -1) { 00054 // Unload all IMEs 00055 RtlEnterCriticalSection(&gcsImeDpi); 00056 while (gpImeDpi) { 00057 PIMEDPI pImeDpi = gpImeDpi; 00058 gpImeDpi = gpImeDpi->pNext; 00059 UnloadIME(pImeDpi, TRUE); 00060 ImmLocalFree(pImeDpi); 00061 } 00062 RtlLeaveCriticalSection(&gcsImeDpi); 00063 } 00064 #endif 00065 return (BOOL)NtUserDisableThreadIme(dwThreadId); 00066 } 00067 00068 /**************************************************************************\ 00069 * ImmIsUIMessageA 00070 * 00071 * Filter messages needed for IME window. 00072 * 00073 * 03-Jan-1996 wkwok Created 00074 \**************************************************************************/ 00075 00076 BOOL WINAPI ImmIsUIMessageA( 00077 HWND hIMEWnd, 00078 UINT message, 00079 WPARAM wParam, 00080 LPARAM lParam) 00081 { 00082 return ImmIsUIMessageWorker(hIMEWnd, message, wParam, lParam, TRUE); 00083 } 00084 00085 00086 /**************************************************************************\ 00087 * ImmIsUIMessageW 00088 * 00089 * Filter messages needed for IME window. 00090 * 00091 * 29-Feb-1996 wkwok Created 00092 \**************************************************************************/ 00093 00094 BOOL WINAPI ImmIsUIMessageW( 00095 HWND hIMEWnd, 00096 UINT message, 00097 WPARAM wParam, 00098 LPARAM lParam) 00099 { 00100 return ImmIsUIMessageWorker(hIMEWnd, message, wParam, lParam, FALSE); 00101 } 00102 00103 00104 /**************************************************************************\ 00105 * ImmIsUIMessageWorker 00106 * 00107 * Worker function of ImmIsUIMessageA/ImmIsUIMessageW. 00108 * 00109 * Return: True if message is processed by IME UI. 00110 * False otherwise. 00111 * 00112 * 29-Feb-1996 wkwok Created 00113 \**************************************************************************/ 00114 00115 BOOL ImmIsUIMessageWorker( 00116 HWND hIMEWnd, 00117 UINT message, 00118 WPARAM wParam, 00119 LPARAM lParam, 00120 BOOL fAnsi) 00121 { 00122 D(DbgPrint("ImmIsUIMessageWorker(wnd[%08X], msg[%04X], wp[%08X], lp[%08X], Ansi[%d]\n", 00123 hIMEWnd, message, wParam, lParam, fAnsi)); 00124 00125 switch (message) { 00126 case WM_IME_STARTCOMPOSITION: 00127 case WM_IME_ENDCOMPOSITION: 00128 case WM_IME_COMPOSITION: 00129 case WM_IME_SETCONTEXT: 00130 case WM_IME_COMPOSITIONFULL: 00131 case WM_IME_SELECT: 00132 case WM_IME_NOTIFY: 00133 case WM_IME_SYSTEM: 00134 00135 if (!hIMEWnd) 00136 return TRUE; 00137 00138 #if DBG 00139 if (!IsWindow(hIMEWnd)) { 00140 RIPMSG1(RIP_WARNING, 00141 "ImmIsUIMessage: Invalid window handle %x", hIMEWnd); 00142 return FALSE; 00143 } 00144 #endif 00145 00146 if (fAnsi) { 00147 SendMessageA(hIMEWnd, message, wParam, lParam); 00148 } 00149 else { 00150 SendMessageW(hIMEWnd, message, wParam, lParam); 00151 } 00152 00153 return TRUE; 00154 00155 default: 00156 break; 00157 } 00158 00159 return FALSE; 00160 } 00161 00162 00163 /**************************************************************************\ 00164 * ImmGenerateMessage 00165 * 00166 * Sends message(s) that are stored in hMsgBuf of hImc to hWnd of hImc. 00167 * 00168 * 29-Feb-1996 wkwok Created 00169 \**************************************************************************/ 00170 00171 BOOL WINAPI ImmGenerateMessage( 00172 HIMC hImc) 00173 { 00174 PCLIENTIMC pClientImc; 00175 PINPUTCONTEXT pInputContext; 00176 PTRANSMSG pTransMsg; 00177 INT iNum; 00178 INT i; 00179 BOOL fUnicodeImc; 00180 00181 if (GetInputContextThread(hImc) != GetCurrentThreadId()) { 00182 RIPMSG1(RIP_WARNING, 00183 "ImmGenerateMessage: Invalid input context access %lx.", hImc); 00184 return FALSE; 00185 } 00186 00187 pClientImc = ImmLockClientImc(hImc); 00188 if (pClientImc == NULL) 00189 return FALSE; 00190 00191 fUnicodeImc = TestICF(pClientImc, IMCF_UNICODE); 00192 00193 ImmUnlockClientImc(pClientImc); 00194 00195 pInputContext = ImmLockIMC(hImc); 00196 if (!pInputContext) { 00197 RIPMSG1(RIP_WARNING, "ImmGenerateMessage: Lock hImc %lx failed.", hImc); 00198 return FALSE; 00199 } 00200 00201 iNum = (int)pInputContext->dwNumMsgBuf; 00202 00203 if (iNum && (pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf))) { 00204 PTRANSMSG pTransMsgBuf, pTransMsgTemp; 00205 00206 pTransMsgBuf = (PTRANSMSG)ImmLocalAlloc(0, iNum * sizeof(TRANSMSG)); 00207 00208 if (pTransMsgBuf != NULL) { 00209 00210 RtlCopyMemory(pTransMsgBuf, pTransMsg, iNum * sizeof(TRANSMSG)); 00211 00212 if (GetClientInfo()->dwExpWinVer < VER40) { 00213 /* 00214 * translate messages for those applications that expect 00215 * old style IME messages. 00216 */ 00217 DWORD dwLangId; 00218 dwLangId = PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())); 00219 if ( (dwLangId == LANG_KOREAN && TransGetLevel(pInputContext->hWnd) == 3) || 00220 (dwLangId == LANG_JAPANESE) ) { 00221 iNum = WINNLSTranslateMessage(iNum, 00222 pTransMsgBuf, 00223 hImc, 00224 !fUnicodeImc, 00225 dwLangId ); 00226 } 00227 } 00228 00229 pTransMsgTemp = pTransMsgBuf; 00230 00231 for (i = 0; i < iNum; i++) { 00232 if (fUnicodeImc) { 00233 SendMessageW( pInputContext->hWnd, 00234 pTransMsgTemp->message, 00235 pTransMsgTemp->wParam, 00236 pTransMsgTemp->lParam ); 00237 } else { 00238 SendMessageW( pInputContext->hWnd, 00239 pTransMsgTemp->message, 00240 pTransMsgTemp->wParam, 00241 pTransMsgTemp->lParam ); 00242 } 00243 pTransMsgTemp++; 00244 } 00245 00246 ImmLocalFree(pTransMsgBuf); 00247 } 00248 00249 ImmUnlockIMCC(pInputContext->hMsgBuf); 00250 } 00251 00252 /* 00253 * We should not reallocate the message buffer 00254 */ 00255 pInputContext->dwNumMsgBuf = 0L; 00256 00257 ImmUnlockIMC(hImc); 00258 00259 return TRUE; 00260 } 00261 00262 00263 /**************************************************************************\ 00264 * ImmGetVirtualKey 00265 * 00266 * Gets the actual virtual key which is preprocessed by an IME. 00267 * 00268 * 03-Jan-1996 wkwok Created 00269 \**************************************************************************/ 00270 00271 UINT WINAPI ImmGetVirtualKey( 00272 HWND hWnd) 00273 { 00274 HIMC hImc; 00275 PINPUTCONTEXT pInputContext; 00276 UINT uVirtKey; 00277 00278 hImc = ImmGetContext(hWnd); 00279 00280 pInputContext = ImmLockIMC(hImc); 00281 if (!pInputContext) { 00282 RIPMSG1(RIP_WARNING, "ImmGetVirtualKey: lock IMC %x failure", hImc); 00283 return (VK_PROCESSKEY); 00284 } 00285 00286 if (pInputContext->fChgMsg) { 00287 uVirtKey = pInputContext->uSavedVKey; 00288 } else { 00289 uVirtKey = VK_PROCESSKEY; 00290 } 00291 00292 ImmUnlockIMC(hImc); 00293 return (uVirtKey); 00294 } 00295 00296 00297 /**************************************************************************\ 00298 * ImmLockIMC 00299 * 00300 * 03-Jan-1996 wkwok Created 00301 \**************************************************************************/ 00302 00303 PINPUTCONTEXT WINAPI InternalImmLockIMC( 00304 HIMC hImc, 00305 BOOL fCanCallImeSelect) 00306 { 00307 PCLIENTIMC pClientImc; 00308 PINPUTCONTEXT pInputContext; 00309 DWORD dwImcThreadId; 00310 00311 if ((pClientImc = ImmLockClientImc(hImc)) == NULL) 00312 return NULL; 00313 00314 EnterImcCrit(pClientImc); 00315 00316 if (pClientImc->hInputContext == NULL) { 00317 /* 00318 * If the owner thread of this hImc does not have 00319 * default IME window, don't bother to create the 00320 * INPUTCONTEXT. It could happen when some other 00321 * thread which call ImmGetContext() to retrieve 00322 * the associate hImc before the default IME window 00323 * is created. 00324 */ 00325 if ((HWND)NtUserQueryInputContext(hImc, 00326 InputContextDefaultImeWindow) == NULL) { 00327 LeaveImcCrit(pClientImc); 00328 ImmUnlockClientImc(pClientImc); 00329 return NULL; 00330 } 00331 00332 /* 00333 * This is a delay creation of INPUTCONTEXT structure. Create 00334 * it now for this hImc. 00335 */ 00336 pClientImc->hInputContext = LocalAlloc(LHND, sizeof(INPUTCONTEXT)); 00337 00338 if (pClientImc->hInputContext == NULL) { 00339 LeaveImcCrit(pClientImc); 00340 ImmUnlockClientImc(pClientImc); 00341 return NULL; 00342 } 00343 00344 dwImcThreadId = (DWORD)NtUserQueryInputContext(hImc, InputContextThread); 00345 00346 if (!CreateInputContext(hImc, GetKeyboardLayout(dwImcThreadId), fCanCallImeSelect)) { 00347 RIPMSG0(RIP_WARNING, "ImmLockIMC: CreateInputContext failed"); 00348 LocalFree(pClientImc->hInputContext); 00349 pClientImc->hInputContext = NULL; 00350 LeaveImcCrit(pClientImc); 00351 ImmUnlockClientImc(pClientImc); 00352 return NULL; 00353 } 00354 } 00355 00356 LeaveImcCrit(pClientImc); 00357 00358 pInputContext = (PINPUTCONTEXT)LocalLock(pClientImc->hInputContext); 00359 00360 /* 00361 * Increment lock count so that the ImmUnlockClientImc() won't 00362 * free up the pClientImc->hInputContext. 00363 */ 00364 InterlockedIncrement(&pClientImc->cLockObj); 00365 00366 ImmUnlockClientImc(pClientImc); 00367 00368 return pInputContext; 00369 } 00370 00371 PINPUTCONTEXT WINAPI ImmLockIMC( 00372 HIMC hImc) 00373 { 00374 return InternalImmLockIMC(hImc, TRUE); 00375 } 00376 00377 /**************************************************************************\ 00378 * ImmUnlockIMC 00379 * 00380 * 03-Jan-1996 wkwok Created 00381 \**************************************************************************/ 00382 00383 BOOL WINAPI ImmUnlockIMC( 00384 HIMC hImc) 00385 { 00386 PCLIENTIMC pClientImc; 00387 00388 if ((pClientImc = ImmLockClientImc(hImc)) == NULL) 00389 return FALSE; 00390 00391 if (pClientImc->hInputContext != NULL) 00392 LocalUnlock(pClientImc->hInputContext); 00393 00394 /* 00395 * Decrement lock count so that the ImmUnlockClientImc() can 00396 * free up the pClientImc->hInputContext if required. 00397 */ 00398 InterlockedDecrement(&pClientImc->cLockObj); 00399 00400 ImmUnlockClientImc(pClientImc); 00401 00402 return TRUE; 00403 } 00404 00405 00406 /**************************************************************************\ 00407 * ImmGetIMCLockCount 00408 * 00409 * 03-Jan-1996 wkwok Created 00410 \**************************************************************************/ 00411 00412 DWORD WINAPI ImmGetIMCLockCount( 00413 HIMC hImc) 00414 { 00415 PCLIENTIMC pClientImc; 00416 DWORD dwRet = 0; 00417 00418 if ((pClientImc = ImmLockClientImc(hImc)) == NULL) 00419 return dwRet; 00420 00421 if (pClientImc->hInputContext != NULL) 00422 dwRet = (DWORD)(LocalFlags(pClientImc->hInputContext) & LMEM_LOCKCOUNT); 00423 00424 ImmUnlockClientImc(pClientImc); 00425 00426 return dwRet; 00427 } 00428 00429 00430 /**************************************************************************\ 00431 * ImmCreateIMCC 00432 * 00433 * 03-Jan-1996 wkwok Created 00434 \**************************************************************************/ 00435 00436 HIMCC WINAPI ImmCreateIMCC( 00437 DWORD dwSize) 00438 { 00439 // At least size should be DWORD. 00440 if (dwSize < sizeof(DWORD)) { 00441 dwSize = sizeof(DWORD); 00442 } 00443 00444 return (HIMCC)LocalAlloc(LHND, dwSize); 00445 } 00446 00447 00448 /**************************************************************************\ 00449 * ImmDestroyIMCC 00450 * 00451 * 03-Jan-1996 wkwok Created 00452 \**************************************************************************/ 00453 00454 HIMCC WINAPI ImmDestroyIMCC( 00455 HIMCC hIMCC) 00456 { 00457 if (hIMCC == NULL) { 00458 return NULL; 00459 } 00460 00461 return (HIMCC)LocalFree(hIMCC); 00462 } 00463 00464 00465 /**************************************************************************\ 00466 * ImmLockIMCC 00467 * 00468 * 03-Jan-1996 wkwok Created 00469 \**************************************************************************/ 00470 00471 LPVOID WINAPI ImmLockIMCC( 00472 HIMCC hIMCC) 00473 { 00474 if (hIMCC == NULL) { 00475 return NULL; 00476 } 00477 00478 return LocalLock(hIMCC); 00479 } 00480 00481 00482 /**************************************************************************\ 00483 * ImmUnlockIMCC 00484 * 00485 * 03-Jan-1996 wkwok Created 00486 \**************************************************************************/ 00487 00488 BOOL WINAPI ImmUnlockIMCC( 00489 HIMCC hIMCC) 00490 { 00491 if (hIMCC == NULL) { 00492 return FALSE; 00493 } 00494 00495 return LocalUnlock(hIMCC); 00496 } 00497 00498 00499 /**************************************************************************\ 00500 * ImmGetIMCCLockCount 00501 * 00502 * 03-Jan-1996 wkwok Created 00503 \**************************************************************************/ 00504 00505 DWORD WINAPI ImmGetIMCCLockCount( 00506 HIMCC hIMCC) 00507 { 00508 if (hIMCC == NULL) { 00509 return 0; 00510 } 00511 00512 return (DWORD)(LocalFlags(hIMCC) & LMEM_LOCKCOUNT); 00513 } 00514 00515 00516 /**************************************************************************\ 00517 * ImmReSizeIMCC 00518 * 00519 * 03-Jan-1996 wkwok Created 00520 \**************************************************************************/ 00521 00522 HIMCC WINAPI ImmReSizeIMCC( 00523 HIMCC hIMCC, 00524 DWORD dwSize) 00525 { 00526 if (hIMCC == NULL) { 00527 return NULL; 00528 } 00529 00530 return (HIMCC)LocalReAlloc(hIMCC, dwSize, LHND); 00531 } 00532 00533 00534 /**************************************************************************\ 00535 * ImmGetIMCCSize 00536 * 00537 * 03-Jan-1996 wkwok Created 00538 \**************************************************************************/ 00539 00540 DWORD WINAPI ImmGetIMCCSize( 00541 HIMCC hIMCC) 00542 { 00543 if (hIMCC == NULL) { 00544 return 0; 00545 } 00546 00547 return (DWORD)LocalSize(hIMCC); 00548 } 00549 00550 00551 /**************************************************************************\ 00552 * ImmLocalAlloc 00553 * 00554 * 18-Jun-1996 wkwok Created 00555 \**************************************************************************/ 00556 00557 LPVOID ImmLocalAlloc( 00558 DWORD uFlag, 00559 DWORD uBytes) 00560 { 00561 if (pImmHeap == NULL) { 00562 pImmHeap = RtlProcessHeap(); 00563 if (pImmHeap == NULL) { 00564 RIPMSG0(RIP_WARNING, "ImmLocalAlloc: NULL pImmHeap!"); 00565 return NULL; 00566 } 00567 } 00568 00569 return HeapAlloc(pImmHeap, uFlag, uBytes); 00570 } 00571 00572 00573 /***************************************************************************\ 00574 * PtiCurrent 00575 * 00576 * Returns the THREADINFO structure for the current thread. 00577 * LATER: Get DLL_THREAD_ATTACH initialization working right and we won't 00578 * need this connect code. 00579 * 00580 * History: 00581 * 10-28-90 DavidPe Created. 00582 * 02-21-96 wkwok Copied from USER32.DLL 00583 \***************************************************************************/ 00584 00585 PTHREADINFO PtiCurrent(VOID) 00586 { 00587 ConnectIfNecessary(); 00588 return (PTHREADINFO)NtCurrentTebShared()->Win32ThreadInfo; 00589 } 00590 00591 00592 /**************************************************************************\ 00593 * TestInputContextProcess 00594 * 00595 * 02-21-96 wkwok Created 00596 \**************************************************************************/ 00597 00598 BOOL TestInputContextProcess( 00599 PIMC pImc) 00600 { 00601 /* 00602 * If the threads are the same, don't bother going to the kernel 00603 * to get the input context's process id. 00604 */ 00605 if (GETPTI(pImc) == PtiCurrent()) { 00606 return TRUE; 00607 } 00608 00609 return (GetInputContextProcess(PtoH(pImc)) == GETPROCESSID()); 00610 } 00611 00612 /**************************************************************************\ 00613 * TestWindowProcess 00614 * 00615 * 11-14-94 JimA Created. 00616 * 02-29-96 wkwok Copied from USER32.DLL 00617 \**************************************************************************/ 00618 00619 BOOL TestWindowProcess( 00620 PWND pwnd) 00621 { 00622 /* 00623 * If the threads are the same, don't bother going to the kernel 00624 * to get the window's process id. 00625 */ 00626 if (GETPTI(pwnd) == PtiCurrent()) { 00627 return TRUE; 00628 } 00629 00630 return (GetWindowProcess(HW(pwnd)) == GETPROCESSID()); 00631 } 00632 00633 00634 /**************************************************************************\ 00635 * GetKeyboardLayoutCP 00636 * 00637 * 12-Mar-1996 wkwok Created 00638 \**************************************************************************/ 00639 00640 static LCID CachedLCID = 0; 00641 static UINT CachedCP = CP_ACP; 00642 00643 UINT GetKeyboardLayoutCP( 00644 HKL hKL) 00645 { 00646 #define LOCALE_CPDATA 7 00647 WCHAR wszCodePage[LOCALE_CPDATA]; 00648 LCID lcid; 00649 00650 lcid = MAKELCID(LOWORD(HandleToUlong(hKL)), SORT_DEFAULT); 00651 00652 if (lcid == CachedLCID) 00653 return CachedCP; 00654 00655 if (!GetLocaleInfoW(lcid, LOCALE_IDEFAULTANSICODEPAGE, 00656 wszCodePage, LOCALE_CPDATA)) 00657 return CP_ACP; 00658 00659 CachedLCID = lcid; 00660 CachedCP = (UINT)wcstol(wszCodePage, NULL, 10); 00661 00662 return CachedCP; 00663 } 00664 00665 00666 /**************************************************************************\ 00667 * GetKeyboardLayoutCP 00668 * 00669 * 12-Mar-1996 wkwok Created 00670 \**************************************************************************/ 00671 00672 UINT GetThreadKeyboardLayoutCP( 00673 DWORD dwThreadId) 00674 { 00675 HKL hKL; 00676 00677 hKL = GetKeyboardLayout(dwThreadId); 00678 00679 return GetKeyboardLayoutCP(hKL); 00680 } 00681 00682 00683 /**************************************************************************\ 00684 * ImmLockClientImc 00685 * 00686 * 13-Mar-1996 wkwok Created 00687 \**************************************************************************/ 00688 00689 PCLIENTIMC WINAPI ImmLockClientImc( 00690 HIMC hImc) 00691 { 00692 PIMC pImc; 00693 PCLIENTIMC pClientImc; 00694 00695 if (hImc == NULL_HIMC) 00696 return NULL; 00697 00698 pImc = HMValidateHandle((HANDLE)hImc, TYPE_INPUTCONTEXT); 00699 00700 /* 00701 * Cannot access input context from other process. 00702 */ 00703 if (pImc == NULL || !TestInputContextProcess(pImc)) 00704 return NULL; 00705 00706 pClientImc = (PCLIENTIMC)pImc->dwClientImcData; 00707 00708 if (pClientImc == NULL) { 00709 /* 00710 * We delay the creation of client side per-thread default Imc. 00711 * Now, this is the time to create it. 00712 */ 00713 pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC)); 00714 if (pClientImc == NULL) 00715 return NULL; 00716 00717 InitImcCrit(pClientImc); 00718 pClientImc->dwImeCompatFlags = (DWORD)NtUserGetThreadState(UserThreadStateImeCompatFlags); 00719 00720 /* 00721 * Update the kernel side input context. 00722 */ 00723 if (!NtUserUpdateInputContext(hImc, 00724 UpdateClientInputContext, (ULONG_PTR)pClientImc)) { 00725 ImmLocalFree(pClientImc); 00726 return NULL; 00727 } 00728 00729 /* 00730 * Marks with default input context signature. 00731 */ 00732 SetICF(pClientImc, IMCF_DEFAULTIMC); 00733 } 00734 else if (TestICF(pClientImc, IMCF_INDESTROY)) { 00735 /* 00736 * Cannot access destroyed input context. 00737 */ 00738 return NULL; 00739 } 00740 00741 InterlockedIncrement(&pClientImc->cLockObj); 00742 00743 return pClientImc; 00744 } 00745 00746 00747 VOID WINAPI ImmUnlockClientImc( 00748 PCLIENTIMC pClientImc) 00749 { 00750 if (InterlockedDecrement(&pClientImc->cLockObj) == 0) { 00751 if (TestICF(pClientImc, IMCF_INDESTROY)) { 00752 if (pClientImc->hInputContext != NULL) 00753 LocalFree(pClientImc->hInputContext); 00754 00755 DeleteImcCrit(pClientImc); 00756 ImmLocalFree(pClientImc); 00757 } 00758 } 00759 00760 return; 00761 } 00762 00763 /**************************************************************************\ 00764 * ImmGetImeDpi 00765 * 00766 * 08-Jan-1996 wkwok Created 00767 \**************************************************************************/ 00768 00769 PIMEDPI WINAPI ImmGetImeDpi( 00770 HKL hKL) 00771 { 00772 PIMEDPI pImeDpi; 00773 00774 RtlEnterCriticalSection(&gcsImeDpi); 00775 00776 pImeDpi = gpImeDpi; 00777 00778 while (pImeDpi != NULL && pImeDpi->hKL != hKL) 00779 pImeDpi = pImeDpi->pNext; 00780 00781 RtlLeaveCriticalSection(&gcsImeDpi); 00782 00783 return (PIMEDPI)pImeDpi; 00784 } 00785 00786 00787 /**************************************************************************\ 00788 * ImmLockImeDpi 00789 * 00790 * 08-Jan-1996 wkwok Created 00791 \**************************************************************************/ 00792 00793 PIMEDPI WINAPI ImmLockImeDpi( 00794 HKL hKL) 00795 { 00796 PIMEDPI pImeDpi; 00797 00798 RtlEnterCriticalSection(&gcsImeDpi); 00799 00800 pImeDpi = gpImeDpi; 00801 00802 while (pImeDpi != NULL && pImeDpi->hKL != hKL) 00803 pImeDpi = pImeDpi->pNext; 00804 00805 if (pImeDpi != NULL) { 00806 if (pImeDpi->dwFlag & IMEDPI_UNLOADED) 00807 pImeDpi = NULL; 00808 else 00809 pImeDpi->cLock++; 00810 } 00811 00812 RtlLeaveCriticalSection(&gcsImeDpi); 00813 00814 return (PIMEDPI)pImeDpi; 00815 } 00816 00817 00818 /**************************************************************************\ 00819 * ImmUnlockImeDpi 00820 * 00821 * 03-Jan-1996 wkwok Created 00822 \**************************************************************************/ 00823 00824 VOID WINAPI ImmUnlockImeDpi( 00825 PIMEDPI pImeDpi) 00826 { 00827 PIMEDPI pImeDpiT; 00828 00829 if (pImeDpi == NULL) 00830 return; 00831 00832 RtlEnterCriticalSection(&gcsImeDpi); 00833 00834 if (--pImeDpi->cLock == 0) { 00835 00836 if ((pImeDpi->dwFlag & IMEDPI_UNLOADED) || 00837 ((pImeDpi->dwFlag & IMEDPI_UNLOCKUNLOAD) && 00838 (pImeDpi->ImeInfo.fdwProperty & IME_PROP_END_UNLOAD))) 00839 { 00840 /* 00841 * Unlink it. 00842 */ 00843 if (gpImeDpi == pImeDpi) { 00844 gpImeDpi = pImeDpi->pNext; 00845 } 00846 else { 00847 pImeDpiT = gpImeDpi; 00848 00849 while (pImeDpiT != NULL && pImeDpiT->pNext != pImeDpi) 00850 pImeDpiT = pImeDpiT->pNext; 00851 00852 if (pImeDpiT != NULL) 00853 pImeDpiT->pNext = pImeDpi->pNext; 00854 } 00855 00856 /* 00857 * Unload the IME DLL. 00858 */ 00859 UnloadIME(pImeDpi, TRUE); 00860 ImmLocalFree(pImeDpi); 00861 } 00862 } 00863 00864 RtlLeaveCriticalSection(&gcsImeDpi); 00865 00866 return; 00867 } 00868 00869 00870 /**************************************************************************\ 00871 * ImmGetImeInfoEx 00872 * 00873 * 03-Jan-1996 wkwok Created 00874 \**************************************************************************/ 00875 00876 BOOL WINAPI ImmGetImeInfoEx( 00877 PIMEINFOEX piiex, 00878 IMEINFOEXCLASS SearchType, 00879 PVOID pvSearchKey) 00880 { 00881 ImmAssert(piiex != NULL && pvSearchKey != NULL); 00882 00883 switch (SearchType) { 00884 case ImeInfoExKeyboardLayout: 00885 piiex->hkl = *((HKL *)pvSearchKey); 00886 /* 00887 * Quick return for non-IME based keyboard layout 00888 */ 00889 if (!IS_IME_KBDLAYOUT(piiex->hkl)) 00890 return FALSE; 00891 break; 00892 00893 case ImeInfoExImeFileName: 00894 wcscpy(piiex->wszImeFile, (PWSTR)pvSearchKey); 00895 break; 00896 00897 default: 00898 return FALSE; 00899 } 00900 00901 return NtUserGetImeInfoEx(piiex, SearchType); 00902 } 00903 00904 /**************************************************************************\ 00905 * ImmGetAppCompatFlags 00906 * 00907 * private function 00908 * returns Win95 compatible IME Compatibility flags 00909 * 00910 * 02-July-1996 takaok Created 00911 \**************************************************************************/ 00912 DWORD ImmGetAppCompatFlags( HIMC hImc ) 00913 { 00914 PCLIENTIMC pClientImc; 00915 DWORD dwImeCompat = 0; 00916 00917 pClientImc = ImmLockClientImc( hImc ); 00918 if ( pClientImc != NULL ) { 00919 dwImeCompat = pClientImc->dwImeCompatFlags; 00920 ImmUnlockClientImc( pClientImc ); 00921 } 00922 return dwImeCompat; 00923 } 00924 00925 /**************************************************************************\ 00926 * ImmPtInRect 00927 * 00928 * private function 00929 * 00930 * 02-July-1997 hiroyama Created 00931 \**************************************************************************/ 00932 00933 BOOL ImmPtInRect( 00934 int left, 00935 int top, 00936 int width, 00937 int height, 00938 LPPOINT lppt) 00939 { 00940 return (lppt->x >= left && lppt->x < (left + width) && 00941 lppt->y >= top && lppt->y < (top + height)); 00942 } 00943 00944 00945 /**************************************************************************\ 00946 * ImmSystemHandler 00947 * 00948 * private function 00949 * 00950 * IMM bulk helper to handle WM_IME_SYSTEM message 00951 * 00952 * 02-July-1997 hiroyama Created 00953 \**************************************************************************/ 00954 00955 LRESULT ImmSystemHandler( 00956 HIMC hImc, 00957 WPARAM wParam, 00958 LPARAM lParam) 00959 { 00960 LRESULT lRet = 0; 00961 00962 switch (wParam) { 00963 case IMS_SENDNOTIFICATION: 00964 ImmSendNotification((BOOL)lParam); 00965 break; 00966 case IMS_FINALIZE_COMPSTR: 00967 ImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0); 00968 break; 00969 } 00970 00971 return lRet; 00972 }

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