test: transsub.c Source File

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 }