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

transsub.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: transsub.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains the translation layer functions 00007 * of the sub functions of SendImeMessageEx. 00008 * 00009 * History: 00010 * 21-May-1996 takaok Created. 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 LRESULT TransSetOpenK( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme ); 00017 LRESULT TransSetOpenJ( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme ); 00018 LRESULT TransGetOpenK( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi ); 00019 LRESULT TransGetOpenJ( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi ); 00020 LRESULT TransMoveImeWindow( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme); 00021 LRESULT TransSetConversionWindow( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme ); 00022 LRESULT TransSetConversionMode( HIMC hImc, LPIMESTRUCT lpIme ); 00023 LRESULT TransGetMode( HIMC hImc ); 00024 LRESULT TransGetConversionMode( HIMC hImc ); 00025 LRESULT TransSetMode( HIMC hImc, LPIMESTRUCT lpIme ); 00026 LRESULT TransSendVKey( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi ); 00027 LRESULT TransEnterWordRegisterMode( HWND hWndApp, LPIMESTRUCT lpIme, BOOL fAnsi); 00028 LRESULT TransSetConversionFontEx( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi); 00029 LRESULT TransHanjaMode( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme); 00030 UINT Get31ModeFrom40ModeJ( DWORD fdwConversion ); 00031 UINT Get31ModeFrom40ModeK( DWORD fdwConversion ); 00032 LRESULT TransVKDBEMode( HIMC hImc, WPARAM wVKDBE ); 00033 00034 BOOL SetFontForMCWVERTICAL( HWND hWndApp, HIMC hImc, LPINPUTCONTEXT pInputContext, BOOL fVert ); 00035 BOOL IsForegroundThread( HWND ); 00036 BOOL FixLogfont( LPLOGFONTW lplfW, BOOL fVert ); 00037 00038 BOOL MySetCompFont( HWND, HIMC, LPLOGFONTW ); 00039 BOOL MySetCompWindow( HWND, HIMC, LPCOMPOSITIONFORM ); 00040 BOOL MySetCandidateWindow( HWND, HIMC, LPCANDIDATEFORM ); 00041 BOOL MyPostImsMessage( HWND hWndApp, WPARAM wParam, LPARAM lParam); 00042 00043 //=================================================================== 00044 // TranslateIMESubFunctions 00045 //========================== 00046 // 00047 // KOREAN and JAPANESE common translate routine for the 00048 // sub functions of SendImeMessageEx. 00049 // 00050 // History: 00051 // 21-May-1996 takaok Created. 00052 // 00053 //=================================================================== 00054 LRESULT TranslateIMESubFunctions( 00055 HWND hWndApp, 00056 LPIMESTRUCT lpIme, 00057 BOOL fAnsi) 00058 { 00059 HIMC hImc; 00060 LRESULT lRet; 00061 DWORD dwLangID; 00062 00063 hImc = ImmGetSaveContext( hWndApp, IGSC_DEFIMCFALLBACK ); 00064 if ( hImc == NULL_HIMC ) { 00065 return FALSE; 00066 } 00067 00068 dwLangID = PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())); 00069 00070 switch (lpIme->fnc) { 00071 case 0x03: // IME_QUERY, IME_GETIMECAPS: KOREAN & JAPANESE 00072 lRet = TRUE; 00073 break; 00074 00075 case 0x04: // IME_SETOPEN: KOREAN & JAPANESE 00076 if ( dwLangID == LANG_KOREAN ) 00077 lRet = TransSetOpenK( hWndApp, hImc, lpIme ); 00078 else 00079 lRet = TransSetOpenJ( hWndApp, hImc, lpIme ); 00080 break; 00081 00082 case 0x05: // IME_GETOPEN: KOREAN & JAPANESE 00083 if ( dwLangID == LANG_KOREAN ) 00084 lRet = TransGetOpenK( hWndApp, hImc, lpIme, fAnsi ); 00085 else 00086 lRet = TransGetOpenJ( hWndApp, hImc, lpIme, fAnsi ); 00087 break; 00088 00089 case 0x06: // IME_ENABLEDOSIME, IME_ENABLE 00090 // internal functions are not supported 00091 lRet = FALSE; 00092 break; 00093 00094 case 0x07: // IME_GETVERSION: KOREAN & JAPANESE 00095 lRet = IMEVER_31; 00096 break; 00097 00098 case 0x08: // IME_MOVEIMEWINDOW, IME_SETCONVERSIONWINDOW: KOREAN & JAPANESE 00099 00100 if ( dwLangID == LANG_KOREAN ) { 00101 // 00102 // IME_MOVEIMEWINDOW for KOREAN 00103 // 00104 lRet = TransMoveImeWindow(hWndApp, hImc, lpIme); 00105 } else { 00106 // 00107 // IME_MOVECONVERTWINDOW or IME_SETCONVERSIONWINDOW for JAPANESE 00108 // 00109 lRet = TransSetConversionWindow( hWndApp, hImc, lpIme ); 00110 } 00111 break; 00112 00113 // case 0x09: // undefined 00114 00115 case 0x10: // IME_SETCONVERSIONMODE: JAPANESE 00116 if ( dwLangID == LANG_JAPANESE ) { 00117 lRet = TransSetConversionMode( hImc, lpIme ); 00118 } else { 00119 lRet = FALSE; 00120 } 00121 break; 00122 00123 case 0x11: // IME_GETCONVERSIONMODE, IME_GETMODE: // KOREAN & JAPANESE 00124 // Use hSaveIMC, If WINNSEnableIME(FALSE). 00125 if ( dwLangID == LANG_KOREAN ) { 00126 // 00127 // IME_GETMODE for KOREAN 00128 // 00129 lRet = TransGetMode( hImc ); 00130 } else { 00131 // 00132 // IME_GETCONVERSIONMODE for JAPANESE 00133 // 00134 lRet = TransGetConversionMode( hImc ); 00135 } 00136 break; 00137 00138 case 0x12: // IME_SET_MODE, IME_SETFONT, IME_SETCONVERSIONFONT: KOREAN & JAPANESE 00139 if ( dwLangID == LANG_KOREAN ) { 00140 // 00141 // IME_SET_MODE for KOREAN 00142 // 00143 lRet = TransSetMode( hImc, lpIme ); 00144 } else { 00145 // 00146 // IME_SETCONVERSIONFONT for JAPANESE 00147 // 00148 lRet = FALSE; // should not be called. use SETCONVERSIONFONTEX instead 00149 } 00150 break; 00151 00152 case 0x13: // IME_SENDVKEY, IME_SENDKEY: JAPANESE only 00153 if ( dwLangID == LANG_JAPANESE ) { 00154 lRet = TransSendVKey( hWndApp, hImc, lpIme, fAnsi ); 00155 } else { 00156 lRet = FALSE; 00157 } 00158 break; 00159 00160 // 00161 // internal sub functions are not supported 00162 // 00163 // case 0x14: // IME_DESTROY, IME_DESTROYIME 00164 // case 0x15: // IME_PRIVATE 00165 // case 0x16: // IME_WINDOWUPDATE 00166 // case 0x17: // IME_SELECT 00167 00168 case 0x18: // IME_ENTERWORDREGISTERMODE: JAPANESE only 00169 if ( dwLangID == LANG_JAPANESE ) { 00170 lRet = TransEnterWordRegisterMode( hWndApp, lpIme, fAnsi); 00171 } else { 00172 lRet = FALSE; 00173 } 00174 break; 00175 00176 case 0x19: // IME_SETCONVERSIONFONTEX: JAPANESE only 00177 if ( dwLangID == LANG_JAPANESE ) { 00178 lRet = TransSetConversionFontEx( hWndApp, hImc, lpIme, fAnsi); 00179 } else { 00180 lRet = FALSE; 00181 } 00182 break; 00183 00184 // 00185 // internal sub functions are not supported 00186 // 00187 // case 0x1A: // IME_DBCSNAME 00188 // case 0x1B: // IME_MAXKEY 00189 // case 0x1C: // IME_WINNLS_SK 00190 00191 case 0x20: // IME_CODECONVERT: KOREAN only 00192 if ( dwLangID == LANG_KOREAN ) { 00193 if (TransCodeConvert( hImc, lpIme)) 00194 lRet = lpIme->wParam; 00195 else 00196 lRet = 0; 00197 } else { 00198 lRet = 0; 00199 } 00200 break; 00201 00202 case 0x21: // IME_CONVERTLIST: KOREAN only 00203 if ( dwLangID == LANG_KOREAN ) { 00204 lRet = TransConvertList( hImc, lpIme); 00205 } else { 00206 lRet = FALSE; 00207 } 00208 break; 00209 00210 // 00211 // internal sub functions and undefined sub functions are not supported 00212 // 00213 // case 0x22: // IME_INPUTKEYTOSEQUENCE 00214 // case 0x23: // IME_SEQUENCETOINTERNAL 00215 // case 0x24: // IME_QUERYIMEINFO 00216 // case 0x25: // IME_DIALOG 00217 // case 0x26 - 0x2f: // undefined 00218 00219 case 0x30: // IME_AUTOMATA: KOREAN only 00220 if ( dwLangID == LANG_KOREAN ) { 00221 lRet = ImmEscape(GetKeyboardLayout(0), hImc, IME_AUTOMATA, lpIme); 00222 } else { 00223 lRet = FALSE; 00224 } 00225 break; 00226 00227 case 0x31: // IME_HANJAMODE: KOREAN only 00228 if ( dwLangID == LANG_KOREAN ) { 00229 lRet = TransHanjaMode( hWndApp, hImc, lpIme); 00230 } else { 00231 lRet = FALSE; 00232 } 00233 break; 00234 // 00235 // case 0x32 - 0x3f: // undefined 00236 // 00237 case 0x40: // IME_GETLEVEL: KOREAN only 00238 if ( dwLangID == LANG_KOREAN ) { 00239 lRet = TransGetLevel( hWndApp ); 00240 } else { 00241 lRet = FALSE; 00242 } 00243 break; 00244 00245 case 0x41: // IME_SETLEVEL: KOREAN only 00246 if ( dwLangID == LANG_KOREAN ) { 00247 lRet = TransSetLevel( hWndApp, lpIme); 00248 } else { 00249 lRet = FALSE; 00250 } 00251 break; 00252 00253 case 0x42: // IME_GETMNTABLE: KOREAN only 00254 if ( dwLangID == LANG_KOREAN ) { 00255 lRet = TransGetMNTable( hImc, lpIme); 00256 } else { 00257 lRet = FALSE; 00258 } 00259 break; 00260 00261 #if defined(PENAPI) 00262 case IME_SETUNDETERMINESTRING: 00263 lRet = FSetUndetermine( hImc, (HGLOBAL)lpIME->lParam1); 00264 break; 00265 00266 case IME_SETCAPTURE: 00267 lRet = FEnablePenUi((HWND)lpIME->wParam, (lpIME->wParam != NULL)); 00268 break; 00269 #endif 00270 00271 #ifdef LATER // IME_NOTIFYWOWTASKEXIT 00272 case IME_NOTIFYWOWTASKEXIT: 00273 // 00274 // Destroy the default IME window of WOW 16bit 00275 // applications now. We should not wait for the 00276 // server wow thread clean up that will destroy the 00277 // IME window because usrsrv won't send WM_DESTROY 00278 // to non-server side window procedures. Some IMEs 00279 // must receive WM_DESTROY to free up 32 bit objects. 00280 // 00281 // kksuzuka #7982:IME memory leak on WOW16 applications. 00282 // 00283 PIMMTHREADINFO piti = PitiCurrent(); 00284 00285 if ( piti != NULL && IsWindow( piti->hwndDefaultIme ) ) { 00286 DestroyWindow( piti->hwndDefaultIme ); 00287 } 00288 return TRUE; 00289 #endif 00290 default: 00291 // 00292 // private/internal/undefined functions are not supported 00293 // 00294 lRet = FALSE; 00295 break; 00296 } 00297 00298 return (lRet); 00299 } 00300 00301 //=================================================================== 00302 // TransSetOpenK 00303 //=============== 00304 // 00305 // KOREAN only 00306 // 00307 // History: 00308 // xx-xx-1995 xxx Created 00309 // 00310 //=================================================================== 00311 LRESULT TransSetOpenK( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme ) 00312 { 00313 // BUGBUG: We will use this function instead of ImmEscape(). 00314 LRESULT lRet; 00315 00316 lRet = ImmEscape(GetKeyboardLayout(0), hImc, IME_SETOPEN, lpIme); 00317 return (lRet); 00318 UNREFERENCED_PARAMETER(hWndApp); 00319 } 00320 00321 //=================================================================== 00322 // TransSetOpenJ 00323 //=============== 00324 // 00325 // Japanese only 00326 // 00327 // History: 00328 // 20-May-1996 takaok Created 00329 // 00330 //=================================================================== 00331 LRESULT TransSetOpenJ( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme ) 00332 { 00333 LRESULT lRet; 00334 00335 lRet = ImmGetOpenStatus( hImc ); 00336 // 00337 // if the owner thread of hIMC doesn't have the input focus, 00338 // we won't call UI. 00339 // 00340 if ( !IsForegroundThread( NULL ) && !GetFocus() ) { 00341 // 00342 // this thread doesn't have focus. 00343 // let's update the input context and return without calling UI 00344 // 00345 PINPUTCONTEXT pInputContext; 00346 00347 if ( (pInputContext = ImmLockIMC(hImc)) != NULL ) { 00348 if ( (pInputContext->fOpen && ! lpIme->wParam ) || 00349 (!pInputContext->fOpen && lpIme->wParam ) ) 00350 { 00351 pInputContext->fOpen = (BOOL)lpIme->wParam; 00352 ImmNotifyIME( hImc, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS); 00353 } 00354 ImmUnlockIMC( hImc ); 00355 } 00356 } else { 00357 ImmSetOpenStatus( hImc, (BOOL)lpIme->wParam ); 00358 } 00359 return lRet; 00360 UNREFERENCED_PARAMETER(hWndApp); 00361 } 00362 00363 //=================================================================== 00364 // TransGetOpenK 00365 //=============== 00366 // 00367 // KOREAN only 00368 // 00369 // History: 00370 // xx-xx-1995 xxx Created 00371 // 00372 //=================================================================== 00373 LRESULT TransGetOpenK( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi ) 00374 { 00375 // BUGBUG: We will use this function instead of ImmEscape(). 00376 RECT rc; 00377 LPARAM lTemp; 00378 LRESULT lRet; 00379 00380 lTemp = lpIme->lParam2; 00381 GetWindowRect(hWndApp, &rc); 00382 lpIme->lParam2 = MAKELONG(rc.top, rc.left); 00383 lRet = ImmEscape(GetKeyboardLayout(0), hImc, IME_GETOPEN, lpIme); 00384 lpIme->lParam2 = lTemp; 00385 return (lRet); 00386 UNREFERENCED_PARAMETER(fAnsi); 00387 } 00388 00389 //=================================================================== 00390 // TransGetOpenJ 00391 //=============== 00392 // 00393 // Japanese only 00394 // 00395 // History: 00396 // 20-May-1996 takaok Created 00397 // 00398 //=================================================================== 00399 LRESULT TransGetOpenJ( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi ) 00400 { 00401 INT Count; 00402 LRESULT lRet; 00403 00404 lRet = ImmGetOpenStatus( hImc ); 00405 00406 // lpIME->wCount is the length of the composition string. 00407 if ( fAnsi ) { 00408 Count= ImmGetCompositionStringA( hImc, GCS_COMPSTR, NULL, 0L ); 00409 } else { 00410 Count= ImmGetCompositionStringW( hImc, GCS_COMPSTR, NULL, 0L ); 00411 } 00412 lpIme->wCount = ( Count > 0 ) ? Count : 0; 00413 00414 return lRet; 00415 UNREFERENCED_PARAMETER(hWndApp); 00416 } 00417 00418 //=================================================================== 00419 // TransMoveImeWindow 00420 //==================== 00421 // 00422 // Korean only 00423 // 00424 //=================================================================== 00425 LRESULT TransMoveImeWindow( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme) 00426 { 00427 // BUGBUG: We will use this function instead of ImmEscape(). 00428 POINT pt; 00429 LRESULT lRet; 00430 00431 if (lpIme->wParam == MCW_WINDOW) 00432 { 00433 pt.x = GET_X_LPARAM(lpIme->lParam1); 00434 pt.y = GET_Y_LPARAM(lpIme->lParam1); 00435 ClientToScreen(hWndApp, &pt); 00436 lpIme->lParam1 = MAKELONG(pt.x, pt.y); 00437 } 00438 lRet = ImmEscape(GetKeyboardLayout(0), hImc, IME_MOVEIMEWINDOW, lpIme); 00439 return (lRet); 00440 } 00441 00442 00443 //=================================================================== 00444 // TransSetConversionWindow 00445 //========================= 00446 // 00447 // Japanese only 00448 // 00449 //=================================================================== 00450 LRESULT TransSetConversionWindow( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme ) 00451 { 00452 LPINPUTCONTEXT pInputContext; 00453 COMPOSITIONFORM cof; 00454 CANDIDATEFORM caf; 00455 POINT pt; 00456 RECT rt; 00457 INT i; 00458 00459 if ( ! IsForegroundThread(NULL) && !GetFocus() ) { 00460 // 00461 // For win95 compatibility, we need to return TRUE though we 00462 // didn't really succeed. PP4 calls us when it doesn't have 00463 // the input focus to check if IME is capable to do the specfied 00464 // MCW_xxx. Returning TRUE here will make such application happy. 00465 // 00466 return ( TRUE ); 00467 } 00468 00469 pInputContext = ImmLockIMC( hImc ); 00470 if ( pInputContext == NULL ) { 00471 return ( FALSE ); 00472 } 00473 00474 pt.x = GET_X_LPARAM(lpIme->lParam1); 00475 pt.y = GET_Y_LPARAM(lpIme->lParam1); 00476 rt.left = GET_X_LPARAM(lpIme->lParam2); 00477 rt.top = GET_Y_LPARAM(lpIme->lParam2); 00478 rt.right = GET_X_LPARAM(lpIme->lParam3); 00479 rt.bottom = GET_Y_LPARAM(lpIme->lParam3); 00480 00481 cof.dwStyle = CFS_DEFAULT; 00482 00483 if ( lpIme->wParam & MCW_HIDDEN ) { 00484 pInputContext->fdw31Compat |= F31COMPAT_MCWHIDDEN; 00485 ScreenToClient( pInputContext->hWnd, &pt ); 00486 MapWindowPoints( HWND_DESKTOP, pInputContext->hWnd, (LPPOINT)&rt, 2); 00487 } else { 00488 pInputContext->fdw31Compat &= ~F31COMPAT_MCWHIDDEN; 00489 } 00490 00491 if ( lpIme->wParam & MCW_WINDOW) { 00492 if ( !IsWndEqual(hWndApp, pInputContext->hWnd)) { 00493 ClientToScreen(hWndApp, &pt); 00494 ScreenToClient(pInputContext->hWnd, &pt); 00495 if (lpIme->wParam & MCW_RECT) { 00496 cof.dwStyle = CFS_RECT; 00497 MapWindowPoints(hWndApp, HWND_DESKTOP, (LPPOINT)&rt, 2); 00498 MapWindowPoints(HWND_DESKTOP, pInputContext->hWnd, (LPPOINT)&rt, 2); 00499 } else { 00500 cof.dwStyle = CFS_POINT; 00501 } 00502 } else { 00503 if ( lpIme->wParam & MCW_RECT) { 00504 cof.dwStyle = CFS_RECT; 00505 } else { 00506 cof.dwStyle = CFS_POINT; 00507 } 00508 } 00509 } 00510 00511 // Because Chicago IME can not handle CFS_SCREEN. The points should be 00512 // converted to client point. 00513 // If these points are out of Client, HOW SHOULD WE DO???? 00514 00515 if ( lpIme->wParam & MCW_SCREEN ) { 00516 ScreenToClient( pInputContext->hWnd, &pt ); 00517 if ( lpIme->wParam & CFS_RECT ) { 00518 cof.dwStyle = CFS_RECT; 00519 MapWindowPoints( HWND_DESKTOP, pInputContext->hWnd, (LPPOINT)&rt, 2 ); 00520 } 00521 else { 00522 cof.dwStyle = CFS_POINT; 00523 } 00524 } 00525 00526 if ( lpIme->wParam & MCW_VERTICAL) { 00527 if ( !(pInputContext->fdw31Compat & F31COMPAT_MCWVERTICAL) ) { 00528 pInputContext->fdw31Compat |= F31COMPAT_MCWVERTICAL; 00529 SetFontForMCWVERTICAL( hWndApp, hImc, pInputContext, TRUE); 00530 } 00531 } else { 00532 if (pInputContext->fdw31Compat & F31COMPAT_MCWVERTICAL) { 00533 pInputContext->fdw31Compat &= ~F31COMPAT_MCWVERTICAL; 00534 SetFontForMCWVERTICAL( hWndApp, hImc, pInputContext, FALSE); 00535 } 00536 } 00537 cof.ptCurrentPos = pt; 00538 cof.rcArea = rt; 00539 00540 #if defined(PENAPI) 00541 if ( !FSetPosPenUi(&cof) ) 00542 #endif 00543 if ( !(pInputContext->fdw31Compat & F31COMPAT_MCWHIDDEN) ) { 00544 MySetCompWindow( hWndApp, hImc, (LPCOMPOSITIONFORM)&cof ); 00545 } else { 00546 // Hack for 3.1 Apps. We save the exlude area into IMC. 00547 pInputContext->cfCompForm.ptCurrentPos = cof.ptCurrentPos; 00548 pInputContext->cfCompForm.rcArea = cof.rcArea; 00549 00550 for ( i=0; i < 4; i++ ) { 00551 if ( pInputContext->cfCandForm[i].dwIndex != -1) 00552 { 00553 caf.dwIndex = i; 00554 caf.dwStyle = CFS_EXCLUDE; 00555 caf.ptCurrentPos = pt; 00556 caf.rcArea = rt; 00557 MySetCandidateWindow( hWndApp, hImc, (LPCANDIDATEFORM)&caf ); 00558 } 00559 } 00560 } 00561 ImmUnlockIMC( hImc ); 00562 return ( TRUE ); 00563 } 00564 00565 //=================================================================== 00566 // TransSetConversionMode 00567 //======================= 00568 // 00569 // Japanese only 00570 // 00571 // History: 00572 // 31-May-1996 takaok Created. 00573 // 00574 //=================================================================== 00575 LRESULT TransSetConversionMode( HIMC hImc, LPIMESTRUCT lpIme ) 00576 { 00577 DWORD fdwConversion, fdwSentence, fdwNewConversion, fdwMask; 00578 UINT uPrevMode; 00579 UINT u31Mode; 00580 00581 // 00582 // Get current conversion mode and translate it to 00583 // the 3.1 style conversion mode. 00584 // 00585 ImmGetConversionStatus( hImc, &fdwConversion, &fdwSentence); 00586 uPrevMode = Get31ModeFrom40ModeJ( fdwConversion ); 00587 00588 // 00589 // translate requested 3.1 conversion mode to 4.0 conversion mode 00590 // 00591 fdwNewConversion = 0; 00592 u31Mode = (UINT)lpIme->wParam; 00593 00594 switch ( u31Mode & 0x07 ) { 00595 case IME_MODE_ALPHANUMERIC: 00596 fdwNewConversion &= ~IME_CMODE_LANGUAGE; 00597 break; 00598 case IME_MODE_KATAKANA: 00599 fdwNewConversion |= IME_CMODE_NATIVE|IME_CMODE_KATAKANA; 00600 break; 00601 case IME_MODE_HIRAGANA: 00602 fdwNewConversion |= IME_CMODE_NATIVE; 00603 break; 00604 } 00605 if ( !(u31Mode & JAPAN_IME_MODE_SBCSCHAR) ) 00606 fdwNewConversion |= IME_CMODE_FULLSHAPE; 00607 00608 if ( u31Mode & IME_MODE_ROMAN ) 00609 fdwNewConversion |= IME_CMODE_ROMAN; 00610 00611 if ( u31Mode & IME_MODE_CODEINPUT ) 00612 fdwNewConversion |= IME_CMODE_CHARCODE; 00613 00614 // 00615 // compute the mask bit. we need to compute this because 00616 // application may set only bit needed to be changed. 00617 // 00618 fdwMask = 0; 00619 if ( u31Mode & (IME_MODE_ROMAN | IME_MODE_NOROMAN) ) 00620 fdwMask |= IME_CMODE_ROMAN; 00621 00622 if ( u31Mode & (IME_MODE_CODEINPUT|IME_MODE_NOCODEINPUT) ) 00623 fdwMask |= IME_CMODE_CHARCODE; 00624 00625 if ( u31Mode & 0x07 ) 00626 fdwMask |= IME_CMODE_LANGUAGE; 00627 00628 if ( u31Mode & (IME_MODE_DBCSCHAR|JAPAN_IME_MODE_SBCSCHAR) ) 00629 fdwMask |= IME_CMODE_FULLSHAPE; 00630 00631 // 00632 // set the new mode 00633 // 00634 fdwNewConversion = (fdwNewConversion & fdwMask) | (fdwConversion & ~fdwMask); 00635 if ( ImmSetConversionStatus( hImc, fdwNewConversion, fdwSentence) ) { 00636 return (LRESULT)uPrevMode; 00637 } else { 00638 return (LRESULT)0; 00639 } 00640 } 00641 00642 //=================================================================== 00643 // TransGetMode 00644 //============== 00645 // 00646 // Korean only 00647 // 00648 // translate 4.0 conversion mode into 3.1 conversion mode 00649 // 00650 // History: 00651 // 31-May-1996 takaok Created. 00652 // 00653 //=================================================================== 00654 LRESULT TransGetMode( HIMC hImc ) 00655 { 00656 DWORD fdwConversion, fdwSentence; 00657 UINT u31Mode = 0; 00658 00659 ImmGetConversionStatus( hImc, &fdwConversion, &fdwSentence); 00660 u31Mode= Get31ModeFrom40ModeK( fdwConversion ); 00661 // HACK: To prevent 0 result from treating FALSE, we always set MSB 00662 return ( u31Mode | 0x80000000 ); 00663 } 00664 00665 //=================================================================== 00666 // Get31ModeFrom40ModeK 00667 //===================== 00668 // 00669 // Korean only 00670 // 00671 // translate 4.0 conversion mode into 3.1 conversion mode 00672 // 00673 // History: 00674 // 31-May-1996 takaok Created. 00675 // 00676 //=================================================================== 00677 UINT Get31ModeFrom40ModeK( DWORD fdwConversion ) 00678 { 00679 UINT u31Mode = 0; 00680 00681 if ( !(fdwConversion & IME_CMODE_NATIVE) ) { 00682 00683 u31Mode |= IME_MODE_ALPHANUMERIC; 00684 } 00685 00686 if ( !(fdwConversion & IME_CMODE_FULLSHAPE) ) { 00687 00688 u31Mode |= KOREA_IME_MODE_SBCSCHAR; 00689 } 00690 00691 if ( fdwConversion & IME_CMODE_HANJACONVERT ) { 00692 u31Mode |= IME_MODE_HANJACONVERT; 00693 } 00694 00695 return u31Mode; 00696 } 00697 00698 //=================================================================== 00699 // TransGetConversionMode 00700 //======================== 00701 // 00702 // Japanese only 00703 // 00704 // 4.0 conversion mode => 3.1 conversion mode 00705 // 00706 // History: 00707 // 31-May-1996 takaok Created. 00708 // 00709 //=================================================================== 00710 LRESULT TransGetConversionMode( HIMC hImc ) 00711 { 00712 DWORD fdwConversion, fdwSentence; 00713 UINT u31Mode = 0; 00714 00715 // 00716 // get the 4.0 style conversion mode 00717 // 00718 ImmGetConversionStatus( hImc, &fdwConversion, &fdwSentence); 00719 return Get31ModeFrom40ModeJ( fdwConversion ); 00720 } 00721 00722 //=================================================================== 00723 // Get31ModeFrom40ModeJ 00724 //====================== 00725 // 00726 // Japanese only 00727 // 00728 // 4.0 conversion mode => 3.1 conversion mode 00729 // 00730 // History: 00731 // 31-May-1996 takaok Created. 00732 // 00733 //=================================================================== 00734 UINT Get31ModeFrom40ModeJ( DWORD fdwConversion ) 00735 { 00736 UINT u31Mode = 0; 00737 00738 // 00739 // translate the 4.0 style mode to the 3.x style conversion mode 00740 // 00741 if (fdwConversion & IME_CMODE_NATIVE) { 00742 if (fdwConversion & IME_CMODE_KATAKANA) { 00743 u31Mode |= IME_MODE_KATAKANA; 00744 } else { 00745 u31Mode |= IME_MODE_HIRAGANA; 00746 } 00747 } else { 00748 u31Mode |= IME_MODE_ALPHANUMERIC; 00749 } 00750 00751 if (fdwConversion & IME_CMODE_FULLSHAPE) { 00752 u31Mode |= IME_MODE_DBCSCHAR; 00753 } else { 00754 u31Mode |= JAPAN_IME_MODE_SBCSCHAR; 00755 } 00756 00757 if (fdwConversion & IME_CMODE_ROMAN) { 00758 u31Mode |= IME_MODE_ROMAN; 00759 } else { 00760 u31Mode |= IME_MODE_NOROMAN; 00761 } 00762 00763 if (fdwConversion & IME_CMODE_CHARCODE) { 00764 u31Mode |= IME_MODE_CODEINPUT; 00765 } else { 00766 u31Mode |= IME_MODE_NOCODEINPUT; 00767 } 00768 00769 return (u31Mode); 00770 } 00771 00772 00773 //=================================================================== 00774 // TransSetMode 00775 //============== 00776 // 00777 // KOREAN only 00778 // 00779 //=================================================================== 00780 LRESULT TransSetMode( HIMC hImc, LPIMESTRUCT lpIme ) 00781 { 00782 DWORD fdwConversion, fdwSentence, fdwNewConversion, fdwMask; 00783 UINT uPrevMode; 00784 UINT u31Mode; 00785 00786 // 00787 // Get current conversion mode and translate it to 00788 // the 3.1 style conversion mode. 00789 // 00790 ImmGetConversionStatus( hImc, &fdwConversion, &fdwSentence); 00791 uPrevMode = Get31ModeFrom40ModeK( fdwConversion ); 00792 00793 // 00794 // translate requested 3.1 conversion mode to 4.0 conversion mode 00795 // 00796 fdwNewConversion = 0; 00797 u31Mode = (UINT)lpIme->wParam; 00798 00799 if ( !(u31Mode & IME_MODE_ALPHANUMERIC) ) 00800 fdwNewConversion |= IME_CMODE_HANGEUL; 00801 if ( !(u31Mode & KOREA_IME_MODE_SBCSCHAR) ) 00802 fdwConversion |= IME_CMODE_FULLSHAPE; 00803 00804 // 00805 // In HWin3.1 there is no "not modification mode" 00806 // 00807 fdwMask = IME_CMODE_LANGUAGE|IME_CMODE_FULLSHAPE|IME_CMODE_HANJACONVERT; 00808 00809 // 00810 // set the new mode 00811 // 00812 fdwNewConversion = (fdwNewConversion & fdwMask) | (fdwConversion & ~fdwMask); 00813 if ( ImmSetConversionStatus( hImc, fdwNewConversion, fdwSentence) ) { 00814 return (LRESULT)uPrevMode; 00815 } else { 00816 return (LRESULT)0; 00817 } 00818 return FALSE; 00819 } 00820 00821 //=================================================================== 00822 // TransSendVKey 00823 //=============== 00824 // 00825 // Japanese only 00826 // 00827 //=================================================================== 00828 LRESULT TransSendVKey( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi ) 00829 { 00830 LRESULT lRet; 00831 00832 switch (lpIme->wParam) 00833 { 00834 // VK_DBE_xxx Support Check. 00835 case (DWORD)(-1): 00836 case (DWORD)(0x0000ffff): // from WOW16 00837 switch (lpIme->wCount) 00838 { 00839 case VK_DBE_ALPHANUMERIC: 00840 case VK_DBE_KATAKANA: 00841 case VK_DBE_HIRAGANA: 00842 case VK_DBE_SBCSCHAR: 00843 case VK_DBE_DBCSCHAR: 00844 case VK_DBE_ROMAN: 00845 case VK_DBE_NOROMAN: 00846 case VK_DBE_CODEINPUT: 00847 case VK_DBE_NOCODEINPUT: 00848 case VK_DBE_ENTERWORDREGISTERMODE: 00849 case VK_DBE_ENTERIMECONFIGMODE: 00850 case VK_DBE_ENTERDLGCONVERSIONMODE: 00851 case VK_DBE_DETERMINESTRING: 00852 case VK_DBE_FLUSHSTRING: 00853 case VK_CONVERT: 00854 lRet = TRUE; 00855 break; 00856 00857 default: 00858 lRet = FALSE; 00859 break; 00860 } 00861 break; 00862 00863 case VK_DBE_ALPHANUMERIC: 00864 case VK_DBE_KATAKANA: 00865 case VK_DBE_HIRAGANA: 00866 case VK_DBE_SBCSCHAR: 00867 case VK_DBE_DBCSCHAR: 00868 case VK_DBE_ROMAN: 00869 case VK_DBE_NOROMAN: 00870 case VK_DBE_CODEINPUT: 00871 case VK_DBE_NOCODEINPUT: 00872 lRet = TransVKDBEMode(hImc, lpIme->wParam); 00873 break; 00874 00875 case VK_DBE_ENTERWORDREGISTERMODE: 00876 { 00877 HKL hkl = GetKeyboardLayout(0L); 00878 00879 if ( fAnsi ) 00880 lRet = ImmConfigureIMEA(hkl, hWndApp, IME_CONFIG_REGISTERWORD, NULL); 00881 else 00882 lRet = ImmConfigureIMEW(hkl, hWndApp, IME_CONFIG_REGISTERWORD, NULL); 00883 } 00884 break; 00885 00886 case VK_DBE_ENTERIMECONFIGMODE: 00887 { 00888 HKL hkl = GetKeyboardLayout(0L); 00889 if (fAnsi) 00890 lRet = ImmConfigureIMEA(hkl, hWndApp, IME_CONFIG_GENERAL, NULL); 00891 else 00892 lRet = ImmConfigureIMEW(hkl, hWndApp, IME_CONFIG_GENERAL, NULL); 00893 } 00894 break; 00895 00896 case VK_DBE_ENTERDLGCONVERSIONMODE: 00897 #if defined(PENAPI) 00898 FInitPenUi(hIMC); 00899 #endif 00900 lRet = FALSE; 00901 break; 00902 00903 case VK_DBE_DETERMINESTRING: 00904 // Check there is the composition string or not. 00905 lRet = ImmNotifyIME( ImmGetContext(hWndApp), 00906 NI_COMPOSITIONSTR, 00907 CPS_COMPLETE, 00908 0L); 00909 break; 00910 00911 case VK_DBE_FLUSHSTRING: 00912 lRet = ImmNotifyIME( hImc, NI_COMPOSITIONSTR,CPS_CANCEL,0L); 00913 break; 00914 00915 case VK_CONVERT: 00916 lRet = ImmNotifyIME( hImc, NI_COMPOSITIONSTR, CPS_CONVERT, 0L); 00917 break; 00918 00919 default: 00920 break; 00921 } 00922 return lRet; 00923 } 00924 00925 //=================================================================== 00926 // TransEnterWordRegisterMode 00927 //=========================== 00928 // 00929 // Japanese only 00930 // 00931 //=================================================================== 00932 LRESULT TransEnterWordRegisterMode( HWND hWndApp, LPIMESTRUCT lpIme, BOOL fAnsi) 00933 { 00934 LRESULT lRet; 00935 HKL hkl = GetKeyboardLayout(0L); 00936 00937 if ( ! ImmIsIME(hkl) ) { 00938 return FALSE; 00939 } 00940 00941 if ( fAnsi ) { 00942 // 00943 // ANSI 00944 // 00945 REGISTERWORDA stReg = {NULL, NULL}; 00946 LPSTR lpsz1, lpsz2; 00947 00948 if (lpIme->lParam1&&(lpsz1=GlobalLock((HGLOBAL)lpIme->lParam1))) { 00949 stReg.lpWord = lpsz1; 00950 } 00951 if (lpIme->lParam2&&(lpsz2=GlobalLock((HGLOBAL)lpIme->lParam2))) { 00952 stReg.lpReading = lpsz2; 00953 } 00954 lRet = ImmConfigureIMEA(hkl,hWndApp,IME_CONFIG_REGISTERWORD, (LPVOID)&stReg); 00955 if (lpIme->lParam1 && lpsz1) 00956 GlobalUnlock((HGLOBAL)lpIme->lParam1); 00957 if (lpIme->lParam2 && lpsz2) 00958 GlobalUnlock((HGLOBAL)lpIme->lParam2); 00959 } else { 00960 // 00961 // UNICODE 00962 // 00963 REGISTERWORDW stReg = {NULL, NULL}; 00964 LPWSTR lpsz1, lpsz2; 00965 00966 if (lpIme->lParam1&&(lpsz1=GlobalLock((HGLOBAL)lpIme->lParam1))) { 00967 stReg.lpWord = lpsz1; 00968 } 00969 if (lpIme->lParam2&&(lpsz2=GlobalLock((HGLOBAL)lpIme->lParam2))) { 00970 stReg.lpReading = lpsz2; 00971 } 00972 lRet = ImmConfigureIMEW(hkl,hWndApp,IME_CONFIG_REGISTERWORD, (LPVOID)&stReg); 00973 if (lpIme->lParam1 && lpsz1) 00974 GlobalUnlock((HGLOBAL)lpIme->lParam1); 00975 if (lpIme->lParam2 && lpsz2) 00976 GlobalUnlock((HGLOBAL)lpIme->lParam2); 00977 } 00978 return lRet; 00979 } 00980 00981 00982 //=================================================================== 00983 // TransSetConversionFontEx 00984 //========================== 00985 // 00986 // Japanese only 00987 // 00988 //=================================================================== 00989 LRESULT TransSetConversionFontEx( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme, BOOL fAnsi) 00990 { 00991 LPINPUTCONTEXT pInputContext; 00992 LRESULT lRet; 00993 LPLOGFONTW lplf; 00994 LOGFONTW lfw; 00995 00996 pInputContext = ImmLockIMC( hImc ); 00997 if ( pInputContext == NULL ) { 00998 return 0L; 00999 } 01000 01001 lplf = (LPLOGFONTW)GlobalLock((HGLOBAL)lpIme->lParam1); 01002 if ( lplf == NULL ) 01003 { 01004 ImmUnlockIMC( hImc ); 01005 return 0L; 01006 } 01007 if ( fAnsi ) { 01008 memcpy( &lfw, lplf, sizeof(LOGFONTA) ); 01009 MultiByteToWideChar( CP_ACP, 01010 0, 01011 (LPCSTR)lplf->lfFaceName, // src 01012 LF_FACESIZE, // size of src 01013 lfw.lfFaceName, // destination buffer 01014 LF_FACESIZE ); // size of destination buffer 01015 } else { 01016 memcpy( &lfw, lplf, sizeof(LOGFONTW)); 01017 } 01018 GlobalUnlock((HGLOBAL)lpIme->lParam1); 01019 01020 if (( pInputContext->fdw31Compat & F31COMPAT_MCWVERTICAL)) { 01021 lRet = FixLogfont( &lfw, TRUE); 01022 } else { 01023 lRet = FixLogfont( &lfw, FALSE); 01024 } 01025 ImmUnlockIMC( hImc ); 01026 01027 if (lRet == FALSE ) { 01028 return FALSE; 01029 } 01030 01031 return MySetCompFont( hWndApp, hImc, &lfw ); 01032 } 01033 01034 01035 //=================================================================== 01036 // TransHanjaMode 01037 //================ 01038 // 01039 // Korean only 01040 // 01041 //=================================================================== 01042 LRESULT TransHanjaMode( HWND hWndApp, HIMC hImc, LPIMESTRUCT lpIme) 01043 { 01044 // BUGBUG: We will use this function instead of ImmEscape(). 01045 LRESULT lRet; 01046 PIMEDPI pImeDpi; 01047 DWORD dwThreadId = GetInputContextThread(hImc); 01048 01049 if (dwThreadId == 0) { 01050 RIPMSG1(RIP_WARNING, 01051 "TransHanjaMode: GetInputContextThread(%lx) failed.", hImc); 01052 return FALSE; 01053 } 01054 01055 pImeDpi = ImmLockImeDpi(GetKeyboardLayout(dwThreadId)); 01056 if (pImeDpi == NULL) 01057 return FALSE; 01058 01059 /* 01060 * Check if we need ANSI/Unicode conversion 01061 */ 01062 if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) { 01063 WCHAR wUni; 01064 CHAR chAnsi[2]; 01065 UINT i, dchSource; 01066 01067 //The 4th word of imestruct32 contains dchSource 01068 dchSource = *((LPSTR)lpIme + 3 * sizeof(WORD)); 01069 01070 chAnsi[0] = *((LPSTR)lpIme + dchSource); 01071 chAnsi[1] = *((LPSTR)lpIme + dchSource + 1); 01072 01073 i = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, chAnsi, 2, &wUni, 1); 01074 01075 if (i) { 01076 *((LPSTR)lpIme + dchSource) = (CHAR)LOWORD(LOBYTE(wUni)); 01077 *((LPSTR)lpIme + dchSource+1) = (CHAR)LOWORD(HIBYTE(wUni)); 01078 } 01079 else { 01080 ImmUnlockImeDpi(pImeDpi); 01081 return FALSE; 01082 } 01083 } 01084 01085 ImmUnlockImeDpi(pImeDpi); 01086 01087 if (lRet = ImmEscape(GetKeyboardLayout(0), hImc, IME_HANJAMODE, lpIme)) 01088 SendMessage(hWndApp, WM_IME_NOTIFY, IMN_OPENCANDIDATE, 1L); 01089 return (lRet); 01090 } 01091 01092 //=================================================================== 01093 // TransGetLevel 01094 //=============== 01095 // 01096 // Korean only 01097 // 01098 //=================================================================== 01099 LRESULT TransGetLevel( HWND hWndApp ) 01100 { 01101 UINT lRet; 01102 01103 if ( (lRet = NtUserGetAppImeLevel( hWndApp )) == 0 ) 01104 lRet = 1; // default level 01105 01106 return lRet; 01107 } 01108 01109 //=================================================================== 01110 // TransSetLevel 01111 //=============== 01112 // 01113 // Korean only 01114 // 01115 //=================================================================== 01116 LRESULT TransSetLevel( HWND hWndApp, LPIMESTRUCT lpIme) 01117 { 01118 DWORD dwLevel; 01119 01120 dwLevel = (DWORD)lpIme->wParam; 01121 if ( dwLevel >= 1 && dwLevel <= 5 ) { 01122 if ( NtUserSetAppImeLevel(hWndApp, dwLevel) ) { 01123 return TRUE; 01124 } 01125 } 01126 return FALSE; 01127 } 01128 01129 //=================================================================== 01130 // TransVKDBEMode 01131 //================ 01132 // 01133 // Japanese only 01134 // 01135 //=================================================================== 01136 LRESULT TransVKDBEMode( HIMC hImc, WPARAM wVKDBE ) 01137 { 01138 DWORD fdwConversion,fdwSentence; 01139 01140 ImmGetConversionStatus(hImc, &fdwConversion, &fdwSentence); 01141 01142 switch (wVKDBE) 01143 { 01144 case VK_DBE_ALPHANUMERIC: 01145 fdwConversion &= ~IME_CMODE_LANGUAGE; 01146 break; 01147 01148 case VK_DBE_KATAKANA: 01149 fdwConversion |= (IME_CMODE_JAPANESE | IME_CMODE_KATAKANA); 01150 break; 01151 01152 case VK_DBE_HIRAGANA: 01153 fdwConversion &= ~IME_CMODE_KATAKANA; 01154 fdwConversion |= IME_CMODE_JAPANESE; 01155 break; 01156 01157 case VK_DBE_SBCSCHAR: 01158 fdwConversion &= ~IME_CMODE_FULLSHAPE; 01159 break; 01160 01161 case VK_DBE_DBCSCHAR: 01162 fdwConversion |= IME_CMODE_FULLSHAPE; 01163 break; 01164 01165 case VK_DBE_ROMAN: 01166 fdwConversion |= IME_CMODE_ROMAN; 01167 break; 01168 01169 case VK_DBE_NOROMAN: 01170 fdwConversion &= ~IME_CMODE_ROMAN; 01171 break; 01172 01173 case VK_DBE_CODEINPUT: 01174 fdwConversion |= IME_CMODE_CHARCODE; 01175 break; 01176 01177 case VK_DBE_NOCODEINPUT: 01178 fdwConversion &= ~IME_CMODE_CHARCODE; 01179 break; 01180 01181 default: 01182 break; 01183 01184 } 01185 01186 return ImmSetConversionStatus(hImc, fdwConversion, fdwSentence); 01187 } 01188 01189 //=================================================================== 01190 // IsForegroundThread 01191 //=================== 01192 // 01193 // Check if the caller thread has the foreground window. 01194 // If hwnd is specified, the function checks if the creator 01195 // thread of the specified window has the foreground window. 01196 // 01197 //=================================================================== 01198 BOOL IsForegroundThread(HWND hwnd) 01199 { 01200 HWND hwndFG; 01201 DWORD dwThreadId; 01202 01203 hwndFG = GetForegroundWindow(); 01204 if ( IsWindow( hwnd ) ) { 01205 dwThreadId = GetWindowThreadProcessId( hwnd, NULL ); 01206 } else { 01207 dwThreadId = GetCurrentThreadId(); 01208 } 01209 return ( GetWindowThreadProcessId(hwndFG,NULL) == dwThreadId ); 01210 } 01211 01212 01213 //=================================================================== 01214 // SetFontForMCWVERTICAL 01215 //====================== 01216 // 01217 // Japanese only 01218 // 01219 // set/reset vertical writing font 01220 // 01221 //=================================================================== 01222 BOOL SetFontForMCWVERTICAL( HWND hWndApp, HIMC hImc, LPINPUTCONTEXT pInputContext, BOOL fVert ) 01223 { 01224 LOGFONTW lf; 01225 PCLIENTIMC pClientImc; 01226 01227 if ( pInputContext->fdwInit & INIT_LOGFONT) { 01228 // 01229 // If a font has ever been set, use it 01230 // 01231 BOOL fAnsi; 01232 01233 memcpy(&lf,&pInputContext->lfFont.W,sizeof(LOGFONTW)); 01234 // 01235 // check if the input context is unicode 01236 // 01237 pClientImc = ImmLockClientImc( hImc ); 01238 if (pClientImc == NULL) { 01239 return FALSE; 01240 } 01241 fAnsi = ! TestICF( pClientImc, IMCF_UNICODE ); 01242 ImmUnlockClientImc( pClientImc ); 01243 01244 if ( fAnsi ) { 01245 CHAR FaceNameA[ LF_FACESIZE ]; 01246 01247 // 01248 // we need a temporary buffer because MultiByteToWideChar 01249 // doesn't allow us to specify src==dest. 01250 // 01251 memcpy( FaceNameA, &lf.lfFaceName, LF_FACESIZE ); 01252 MultiByteToWideChar( CP_ACP, 01253 0, 01254 FaceNameA, // src 01255 LF_FACESIZE, // size of src 01256 lf.lfFaceName, // destination buffer 01257 LF_FACESIZE ); // size of destination buffer 01258 } 01259 } else { 01260 // 01261 // system font should be used as the default font 01262 // 01263 GetObjectW( GetStockObject(SYSTEM_FONT), sizeof(lf), (LPVOID)&lf ); 01264 } 01265 01266 // 01267 // put/remove '@' from the font facename. 01268 // "@facename" means vertical writing font 01269 // 01270 if ( FixLogfont( &lf, fVert ) == FALSE ) { 01271 return FALSE; 01272 } 01273 01274 return MySetCompFont( hWndApp, hImc, &lf ); 01275 } 01276 01277 //=================================================================== 01278 // FixLogfont 01279 //============ 01280 // 01281 // Japanese only 01282 // 01283 // put/remove '@' from the font facename. 01284 // "@facename" means vertical writing font 01285 // 01286 //=================================================================== 01287 BOOL FixLogfont( LPLOGFONTW lplfW, BOOL fVert ) 01288 { 01289 int i; 01290 01291 if ( fVert ) { 01292 // 01293 // convert the specified font to vertical writing font 01294 // 01295 lplfW->lfEscapement = 2700; 01296 lplfW->lfOrientation = 2700; 01297 if ((lplfW->lfCharSet == SHIFTJIS_CHARSET) && (lplfW->lfFaceName[0] != L'@')) { 01298 for(i=0;lplfW->lfFaceName[i];++i) // Search NULL 01299 if (i > (LF_FACESIZE-2)) // if not remain 2 char 01300 return FALSE; // then error 01301 // Because insert @ char 01302 01303 for( ; i>=0 ; --i ) // Copy facename from tail 01304 lplfW->lfFaceName[i+1] = lplfW->lfFaceName[i]; 01305 01306 lplfW->lfFaceName[0] = L'@'; // insert @ character 01307 } 01308 } else { 01309 // 01310 // convert the specified font to normal font 01311 // 01312 lplfW->lfEscapement = 0; 01313 lplfW->lfOrientation = 0; 01314 if ((lplfW->lfCharSet == SHIFTJIS_CHARSET) && (lplfW->lfFaceName[0] == L'@')) 01315 lstrcpynW(lplfW->lfFaceName,&(lplfW->lfFaceName[1]),LF_FACESIZE-1); 01316 } 01317 return TRUE; 01318 } 01319 01320 01321 //=================================================================== 01322 // MySetCompFont 01323 //============== 01324 // 01325 // Japanese only 01326 // 01327 //=================================================================== 01328 BOOL MySetCompFont( HWND hWndApp, HIMC hImc, LPLOGFONTW lplf ) 01329 { 01330 BOOL lRet = FALSE; 01331 DWORD dwCompat; 01332 PINPUTCONTEXT pInputContext; 01333 PCLIENTIMC pClientImc; 01334 LOGFONTW lfw; 01335 LPLOGFONTW lplfw = &lfw; 01336 BOOL fUnicode; 01337 01338 // BOGUS!! 01339 // Some application call SendIMEMessage(IME_SETCONVERSIONFONT) 01340 // when the apps is handling WM_PAINT. 01341 // New Win95 IME try to draw the UI during calling ImmSetCompositionFont, 01342 // and WM_PAINT will be sent in the API.... 01343 // To avoid this thing, WINNLS makes the notification to IME and APPS later. 01344 // ........ 01345 01346 if ( (pInputContext = ImmLockIMC(hImc)) != NULL ) { 01347 dwCompat = ImmGetAppCompatFlags( hImc ); 01348 pClientImc = ImmLockClientImc(hImc); 01349 if (pClientImc != NULL) { 01350 fUnicode = TestICF(pClientImc, IMCF_UNICODE); 01351 01352 ImmUnlockClientImc(pClientImc); 01353 01354 if ( fUnicode ) 01355 lplfw = &(pInputContext->lfFont.W); 01356 else 01357 LFontAtoLFontW( &(pInputContext->lfFont.A), lplfw ); 01358 01359 if ( RtlEqualMemory(lplfw, lplf, sizeof(LOGFONTA)-LF_FACESIZE) 01360 && !lstrcmp(lplfw->lfFaceName, lplf->lfFaceName) ) { 01361 01362 /* 01363 * Don't inform IME ahd UI when logfont is not changed. 01364 */ 01365 lRet = TRUE; 01366 01367 } else if ( dwCompat & IMECOMPAT_UNSYNC31IMEMSG ) { 01368 01369 memcpy( &(pInputContext->lfFont.W), lplf, sizeof(LOGFONT)); 01370 if ( dwCompat & IMECOMPAT_UNSYNC31IMEMSG2 ) 01371 /* 01372 * BOGUS!! for PageMaker5J 01373 */ 01374 lRet = PostMessage( hWndApp, WM_IME_SYSTEM, IMS_SETCOMPOSITIONFONT, 0 ); 01375 else 01376 lRet = MyPostImsMessage( hWndApp, IMS_SETCOMPOSITIONFONT, 0); 01377 01378 } else { 01379 01380 lRet = ImmSetCompositionFont( hImc, lplf ); 01381 01382 } 01383 } 01384 ImmUnlockIMC( hImc ); 01385 } 01386 return lRet; 01387 } 01388 01389 //=================================================================== 01390 // MySetCompWindow 01391 //================ 01392 // 01393 // Japanese only 01394 // 01395 //=================================================================== 01396 BOOL MySetCompWindow( 01397 HWND hWndApp, 01398 HIMC hImc, 01399 LPCOMPOSITIONFORM lpcof 01400 ) 01401 { 01402 BOOL fRet = FALSE; 01403 DWORD dwCompat; 01404 PINPUTCONTEXT pInputContext; 01405 01406 // BOGUS!! 01407 // Some application call SendIMEMessage(IME_SETCONVERSIONWINDOW) 01408 // when the apps is handling WM_PAINT. 01409 // New Win95 IME try to draw the UI during calling ImmSetCompositionWindow, 01410 // and WM_PAINT will be sent in the API.... 01411 // To avoid this thing, WINNLS makes the notification to IME and APPS later. 01412 // ........ 01413 if ( (pInputContext = ImmLockIMC(hImc)) != NULL ) { 01414 dwCompat = ImmGetAppCompatFlags( hImc ); 01415 if ( dwCompat & IMECOMPAT_UNSYNC31IMEMSG ) { 01416 memcpy( &(pInputContext->cfCompForm), lpcof, sizeof(COMPOSITIONFORM)); 01417 if ( dwCompat & IMECOMPAT_UNSYNC31IMEMSG2 ) { 01418 /* 01419 * BOGUS!! for PageMaker5J 01420 */ 01421 fRet = PostMessage( hWndApp, WM_IME_SYSTEM, IMS_SETCOMPOSITIONWINDOW, 0 ); 01422 } else { 01423 fRet = MyPostImsMessage( hWndApp, IMS_SETCOMPOSITIONWINDOW, 0 ); 01424 } 01425 } else { 01426 pInputContext->fdw31Compat |= F31COMPAT_CALLFROMWINNLS; 01427 fRet = ImmSetCompositionWindow( hImc, lpcof ); 01428 } 01429 ImmUnlockIMC( hImc ); 01430 } 01431 return fRet; 01432 } 01433 01434 //=================================================================== 01435 // MySetCandidateWindow 01436 //===================== 01437 // 01438 // Japanese only 01439 // 01440 //=================================================================== 01441 BOOL MySetCandidateWindow( HWND hWndApp, HIMC hImc, LPCANDIDATEFORM lpcaf) 01442 { 01443 BOOL fRet = FALSE; 01444 DWORD dwCompat; 01445 PINPUTCONTEXT pInputContext; 01446 01447 // BOGUS!! 01448 // Some application call SendIMEMessage(IME_SETCONVERSIONWINDOW) 01449 // when the apps is handling WM_PAINT. 01450 // New Win95 IME try to draw the UI during calling ImmSetCandidateWindow, 01451 // and WM_PAINT will be sent in the API.... 01452 // To avoid this thing, WINNLS makes the notification to IME and APPS later. 01453 // ........ 01454 if ( (pInputContext = ImmLockIMC(hImc)) != NULL ) { 01455 dwCompat = ImmGetAppCompatFlags( hImc ); 01456 if ( dwCompat & IMECOMPAT_UNSYNC31IMEMSG ) { 01457 memcpy( &(pInputContext->cfCandForm[lpcaf->dwIndex]), lpcaf, sizeof(CANDIDATEFORM)); 01458 fRet = MyPostImsMessage( hWndApp, IMS_SETCANDIDATEPOS, lpcaf->dwIndex ); 01459 } else { 01460 fRet = ImmSetCandidateWindow( hImc, lpcaf ); 01461 } 01462 ImmUnlockIMC( hImc ); 01463 } 01464 return fRet; 01465 } 01466 01467 //=================================================================== 01468 // MyPostImsMessage 01469 //================== 01470 // 01471 // Japanese only 01472 // 01473 // BOGUS!! 01474 // Some application call SendIMEMessage(IME_SETCONVERSIONWINDOW) 01475 // when the apps is handling WM_PAINT. 01476 // New Win95 IME try to draw the UI during calling ImmSetCompositionWindow, 01477 // and WM_PAINT will be sent in the API.... 01478 // To avoid this thing, WINNLS makes the notification to IME and APPS later. 01479 // ........ 01480 //=================================================================== 01481 BOOL MyPostImsMessage( HWND hWndApp, WPARAM wParam, LPARAM lParam ) 01482 { 01483 HWND hDefIMEWnd; 01484 BOOL fRet = FALSE; 01485 01486 hDefIMEWnd = ImmGetDefaultIMEWnd(hWndApp); 01487 if ( hDefIMEWnd != NULL ) { 01488 if ( PostMessage( hDefIMEWnd, WM_IME_SYSTEM, wParam, lParam) ) { 01489 fRet = TRUE; 01490 } 01491 } 01492 return fRet; 01493 }

Generated on Sat May 15 19:42:03 2004 for test by doxygen 1.3.7