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

imectl.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: imectl.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * IME Window Handling Routines 00007 * 00008 * History: 00009 * 20-Dec-1995 wkwok 00010 \**************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 #include <intlshar.h> 00016 00017 #define LATE_CREATEUI 1 00018 00019 CONST WCHAR szIndicDLL[] = L"indicdll.dll"; 00020 00021 FARPROC gpfnGetIMEMenuItemData = NULL; 00022 BOOL IMEIndicatorGetMenuIDData(PUINT puMenuID, PDWORD pdwData); 00023 00024 /* 00025 * Local Routines. 00026 */ 00027 LONG ImeWndCreateHandler(PIMEUI, LPCREATESTRUCT); 00028 void ImeWndDestroyHandler(PIMEUI); 00029 LRESULT ImeSystemHandler(PIMEUI, UINT, WPARAM, LPARAM); 00030 LONG ImeSelectHandler(PIMEUI, UINT, WPARAM, LPARAM); 00031 LRESULT ImeControlHandler(PIMEUI, UINT, WPARAM, LPARAM, BOOL); 00032 LRESULT ImeSetContextHandler(PIMEUI, UINT, WPARAM, LPARAM); 00033 LRESULT ImeNotifyHandler(PIMEUI, UINT, WPARAM, LPARAM); 00034 HWND CreateIMEUI(PIMEUI, HKL); 00035 VOID DestroyIMEUI(PIMEUI); 00036 LRESULT SendMessageToUI(PIMEUI, UINT, WPARAM, LPARAM, BOOL); 00037 VOID SendOpenStatusNotify(PIMEUI, HWND, BOOL); 00038 VOID ImeSetImc(PIMEUI, HIMC); 00039 VOID FocusSetIMCContext(HWND, BOOL); 00040 BOOL ImeBroadCastMsg(PIMEUI, UINT, WPARAM, LPARAM); 00041 VOID ImeMarkUsedContext(HWND, HIMC); 00042 BOOL ImeIsUsableContext(HWND, HIMC); 00043 BOOL GetIMEShowStatus(void); 00044 LRESULT ImeCopyDataHandler(WPARAM, LPARAM); 00045 00046 /* 00047 * Common macros for IME UI, HKL and IMC handlings 00048 */ 00049 #define GETHKL(pimeui) (pimeui->hKL) 00050 #define SETHKL(pimeui, hkl) (pimeui->hKL=(hkl)) 00051 #define GETIMC(pimeui) (pimeui->hIMC) 00052 #define SETIMC(pimeui, himc) (ImeSetImc(pimeui, himc)) 00053 #define GETUI(pimeui) (pimeui->hwndUI) 00054 #define SETUI(pimeui, hwndui) (pimeui->hwndUI=(hwndui)) 00055 00056 LOOKASIDE ImeUILookaside; 00057 00058 /***************************************************************************\ 00059 * NtUserBroadcastImeShowStatusChange(), NtUserCheckImeShowStatusInThread() 00060 * 00061 * Stub for kernel mode routines 00062 * 00063 \***************************************************************************/ 00064 00065 _inline void NtUserBroadcastImeShowStatusChange(HWND hwndDefIme, BOOL fShow) 00066 { 00067 NtUserCallHwndParamLock(hwndDefIme, fShow, SFI_XXXBROADCASTIMESHOWSTATUSCHANGE); 00068 } 00069 00070 _inline void NtUserCheckImeShowStatusInThread(HWND hwndDefIme) 00071 { 00072 NtUserCallHwndLock(hwndDefIme, SFI_XXXCHECKIMESHOWSTATUSINTHREAD); 00073 } 00074 00075 /***************************************************************************\ 00076 * ImeWndProc 00077 * 00078 * WndProc for IME class 00079 * 00080 * History: 00081 \***************************************************************************/ 00082 00083 LRESULT APIENTRY ImeWndProcWorker( 00084 PWND pwnd, 00085 UINT message, 00086 WPARAM wParam, 00087 LPARAM lParam, 00088 DWORD fAnsi) 00089 { 00090 HWND hwnd = HWq(pwnd); 00091 PIMEUI pimeui; 00092 static BOOL fInit = TRUE; 00093 00094 CheckLock(pwnd); 00095 00096 VALIDATECLASSANDSIZE(pwnd, FNID_IME); 00097 INITCONTROLLOOKASIDE(&ImeUILookaside, IMEUI, spwnd, 8); 00098 00099 /* 00100 * If the control is not interested in this message, 00101 * pass it to DefWindowProc. 00102 */ 00103 if (!FWINDOWMSG(message, FNID_IME)) 00104 return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi); 00105 00106 /* 00107 * Get the pimeui for the given window now since we will use it a lot in 00108 * various handlers. This was stored using SetWindowLong(hwnd,0,pimeui) when 00109 * we initially created the IME control. 00110 */ 00111 pimeui = ((PIMEWND)pwnd)->pimeui; 00112 00113 if (pimeui == NULL) { 00114 /* 00115 * Further processing not needed 00116 */ 00117 RIPMSG0(RIP_WARNING, "ImeWndProcWorker: pimeui == NULL\n"); 00118 return 0L; 00119 } 00120 00121 /* 00122 * This is necessary to avoid recursion call from IME UI. 00123 */ 00124 UserAssert(pimeui->nCntInIMEProc >= 0); 00125 00126 if (pimeui->nCntInIMEProc > 0) { 00127 TAGMSG5(DBGTAG_IMM, "ImeWndProcWorker: Recursive for pwnd=%08p, msg=%08x, wp=%08x, lp=%08x, fAnsi=%d\n", 00128 pwnd, message, wParam, lParam, fAnsi); 00129 switch (message) { 00130 case WM_IME_SYSTEM: 00131 switch (wParam) { 00132 case IMS_ISACTIVATED: 00133 case IMS_SETOPENSTATUS: 00134 // case IMS_SETCONVERSIONSTATUS: 00135 case IMS_SETSOFTKBDONOFF: 00136 /* 00137 * Because these will not be pass to UI. 00138 * We can do it. 00139 */ 00140 break; 00141 00142 default: 00143 return 0L; 00144 } 00145 break; 00146 00147 case WM_IME_STARTCOMPOSITION: 00148 case WM_IME_ENDCOMPOSITION: 00149 case WM_IME_COMPOSITION: 00150 case WM_IME_SETCONTEXT: 00151 case WM_IME_NOTIFY: 00152 case WM_IME_CONTROL: 00153 case WM_IME_COMPOSITIONFULL: 00154 case WM_IME_SELECT: 00155 case WM_IME_CHAR: 00156 case WM_IME_REQUEST: 00157 return 0L; 00158 00159 default: 00160 return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi); 00161 } 00162 } 00163 00164 if (TestWF(pwnd, WFINDESTROY) || TestWF(pwnd, WFDESTROYED)) { 00165 switch (message) { 00166 case WM_DESTROY: 00167 case WM_NCDESTROY: 00168 case WM_FINALDESTROY: 00169 break; 00170 default: 00171 RIPMSG1(RIP_WARNING, "ImeWndProcWorker: message %x is sent to destroyed window.", message); 00172 return 0L; 00173 } 00174 } 00175 00176 switch (message) { 00177 case WM_ERASEBKGND: 00178 return (LONG)TRUE; 00179 00180 case WM_PAINT: 00181 break; 00182 00183 case WM_CREATE: 00184 00185 return ImeWndCreateHandler(pimeui, (LPCREATESTRUCT)lParam); 00186 00187 case WM_DESTROY: 00188 /* 00189 * We are destroying the IME window, destroy 00190 * any UI window that it owns. 00191 */ 00192 ImeWndDestroyHandler(pimeui); 00193 break; 00194 00195 case WM_NCDESTROY: 00196 case WM_FINALDESTROY: 00197 if (pimeui) { 00198 Unlock(&pimeui->spwnd); 00199 FreeLookasideEntry(&ImeUILookaside, pimeui); 00200 } 00201 NtUserSetWindowFNID(hwnd, FNID_CLEANEDUP_BIT); 00202 goto CallDWP; 00203 00204 case WM_IME_SYSTEM: 00205 UserAssert(pimeui->spwnd == pwnd); 00206 return ImeSystemHandler(pimeui, message, wParam, lParam); 00207 00208 case WM_IME_SELECT: 00209 return ImeSelectHandler(pimeui, message, wParam, lParam); 00210 00211 case WM_IME_CONTROL: 00212 return ImeControlHandler(pimeui, message, wParam, lParam, fAnsi); 00213 00214 case WM_IME_SETCONTEXT: 00215 return ImeSetContextHandler(pimeui, message, wParam, lParam); 00216 00217 case WM_IME_NOTIFY: 00218 return ImeNotifyHandler(pimeui, message, wParam, lParam); 00219 00220 case WM_IME_REQUEST: 00221 return 0; 00222 00223 case WM_IME_COMPOSITION: 00224 case WM_IME_ENDCOMPOSITION: 00225 case WM_IME_STARTCOMPOSITION: 00226 return SendMessageToUI(pimeui, message, wParam, lParam, fAnsi); 00227 00228 case WM_COPYDATA: 00229 return ImeCopyDataHandler(wParam, lParam); 00230 00231 default: 00232 CallDWP: 00233 return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi); 00234 } 00235 00236 return 0L; 00237 } 00238 00239 00240 LRESULT WINAPI ImeWndProcA( 00241 HWND hwnd, 00242 UINT message, 00243 WPARAM wParam, 00244 LPARAM lParam) 00245 { 00246 PWND pwnd; 00247 00248 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 00249 return (0L); 00250 } 00251 00252 return ImeWndProcWorker(pwnd, message, wParam, lParam, TRUE); 00253 } 00254 00255 00256 LRESULT WINAPI ImeWndProcW( 00257 HWND hwnd, 00258 UINT message, 00259 WPARAM wParam, 00260 LPARAM lParam) 00261 { 00262 PWND pwnd; 00263 00264 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 00265 return (0L); 00266 } 00267 00268 return ImeWndProcWorker(pwnd, message, wParam, lParam, FALSE); 00269 } 00270 00271 00272 LONG ImeWndCreateHandler( 00273 PIMEUI pimeui, 00274 LPCREATESTRUCT lpcs) 00275 { 00276 PWND pwndParent; 00277 HIMC hImc; 00278 PWND pwndIme = pimeui->spwnd; 00279 #if _DBG 00280 static DWORD dwFirstWinlogonThreadId; 00281 #endif 00282 extern BOOL gfLogonProcess; 00283 00284 #if _DBG 00285 /* 00286 * For Winlogon, only the first thread can have IME processing. 00287 */ 00288 if (gfLogonProcess) { 00289 UserAssert(dwFirstWinLogonThreadId == 0); 00290 dwFirstWinlogonThreadId = GetCurrentThreadId(); 00291 } 00292 #endif 00293 00294 if (!TestWF(pwndIme, WFPOPUP) || !TestWF(pwndIme, WFDISABLED)) { 00295 RIPMSG0(RIP_WARNING, "IME window should have WS_POPUP and WS_DISABLE!!"); 00296 return -1L; 00297 } 00298 00299 /* 00300 * Check with parent window, if exists, try to get IMC. 00301 * If this is top level window, wait for first WM_IME_SETCONTEXT. 00302 */ 00303 if ((pwndParent = ValidateHwndNoRip(lpcs->hwndParent)) != NULL) { 00304 hImc = pwndParent->hImc; 00305 if (hImc != NULL_HIMC && ImeIsUsableContext(HWq(pwndIme), hImc)) { 00306 /* 00307 * Store it for later use. 00308 */ 00309 SETIMC(pimeui, hImc); 00310 } 00311 else { 00312 SETIMC(pimeui, NULL_HIMC); 00313 } 00314 } 00315 else { 00316 SETIMC(pimeui, NULL_HIMC); 00317 } 00318 00319 /* 00320 * Initialize status window show state 00321 * The status window is not open yet. 00322 */ 00323 pimeui->fShowStatus = 0; 00324 pimeui->nCntInIMEProc = 0; 00325 pimeui->fActivate = 0; 00326 pimeui->fDestroy = 0; 00327 pimeui->hwndIMC = NULL; 00328 pimeui->hKL = THREAD_HKL(); 00329 pimeui->fCtrlShowStatus = TRUE; 00330 00331 /* 00332 * Load up the IME DLL of current keyboard layout. 00333 */ 00334 fpImmLoadIME(pimeui->hKL); 00335 00336 #ifdef LATE_CREATEUI 00337 SETUI(pimeui, NULL); 00338 #else 00339 SETUI(pimeui, CreateIMEUI(pimeui, pimeui->hKL)); 00340 #endif 00341 00342 return 0L; 00343 } 00344 00345 void ImeWndDestroyHandler( 00346 PIMEUI pimeui) 00347 { 00348 DestroyIMEUI(pimeui); 00349 } 00350 00351 00352 /***************************************************************************\ 00353 * ImeRunHelp 00354 * 00355 * Display Help file (HLP and CHM). 00356 * 00357 * History: 00358 * 27-Oct-98 Hiroyama 00359 \***************************************************************************/ 00360 00361 void ImeRunHelp(LPWSTR wszHelpFile) 00362 { 00363 static const WCHAR wszHelpFileExt[] = L".HLP"; 00364 UINT cchLen = wcslen(wszHelpFile); 00365 00366 if (cchLen > 4 && _wcsicmp(wszHelpFile + cchLen - 4, wszHelpFileExt) == 0) { 00367 #ifdef FYI 00368 WinHelpW(NULL, wszHelpFile, HELP_CONTENTS, 0); 00369 #else 00370 WinHelpW(NULL, wszHelpFile, HELP_FINDER, 0); 00371 #endif 00372 } else { 00373 // 00374 // If it's not HLP file, try to run hh.exe, HTML based 00375 // help tool. It should be in %windir%\hh.exe. 00376 // 00377 static const WCHAR wszHH[] = L"hh.exe "; 00378 WCHAR wszCmdLine[MAX_PATH * 2]; 00379 LPWSTR lpwszCmdLine = wszCmdLine; 00380 DWORD idProcess; 00381 STARTUPINFO StartupInfo; 00382 PROCESS_INFORMATION ProcessInformation; 00383 UINT i; 00384 00385 i = GetSystemWindowsDirectoryW(wszCmdLine, MAX_PATH); 00386 if (i > 0 && i < MAX_PATH - cchLen - (sizeof L'\\' + sizeof wszHH) / sizeof(WCHAR)) { 00387 lpwszCmdLine += i; 00388 if (lpwszCmdLine[-1] != L'\\') { 00389 *lpwszCmdLine++ = L'\\'; 00390 } 00391 } 00392 wcscpy(lpwszCmdLine, wszHH); 00393 wcscat(lpwszCmdLine, wszHelpFile); 00394 00395 /* 00396 * Launch HTML Help. 00397 */ 00398 RtlZeroMemory(&StartupInfo, sizeof(StartupInfo)); 00399 StartupInfo.cb = sizeof(StartupInfo); 00400 StartupInfo.wShowWindow = SW_SHOW; 00401 StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK; 00402 00403 TAGMSG1(DBGTAG_IMM, "Invoking help with '%S'", wszCmdLine); 00404 00405 idProcess = (DWORD)CreateProcessW(NULL, wszCmdLine, 00406 NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, 00407 &ProcessInformation); 00408 00409 if (idProcess) { 00410 WaitForInputIdle(ProcessInformation.hProcess, 10000); 00411 NtClose(ProcessInformation.hProcess); 00412 NtClose(ProcessInformation.hThread); 00413 } 00414 } 00415 } 00416 00417 LRESULT ImeSystemHandler( 00418 PIMEUI pimeui, 00419 UINT message, 00420 WPARAM wParam, 00421 LPARAM lParam) 00422 { 00423 PINPUTCONTEXT pInputContext; 00424 HIMC hImc = GETIMC(pimeui); 00425 LRESULT dwRet = 0L; 00426 00427 UNREFERENCED_PARAMETER(message); 00428 00429 switch (wParam) { 00430 00431 case IMS_SETOPENCLOSE: 00432 if (hImc != NULL_HIMC) 00433 fpImmSetOpenStatus(hImc, (BOOL)lParam); 00434 break; 00435 00436 #ifdef LATER 00437 case IMS_WINDOWPOS: 00438 if (hImc != NULL_HIMC) { 00439 INT i; 00440 BOOL f31Hidden = FALSE: 00441 00442 if ((pInputContext = fpImmLockIMC(hImc)) != NULL) { 00443 f31Hidden = (pInputContext & F31COMPAT_MCWHIDDEN) ? TRUE : FALSE; 00444 fpImmUnlockIMC(hImc); 00445 } 00446 00447 if (IsWindow(pimeui->hwndIMC)) { 00448 if (!f31Hidden) { 00449 } 00450 } 00451 } 00452 #endif 00453 00454 case IMS_ACTIVATECONTEXT: 00455 FocusSetIMCContext((HWND)(lParam), TRUE); 00456 break; 00457 00458 case IMS_DEACTIVATECONTEXT: 00459 FocusSetIMCContext((HWND)(lParam), FALSE); 00460 break; 00461 00462 case IMS_UNLOADTHREADLAYOUT: 00463 return (LONG)(fpImmFreeLayout((DWORD)lParam)); 00464 00465 case IMS_ACTIVATETHREADLAYOUT: 00466 return (LONG)(fpImmActivateLayout((HKL)lParam)); 00467 00468 case IMS_SETCANDIDATEPOS: 00469 if ( (pInputContext = fpImmLockIMC( hImc )) != NULL ) { 00470 LPCANDIDATEFORM lpcaf; 00471 DWORD dwIndex = (DWORD)lParam; 00472 00473 lpcaf = &(pInputContext->cfCandForm[dwIndex]); 00474 fpImmSetCandidateWindow( hImc, lpcaf ); 00475 fpImmUnlockIMC( hImc ); 00476 } 00477 break; 00478 00479 case IMS_SETCOMPOSITIONWINDOW: 00480 if ( (pInputContext = fpImmLockIMC( hImc )) != NULL ) { 00481 LPCOMPOSITIONFORM lpcof; 00482 00483 lpcof = &(pInputContext->cfCompForm); 00484 pInputContext->fdw31Compat |= F31COMPAT_CALLFROMWINNLS; 00485 fpImmSetCompositionWindow( hImc, lpcof); 00486 } 00487 break; 00488 00489 case IMS_SETCOMPOSITIONFONT: 00490 if ( (pInputContext = fpImmLockIMC( hImc )) != NULL ) { 00491 LPLOGFONT lplf; 00492 00493 lplf = &(pInputContext->lfFont.W); 00494 fpImmSetCompositionFont( hImc, lplf ); 00495 } 00496 break; 00497 00498 case IMS_CONFIGUREIME: 00499 fpImmConfigureIMEW( (HKL)lParam, pimeui->hwndIMC, IME_CONFIG_GENERAL, NULL); 00500 break; 00501 00502 case IMS_CHANGE_SHOWSTAT: 00503 // Private message from internat.exe 00504 // Before it reaches here, the registry is already updated. 00505 if (GetIMEShowStatus() == !lParam) { 00506 #if 1 00507 NtUserBroadcastImeShowStatusChange(HW(pimeui->spwnd), !!lParam); 00508 #else 00509 SystemParametersInfo(SPI_SETSHOWIMEUI, lParam, NULL, FALSE); 00510 #endif 00511 } 00512 break; 00513 00514 case IMS_GETCONVERSIONMODE: 00515 { 00516 DWORD dwConv = 0; 00517 DWORD dwTemp; 00518 00519 fpImmGetConversionStatus(hImc, &dwConv, &dwTemp); 00520 return (dwConv); 00521 break; 00522 } 00523 00524 case IMS_SETSOFTKBDONOFF: 00525 fpImmEnumInputContext(0, SyncSoftKbdState, lParam); 00526 break; 00527 00528 case IMS_GETIMEMENU: 00529 // new in NT50 00530 // IMS_GETIEMMENU is used to handle Inter Process GetMenu. 00531 // NOTE: This operation is only intended to internat.exe 00532 return fpImmPutImeMenuItemsIntoMappedFile((HIMC)lParam); 00533 00534 case IMS_IMEHELP: 00535 dwRet = IME_ESC_GETHELPFILENAME; 00536 dwRet = fpImmEscapeW(pimeui->hKL, pimeui->hIMC, IME_ESC_QUERY_SUPPORT, (LPVOID)&dwRet); 00537 if (lParam) { 00538 // try to run WinHelp 00539 WCHAR wszHelpFile[MAX_PATH]; 00540 00541 if (dwRet) { 00542 if (fpImmEscapeW(pimeui->hKL, pimeui->hIMC, IME_ESC_GETHELPFILENAME, 00543 (LPVOID)wszHelpFile)) { 00544 ImeRunHelp(wszHelpFile); 00545 } 00546 } 00547 } 00548 return dwRet; 00549 00550 case IMS_GETCONTEXT: 00551 dwRet = (ULONG_PTR)fpImmGetContext((HWND)lParam); 00552 return dwRet; 00553 00554 case IMS_ENDIMEMENU: 00555 // New in NT5.0: Special support for Internat.exe 00556 if (IsWindow((HWND)lParam)) { 00557 HIMC hImc; 00558 UINT uID; 00559 DWORD dwData; 00560 00561 hImc = fpImmGetContext((HWND)lParam); 00562 00563 if (hImc != NULL) { 00564 // 00565 // Call Indicator to get IME menu data. 00566 // 00567 if (IMEIndicatorGetMenuIDData(&uID, &dwData)) { 00568 fpImmNotifyIME(hImc, NI_IMEMENUSELECTED, uID, dwData); 00569 } 00570 fpImmReleaseContext((HWND)lParam, hImc); 00571 } 00572 } 00573 break; 00574 00575 case IMS_SENDNOTIFICATION: 00576 case IMS_FINALIZE_COMPSTR: 00577 dwRet = fpImmSystemHandler(hImc, wParam, lParam); 00578 break; 00579 00580 default: 00581 break; 00582 } 00583 00584 return dwRet; 00585 } 00586 00587 00588 LONG ImeSelectHandler( 00589 PIMEUI pimeui, 00590 UINT message, 00591 WPARAM wParam, 00592 LPARAM lParam) 00593 { 00594 HWND hwndUI; 00595 00596 /* 00597 * Deliver this message to other IME windows in this thread. 00598 */ 00599 if (pimeui->fDefault) 00600 ImeBroadCastMsg(pimeui, message, wParam, lParam); 00601 00602 /* 00603 * We must re-create UI window of newly selected IME. 00604 */ 00605 if ((BOOL)wParam == TRUE) { 00606 UserAssert(!IsWindow(GETUI(pimeui))); 00607 00608 SETHKL(pimeui, (HKL)lParam); 00609 00610 #ifdef LATE_CREATEUI 00611 if (!pimeui->fActivate) 00612 return 0L; 00613 #endif 00614 00615 hwndUI = CreateIMEUI(pimeui, (HKL)lParam); 00616 00617 SETUI(pimeui, hwndUI); 00618 00619 if (hwndUI != NULL) { 00620 SetWindowLongPtr(hwndUI, IMMGWLP_IMC, (LONG_PTR)GETIMC(pimeui)); 00621 SendMessageToUI(pimeui, message, wParam, lParam, FALSE); 00622 } 00623 00624 if (GetIMEShowStatus() && pimeui->fCtrlShowStatus) { 00625 if (!pimeui->fShowStatus && pimeui->fActivate && 00626 IsWindow(pimeui->hwndIMC)) { 00627 /* 00628 * This must be sent to an application as an app may want 00629 * to hook this message to do its own UI. 00630 */ 00631 SendOpenStatusNotify(pimeui, pimeui->hwndIMC, TRUE); 00632 } 00633 } 00634 } 00635 else { 00636 00637 if (pimeui->fShowStatus && pimeui->fActivate && 00638 IsWindow(pimeui->hwndIMC)) { 00639 /* 00640 * This must be sent to an application as an app may want 00641 * to hook this message to do its own UI. 00642 */ 00643 SendOpenStatusNotify(pimeui, pimeui->hwndIMC, FALSE); 00644 } 00645 00646 SendMessageToUI(pimeui, message, wParam, lParam, FALSE); 00647 00648 DestroyIMEUI(pimeui); 00649 00650 SETHKL(pimeui, (HKL)NULL); 00651 } 00652 00653 return 0L; 00654 } 00655 00656 00657 LRESULT ImeControlHandler( 00658 PIMEUI pimeui, 00659 UINT message, 00660 WPARAM wParam, 00661 LPARAM lParam, 00662 BOOL fAnsi) 00663 { 00664 HIMC hImc; 00665 DWORD dwConversion, dwSentence; 00666 00667 /* 00668 * Do nothing with NULL hImc. 00669 */ 00670 if ((hImc = GETIMC(pimeui)) == NULL_HIMC) 00671 return 0L; 00672 00673 switch (wParam) { 00674 00675 case IMC_OPENSTATUSWINDOW: 00676 if (GetIMEShowStatus() && !pimeui->fShowStatus) { 00677 pimeui->fShowStatus = TRUE; 00678 SendMessageToUI(pimeui, WM_IME_NOTIFY, 00679 IMN_OPENSTATUSWINDOW, 0L, FALSE); 00680 } 00681 pimeui->fCtrlShowStatus = TRUE; 00682 break; 00683 00684 case IMC_CLOSESTATUSWINDOW: 00685 if (GetIMEShowStatus() && pimeui->fShowStatus) { 00686 pimeui->fShowStatus = FALSE; 00687 SendMessageToUI(pimeui, WM_IME_NOTIFY, 00688 IMN_CLOSESTATUSWINDOW, 0L, FALSE); 00689 } 00690 pimeui->fCtrlShowStatus = FALSE; 00691 break; 00692 00693 /* 00694 * ------------------------------------------------ 00695 * IMC_SETCOMPOSITIONFONT, 00696 * IMC_SETCONVERSIONMODE, 00697 * IMC_SETOPENSTATUS 00698 * ------------------------------------------------ 00699 * Don't pass these WM_IME_CONTROLs to UI window. 00700 * Call Imm in order to process these requests instead. 00701 * It makes message flows simpler. 00702 */ 00703 case IMC_SETCOMPOSITIONFONT: 00704 if (fAnsi) { 00705 if (!fpImmSetCompositionFontA(hImc, (LPLOGFONTA)lParam)) 00706 return 1L; 00707 } 00708 else { 00709 if (!fpImmSetCompositionFontW(hImc, (LPLOGFONTW)lParam)) 00710 return 1L; 00711 } 00712 break; 00713 00714 case IMC_SETCONVERSIONMODE: 00715 if (!fpImmGetConversionStatus(hImc, &dwConversion, &dwSentence) || 00716 !fpImmSetConversionStatus(hImc, (DWORD)lParam, dwSentence)) 00717 return 1L; 00718 break; 00719 00720 case IMC_SETSENTENCEMODE: 00721 if (!fpImmGetConversionStatus(hImc, &dwConversion, &dwSentence) || 00722 !fpImmSetConversionStatus(hImc, dwConversion, (DWORD)lParam)) 00723 return 1L; 00724 break; 00725 00726 case IMC_SETOPENSTATUS: 00727 if (!fpImmSetOpenStatus(hImc, (BOOL)lParam)) 00728 return 1L; 00729 break; 00730 00731 case IMC_GETCONVERSIONMODE: 00732 if (!fpImmGetConversionStatus(hImc,&dwConversion, &dwSentence)) 00733 return 1L; 00734 00735 return (LONG)dwConversion; 00736 00737 case IMC_GETSENTENCEMODE: 00738 if (!fpImmGetConversionStatus(hImc,&dwConversion, &dwSentence)) 00739 return 1L; 00740 00741 return (LONG)dwSentence; 00742 00743 case IMC_GETOPENSTATUS: 00744 return (LONG)fpImmGetOpenStatus(hImc); 00745 00746 case IMC_GETCOMPOSITIONFONT: 00747 if (fAnsi) { 00748 if (!fpImmGetCompositionFontA(hImc, (LPLOGFONTA)lParam)) 00749 return 1L; 00750 } 00751 else { 00752 if (!fpImmGetCompositionFontW(hImc, (LPLOGFONTW)lParam)) 00753 return 1L; 00754 } 00755 break; 00756 00757 case IMC_SETCOMPOSITIONWINDOW: 00758 if (!fpImmSetCompositionWindow(hImc, (LPCOMPOSITIONFORM)lParam)) 00759 return 1L; 00760 break; 00761 00762 case IMC_SETSTATUSWINDOWPOS: 00763 { 00764 POINT ppt; 00765 00766 ppt.x = (LONG)((LPPOINTS)&lParam)->x; 00767 ppt.y = (LONG)((LPPOINTS)&lParam)->y; 00768 00769 if (!fpImmSetStatusWindowPos(hImc, &ppt)) 00770 return 1L; 00771 } 00772 break; 00773 00774 case IMC_SETCANDIDATEPOS: 00775 if (!fpImmSetCandidateWindow(hImc, (LPCANDIDATEFORM)lParam)) 00776 return 1; 00777 break; 00778 00779 /* 00780 * Followings are the messsages to be sent to UI. 00781 */ 00782 case IMC_GETCANDIDATEPOS: 00783 case IMC_GETSTATUSWINDOWPOS: 00784 case IMC_GETCOMPOSITIONWINDOW: 00785 case IMC_GETSOFTKBDPOS: 00786 case IMC_SETSOFTKBDPOS: 00787 return SendMessageToUI(pimeui, message, wParam, lParam, fAnsi); 00788 00789 default: 00790 break; 00791 } 00792 00793 return 0L; 00794 } 00795 00796 00797 00798 LRESULT ImeSetContextHandler( 00799 PIMEUI pimeui, 00800 UINT message, 00801 WPARAM wParam, 00802 LPARAM lParam) 00803 { 00804 HWND hwndPrevIMC, hwndFocus; // focus window in the thread 00805 HIMC hFocusImc; // focus window's IMC 00806 LRESULT lRet; 00807 00808 pimeui->fActivate = (BOOL)wParam ? 1 : 0; 00809 hwndPrevIMC = pimeui->hwndIMC; 00810 00811 if (wParam) { 00812 /* 00813 * if it's being activated 00814 */ 00815 #ifdef LATE_CREATEUI 00816 if (!GETUI(pimeui)) 00817 SETUI(pimeui, CreateIMEUI(pimeui, GETHKL(pimeui))); 00818 #endif 00819 00820 /* 00821 * Check if this process a console IME ? 00822 */ 00823 if (gfConIme == UNKNOWN_CONIME) { 00824 gfConIme = (DWORD)NtUserGetThreadState(UserThreadStateIsConImeThread); 00825 if (gfConIme) { 00826 RIPMSG0(RIP_VERBOSE, "ImmSetContextHandler: This thread is console IME.\n"); 00827 UserAssert(pimeui); 00828 // Console IME will never show the IME status window. 00829 pimeui->fCtrlShowStatus = FALSE; 00830 } 00831 } 00832 00833 if (gfConIme) { 00834 /* 00835 * Special handling for Console IME is needed 00836 */ 00837 PWND pwndOwner; 00838 00839 UserAssert(pimeui->spwnd); 00840 pwndOwner = REBASEPWND(pimeui->spwnd, spwndOwner); 00841 if (pwndOwner != NULL) { 00842 /* 00843 * Set current associated hIMC in IMEUI. 00844 */ 00845 SETIMC(pimeui, pwndOwner->hImc); 00846 /* 00847 * Store it to the window memory. 00848 */ 00849 if (GETUI(pimeui) != NULL) 00850 SetWindowLongPtr(GETUI(pimeui), IMMGWLP_IMC, (LONG_PTR)pwndOwner->hImc); 00851 } 00852 00853 hwndFocus = NtUserQueryWindow(HW(pimeui->spwnd), WindowFocusWindow); 00854 hFocusImc = pwndOwner->hImc; 00855 RIPMSG2(RIP_VERBOSE, "CONSOLE IME: hwndFocus = %x, hFocusImc = %x", hwndFocus, hFocusImc); 00856 00857 return SendMessageToUI(pimeui, message, wParam, lParam, FALSE); 00858 } 00859 else { 00860 hwndFocus = NtUserQueryWindow(HW(pimeui->spwnd), WindowFocusWindow); 00861 hFocusImc = fpImmGetContext(hwndFocus); 00862 } 00863 00864 /* 00865 * Cannot share input context with other IME window. 00866 */ 00867 if (hFocusImc != NULL_HIMC && 00868 !ImeIsUsableContext(HW(pimeui->spwnd), hFocusImc)) { 00869 SETIMC(pimeui, NULL_HIMC); 00870 return 0L; 00871 } 00872 00873 SETIMC(pimeui, hFocusImc); 00874 00875 /* 00876 * Store it to the window memory. 00877 */ 00878 if (GETUI(pimeui) != NULL) 00879 SetWindowLongPtr(GETUI(pimeui), IMMGWLP_IMC, (LONG_PTR)hFocusImc); 00880 00881 /* 00882 * When we're receiving context, 00883 * it is necessary to set the owner to this window. 00884 * This is for: 00885 * Give the UI moving information. 00886 * Give the UI automatic Z-ordering. 00887 * Hide the UI when the owner is minimized. 00888 */ 00889 if (hFocusImc != NULL_HIMC) { 00890 PINPUTCONTEXT pInputContext; 00891 00892 /* 00893 * Get the window who's given the context. 00894 */ 00895 if ((pInputContext = fpImmLockIMC(hFocusImc)) != NULL) { 00896 //UserAssert(hwndFocus == pInputContext->hWnd); 00897 if (hwndFocus != pInputContext->hWnd) { 00898 /* 00899 * Pq->spwndFocus has been changed so far... 00900 * All we can do is just to bail out. 00901 */ 00902 return 0L; 00903 } 00904 } 00905 else 00906 return 0L; // the context was broken 00907 00908 if ((pInputContext->fdw31Compat & F31COMPAT_ECSETCFS) && 00909 hwndPrevIMC != hwndFocus) { 00910 COMPOSITIONFORM cf; 00911 00912 /* 00913 * Set CFS_DEFAULT.... 00914 */ 00915 RtlZeroMemory(&cf, sizeof(cf)); 00916 fpImmSetCompositionWindow(hFocusImc, &cf); 00917 pInputContext->fdw31Compat &= ~F31COMPAT_ECSETCFS; 00918 } 00919 00920 fpImmUnlockIMC(hFocusImc); 00921 00922 if (NtUserSetImeOwnerWindow(HW(pimeui->spwnd), hwndFocus)) 00923 pimeui->hwndIMC = hwndFocus; 00924 00925 } 00926 else { 00927 /* 00928 * NULL IMC is getting activated 00929 */ 00930 pimeui->hwndIMC = hwndFocus; 00931 00932 NtUserSetImeOwnerWindow(HW(pimeui->spwnd), NULL); 00933 00934 } 00935 } 00936 00937 lRet = SendMessageToUI(pimeui, message, wParam, lParam, FALSE); 00938 00939 if (pimeui->spwnd == NULL) { 00940 // Unusual case in stress.. 00941 // IME window has been destroyed during the callback 00942 RIPMSG0(RIP_WARNING, "ImmSetContextHandler: pimeui->spwnd is NULL after SendMessageToUI."); 00943 return 0L; 00944 } 00945 00946 if (pimeui->fCtrlShowStatus && GetIMEShowStatus()) { 00947 PWND pwndFocus, pwndIMC, pwndPrevIMC; 00948 HWND hwndActive; 00949 00950 hwndFocus = NtUserQueryWindow(HWq(pimeui->spwnd), WindowFocusWindow); 00951 pwndFocus = ValidateHwndNoRip(hwndFocus); 00952 00953 if ((BOOL)wParam == TRUE) { 00954 HWND hwndIme; 00955 00956 /* 00957 * BOGUS BOGUS 00958 * The following if statement is still insufficient 00959 * it needs to think what WM_IME_SETCONTEXT:TRUE should do 00960 * in the case of WINNLSEnableIME(true) - ref.win95c B#8548. 00961 */ 00962 UserAssert(pimeui->spwnd); 00963 if (pwndFocus != NULL && GETPTI(pimeui->spwnd) == GETPTI(pwndFocus)) { 00964 00965 if (!pimeui->fShowStatus) { 00966 /* 00967 * We have never sent IMN_OPENSTATUSWINDOW yet.... 00968 */ 00969 if (ValidateHwndNoRip(pimeui->hwndIMC)) { 00970 SendOpenStatusNotify(pimeui, pimeui->hwndIMC, TRUE); 00971 } 00972 } 00973 else if ((pwndIMC = ValidateHwndNoRip(pimeui->hwndIMC)) != NULL && 00974 (pwndPrevIMC = ValidateHwndNoRip(hwndPrevIMC)) != NULL && 00975 GetTopLevelWindow(pwndIMC) != GetTopLevelWindow(pwndPrevIMC)) { 00976 /* 00977 * Because the top level window of IME Wnd was changed. 00978 */ 00979 SendOpenStatusNotify(pimeui, hwndPrevIMC, FALSE); 00980 SendOpenStatusNotify(pimeui, pimeui->hwndIMC, TRUE); 00981 } 00982 } 00983 /* 00984 * There may have other IME windows that have fShowStatus. 00985 * We need to check the fShowStatus in the window list. 00986 */ 00987 hwndIme = HW(pimeui->spwnd); 00988 if (hwndIme) { 00989 NtUserCheckImeShowStatusInThread(hwndIme); 00990 } 00991 } 00992 else { 00993 /* 00994 * When focus was removed from this thread, we close the 00995 * status window. 00996 * Because focus was already removed from whndPrevIMC, 00997 * hwndPrevIMC may be destroyed but we need to close the 00998 * status window. 00999 */ 01000 hwndActive = NtUserQueryWindow(HW(pimeui->spwnd), WindowActiveWindow); 01001 UserAssert(pimeui->spwnd); 01002 if (pwndFocus == NULL || GETPTI(pimeui->spwnd) != GETPTI(pwndFocus) || 01003 hwndActive == NULL) { 01004 01005 if (IsWindow(hwndPrevIMC)) 01006 SendOpenStatusNotify(pimeui, hwndPrevIMC, FALSE); 01007 else { 01008 pimeui->fShowStatus = FALSE; 01009 SendMessageToUI(pimeui, WM_IME_NOTIFY, 01010 IMN_CLOSESTATUSWINDOW, 0L, FALSE); 01011 } 01012 } 01013 } 01014 } 01015 01016 return lRet; 01017 } 01018 01019 01020 LRESULT ImeNotifyHandler( 01021 PIMEUI pimeui, 01022 UINT message, 01023 WPARAM wParam, 01024 LPARAM lParam) 01025 { 01026 HWND hwndUI; 01027 LRESULT lRet = 0L; 01028 HIMC hImc; 01029 PINPUTCONTEXT pInputContext; 01030 01031 switch (wParam) { 01032 case IMN_PRIVATE: 01033 hwndUI = GETUI(pimeui); 01034 if (IsWindow(hwndUI)) 01035 lRet = SendMessage(hwndUI, message, wParam, lParam); 01036 break; 01037 01038 case IMN_SETCONVERSIONMODE: 01039 case IMN_SETOPENSTATUS: 01040 // 01041 // notify shell and keyboard the conversion mode change 01042 // 01043 // if this message is sent from ImmSetOpenStatus or 01044 // ImmSetConversionStatus, we have already notified 01045 // kernel the change. This is a little bit redundant. 01046 // 01047 // if application has eaten the message, we won't be here. 01048 // We need to think about the possibility later. 01049 // 01050 hImc = GETIMC(pimeui); 01051 if ((pInputContext = fpImmLockIMC(hImc)) != NULL) { 01052 if ( IsWindow(pimeui->hwndIMC) ) { 01053 NtUserNotifyIMEStatus( pimeui->hwndIMC, 01054 (DWORD)pInputContext->fOpen, 01055 pInputContext->fdwConversion ); 01056 } 01057 else if (gfConIme == TRUE) { 01058 /* 01059 * Special handling for Console IME is needed 01060 */ 01061 if (pimeui->spwnd) { // If IME window is still there. 01062 PWND pwndOwner = REBASEPWND(pimeui->spwnd, spwndOwner); 01063 01064 if (pwndOwner != NULL) { 01065 NtUserNotifyIMEStatus(HWq(pwndOwner), 01066 (DWORD)pInputContext->fOpen, 01067 pInputContext->fdwConversion); 01068 } 01069 } 01070 } 01071 fpImmUnlockIMC(hImc); 01072 } 01073 /*** FALL THROUGH ***/ 01074 default: 01075 TAGMSG4(DBGTAG_IMM, "ImeNotifyHandler: sending to pimeui->ui=%p, msg=%x, wParam=%x, lParam=%x\n", GETUI(pimeui), message, wParam, lParam); 01076 lRet = SendMessageToUI(pimeui, message, wParam, lParam, FALSE); 01077 } 01078 01079 return lRet; 01080 } 01081 01082 01083 HWND CreateIMEUI( 01084 PIMEUI pimeui, 01085 HKL hKL) 01086 { 01087 PWND pwndIme = pimeui->spwnd; 01088 HWND hwndUI; 01089 IMEINFOEX iiex; 01090 PIMEDPI pimedpi; 01091 WNDCLASS wndcls; 01092 01093 if (!fpImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) 01094 return (HWND)NULL; 01095 01096 if ((pimedpi = fpImmLockImeDpi(hKL)) == NULL) { 01097 RIPMSG1(RIP_WARNING, "CreateIMEUI: ImmLockImeDpi(%lx) failed.", hKL); 01098 return (HWND)NULL; 01099 } 01100 01101 if (!GetClassInfoW(pimedpi->hInst, iiex.wszUIClass, &wndcls)) { 01102 RIPMSG1(RIP_WARNING, "CreateIMEUI: GetClassInfoW(%ws) failed\n", iiex.wszUIClass); 01103 fpImmUnlockImeDpi(pimedpi); 01104 return (HWND)NULL; 01105 } 01106 01107 // HACK HACK HACK 01108 if ((wndcls.style & CS_IME) == 0) { 01109 RIPMSG1(RIP_ERROR, "CreateIMEUI: the Window Class (%S) does not have CS_IME flag on !!!\n", 01110 wndcls.lpszClassName); 01111 } 01112 01113 if (iiex.ImeInfo.fdwProperty & IME_PROP_UNICODE) { 01114 /* 01115 * For Unicode IME, we create an Unicode IME UI window. 01116 */ 01117 hwndUI = CreateWindowExW(0L, 01118 iiex.wszUIClass, 01119 iiex.wszUIClass, 01120 WS_POPUP|WS_DISABLED, 01121 0, 0, 0, 0, 01122 HWq(pwndIme), 0, wndcls.hInstance, NULL); 01123 } 01124 else { 01125 /* 01126 * For ANSI IME, we create an ANSI IME UI window. 01127 */ 01128 01129 LPSTR pszClass; 01130 int i; 01131 i = WCSToMB(iiex.wszUIClass, -1, &pszClass, -1, TRUE); 01132 if (i == 0) { 01133 RIPMSG1(RIP_WARNING, "CreateIMEUI: failed in W->A conversion (%S)", iiex.wszUIClass); 01134 return (HWND)NULL; 01135 } 01136 pszClass[i] = '\0'; 01137 01138 hwndUI = CreateWindowExA(0L, 01139 pszClass, 01140 pszClass, 01141 WS_POPUP|WS_DISABLED, 01142 0, 0, 0, 0, 01143 HWq(pwndIme), 0, wndcls.hInstance, NULL); 01144 01145 UserLocalFree(pszClass); 01146 } 01147 01148 if (hwndUI) 01149 NtUserSetWindowLongPtr(hwndUI, IMMGWLP_IMC, (LONG_PTR)GETIMC(pimeui), FALSE); 01150 01151 fpImmUnlockImeDpi(pimedpi); 01152 01153 return hwndUI; 01154 } 01155 01156 01157 VOID DestroyIMEUI( 01158 PIMEUI pimeui) 01159 { 01160 // This has currently nothing to do except for destroying the UI. 01161 // Review: Need to notify the UI with WM_IME_SETCONTEXT ? 01162 // Review: This doesn't support Multiple IME install yet. 01163 01164 HWND hwndUI = GETUI(pimeui); 01165 01166 if (IsWindow(hwndUI)) { 01167 pimeui->fDestroy = TRUE; 01168 /* 01169 * We need this verify because the owner might have already 01170 * killed it during its termination. 01171 */ 01172 NtUserDestroyWindow(hwndUI); 01173 } 01174 pimeui->fDestroy = FALSE; 01175 01176 /* 01177 * Reinitialize show status of the IME status window so that 01178 * notification message will be sent when needed. 01179 */ 01180 pimeui->fShowStatus = FALSE; 01181 01182 SETUI(pimeui, NULL); 01183 01184 return; 01185 } 01186 01187 01188 /***************************************************************************\ 01189 * SendMessageToUI 01190 * 01191 * History: 01192 * 09-Apr-1996 wkwok Created 01193 \***************************************************************************/ 01194 01195 LRESULT SendMessageToUI( 01196 PIMEUI pimeui, 01197 UINT message, 01198 WPARAM wParam, 01199 LPARAM lParam, 01200 BOOL fAnsi) 01201 { 01202 PWND pwndUI; 01203 LRESULT lRet; 01204 01205 TAGMSG1(DBGTAG_IMM, "Sending to UI msg[%04X]\n", message); 01206 01207 pwndUI = ValidateHwndNoRip(GETUI(pimeui)); 01208 01209 if (pwndUI == NULL || pimeui->spwnd == NULL) 01210 return 0L; 01211 01212 if (TestWF(pimeui->spwnd, WFINDESTROY) || TestWF(pimeui->spwnd, WFDESTROYED) || 01213 TestWF(pwndUI, WFINDESTROY) || TestWF(pwndUI, WFDESTROYED)) { 01214 return 0L; 01215 } 01216 01217 InterlockedIncrement(&pimeui->nCntInIMEProc); // Mark to avoid recursion. 01218 01219 lRet = SendMessageWorker(pwndUI, message, wParam, lParam, fAnsi); 01220 01221 InterlockedDecrement(&pimeui->nCntInIMEProc); // Mark to avoid recursion. 01222 01223 return lRet; 01224 } 01225 01226 01227 /***************************************************************************\ 01228 * SendOpenStatusNotify 01229 * 01230 * History: 01231 * 09-Apr-1996 wkwok Created 01232 \***************************************************************************/ 01233 01234 VOID SendOpenStatusNotify( 01235 PIMEUI pimeui, 01236 HWND hwndApp, 01237 BOOL fOpen) 01238 { 01239 WPARAM wParam = fOpen ? IMN_OPENSTATUSWINDOW : IMN_CLOSESTATUSWINDOW; 01240 01241 pimeui->fShowStatus = fOpen; 01242 01243 01244 if (GetClientInfo()->dwExpWinVer >= VER40) { 01245 TAGMSG2(DBGTAG_IMM, "SendOpenStatusNotify: sending to hwnd=%lx, wParam=%d\n", hwndApp, wParam); 01246 SendMessage(hwndApp, WM_IME_NOTIFY, wParam, 0L); 01247 } 01248 else { 01249 TAGMSG2(DBGTAG_IMM, "SendOpenStatusNotify:sending to imeui->UI=%p, wParam=%d\n", GETUI(pimeui), wParam); 01250 SendMessageToUI(pimeui, WM_IME_NOTIFY, wParam, 0L, FALSE); 01251 } 01252 01253 return; 01254 } 01255 01256 01257 VOID ImeSetImc( 01258 PIMEUI pimeui, 01259 HIMC hImc) 01260 { 01261 HWND hImeWnd = HW(pimeui->spwnd); 01262 HIMC hOldImc = GETIMC(pimeui); 01263 01264 /* 01265 * return if nothing to change. 01266 */ 01267 if (hImc == hOldImc) 01268 return; 01269 01270 /* 01271 * Unmark the old input context. 01272 */ 01273 if (hOldImc != NULL_HIMC) 01274 ImeMarkUsedContext(NULL, hOldImc); 01275 01276 /* 01277 * Update the in use input context for this IME window. 01278 */ 01279 pimeui->hIMC = hImc; 01280 01281 /* 01282 * Mark the new input context. 01283 */ 01284 if (hImc != NULL_HIMC) 01285 ImeMarkUsedContext(hImeWnd, hImc); 01286 } 01287 01288 01289 /***************************************************************************\ 01290 * FocusSetIMCContext() 01291 * 01292 * History: 01293 * 21-Mar-1996 wkwok Created 01294 \***************************************************************************/ 01295 01296 VOID FocusSetIMCContext( 01297 HWND hWnd, 01298 BOOL fActivate) 01299 { 01300 HIMC hImc; 01301 01302 if (IsWindow(hWnd)) { 01303 hImc = fpImmGetContext(hWnd); 01304 fpImmSetActiveContext(hWnd, hImc, fActivate); 01305 fpImmReleaseContext(hWnd, hImc); 01306 } 01307 else { 01308 fpImmSetActiveContext(NULL, NULL_HIMC, fActivate); 01309 } 01310 01311 return; 01312 } 01313 01314 01315 BOOL ImeBroadCastMsg( 01316 PIMEUI pimeui, 01317 UINT message, 01318 WPARAM wParam, 01319 LPARAM lParam) 01320 { 01321 UNREFERENCED_PARAMETER(pimeui); 01322 UNREFERENCED_PARAMETER(message); 01323 UNREFERENCED_PARAMETER(wParam); 01324 UNREFERENCED_PARAMETER(lParam); 01325 01326 return TRUE; 01327 } 01328 01329 /***************************************************************************\ 01330 * ImeMarkUsedContext() 01331 * 01332 * Some IME windows can not share the same input context. This function 01333 * marks the specified hImc to be in used by the specified IME window. 01334 * 01335 * History: 01336 * 12-Mar-1996 wkwok Created 01337 \***************************************************************************/ 01338 01339 VOID ImeMarkUsedContext( 01340 HWND hImeWnd, 01341 HIMC hImc) 01342 { 01343 PIMC pImc; 01344 01345 pImc = HMValidateHandle((HANDLE)hImc, TYPE_INPUTCONTEXT); 01346 if (pImc == NULL) { 01347 RIPMSG1(RIP_WARNING, "ImeMarkUsedContext: Invalid hImc (=%lx).", hImc); 01348 return; 01349 } 01350 01351 UserAssert( ValidateHwndNoRip(pImc->hImeWnd) == NULL || hImeWnd == NULL ); 01352 01353 /* 01354 * Nothing to change? 01355 */ 01356 if (pImc->hImeWnd == hImeWnd) 01357 return; 01358 01359 NtUserUpdateInputContext(hImc, UpdateInUseImeWindow, (ULONG_PTR)hImeWnd); 01360 01361 return; 01362 } 01363 01364 01365 /***************************************************************************\ 01366 * ImeIsUsableContext() 01367 * 01368 * Some IME windows can not share the same input context. This function 01369 * checks whether the specified hImc can be used (means 'Set activated') 01370 * by the specified IME window. 01371 * 01372 * Return: TRUE - OK to use the hImc by hImeWnd. 01373 * FALSE - otherwise. 01374 * 01375 * History: 01376 * 12-Mar-1996 wkwok Created 01377 \***************************************************************************/ 01378 01379 BOOL ImeIsUsableContext( 01380 HWND hImeWnd, 01381 HIMC hImc) 01382 { 01383 PIMC pImc; 01384 01385 UserAssert(hImeWnd != NULL); 01386 01387 pImc = HMValidateHandle((HANDLE)hImc, TYPE_INPUTCONTEXT); 01388 if (pImc == NULL) { 01389 RIPMSG1(RIP_WARNING, "ImeIsUsableContext: Invalid hImc (=%lx).", hImc); 01390 return FALSE; 01391 } 01392 01393 if ( pImc->hImeWnd == NULL || 01394 pImc->hImeWnd == hImeWnd || 01395 ValidateHwndNoRip(pImc->hImeWnd) == NULL ) 01396 { 01397 return TRUE; 01398 } 01399 01400 01401 return FALSE; 01402 } 01403 01404 /***************************************************************************\ 01405 * GetIMEShowStatus() 01406 * 01407 * Get the global IME show status from kernel. 01408 * 01409 * History: 01410 * 19-Sep-1996 takaok Ported from internat.exe. 01411 \***************************************************************************/ 01412 01413 BOOL GetIMEShowStatus(void) 01414 { 01415 return (BOOL)NtUserCallNoParam(SFI__GETIMESHOWSTATUS); 01416 } 01417 01418 01419 01420 /***************************************************************************\ 01421 * IMEIndicatorGetMenuIDData 01422 * 01423 * History: 01424 * 3-Nov-97 Hiroyama 01425 \***************************************************************************/ 01426 01427 BOOL IMEIndicatorGetMenuIDData(PUINT puMenuID, PDWORD pdwData) 01428 { 01429 HANDLE hinstIndic; 01430 01431 hinstIndic = GetModuleHandle(szIndicDLL); 01432 if (hinstIndic == NULL) { 01433 gpfnGetIMEMenuItemData = NULL; 01434 return FALSE; 01435 } 01436 01437 if (!gpfnGetIMEMenuItemData) { 01438 gpfnGetIMEMenuItemData = GetProcAddress(hinstIndic, (LPSTR)ORD_GETIMEMENUITEMDATA); 01439 } 01440 if (!gpfnGetIMEMenuItemData) 01441 return FALSE; 01442 01443 (*(FPGETIMEMENUITEMDATA)gpfnGetIMEMenuItemData)(puMenuID, pdwData); 01444 return TRUE; 01445 } 01446 01447 01448 BOOL SyncSoftKbdState( 01449 HIMC hImc, 01450 LPARAM lParam) 01451 { 01452 DWORD fdwConversion, fdwSentence, fdwNewConversion; 01453 01454 fpImmGetConversionStatus(hImc, &fdwConversion, &fdwSentence); 01455 01456 if (lParam) { 01457 fdwNewConversion = fdwConversion | IME_CMODE_SOFTKBD; 01458 } else { 01459 fdwNewConversion = fdwConversion & ~IME_CMODE_SOFTKBD; 01460 } 01461 01462 if (fdwNewConversion != fdwConversion) { 01463 fpImmSetConversionStatus(hImc, fdwNewConversion, fdwSentence); 01464 } 01465 01466 return TRUE; 01467 } 01468 01469 /***************************************************************************\ 01470 * ImeCopyDataHandler 01471 * 01472 * History: 01473 * 10-Nov-98 Hiroyama 01474 \***************************************************************************/ 01475 01476 LRESULT ImeCopyDataHandler( 01477 WPARAM wParam, 01478 LPARAM lParam) 01479 { 01480 HINSTANCE hInstImm; 01481 BOOL (WINAPI* fpImmPenAuxInput)(HWND, LPVOID); 01482 01483 hInstImm = GetModuleHandleW(L"IMM32.DLL"); 01484 if (hInstImm == NULL) { 01485 return FALSE; 01486 } 01487 01488 fpImmPenAuxInput = (LPVOID)GetProcAddress(hInstImm, "ImmPenAuxInput"); 01489 if (fpImmPenAuxInput == NULL) { 01490 return FALSE; 01491 } 01492 01493 return fpImmPenAuxInput((HWND)wParam, (LPVOID)lParam); 01494 }

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