DragonNest/Common/EtInterface/EtUIIME.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

927 lines
No EOL
26 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#include "EtUIIME.h"
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
INPUTCONTEXT* (WINAPI * CEtUIIME::_ImmLockIMC)( HIMC ) = CEtUIIME::Dummy_ImmLockIMC;
BOOL (WINAPI * CEtUIIME::_ImmUnlockIMC)( HIMC ) = CEtUIIME::Dummy_ImmUnlockIMC;
LPVOID (WINAPI * CEtUIIME::_ImmLockIMCC)( HIMCC ) = CEtUIIME::Dummy_ImmLockIMCC;
BOOL (WINAPI * CEtUIIME::_ImmUnlockIMCC)( HIMCC ) = CEtUIIME::Dummy_ImmUnlockIMCC;
BOOL (WINAPI * CEtUIIME::_ImmDisableTextFrameService)( DWORD ) = CEtUIIME::Dummy_ImmDisableTextFrameService;
LONG (WINAPI * CEtUIIME::_ImmGetCompositionStringW)( HIMC, DWORD, LPVOID, DWORD ) = CEtUIIME::Dummy_ImmGetCompositionStringW;
DWORD (WINAPI * CEtUIIME::_ImmGetCandidateListW)( HIMC, DWORD, LPCANDIDATELIST, DWORD ) = CEtUIIME::Dummy_ImmGetCandidateListW;
HIMC (WINAPI * CEtUIIME::_ImmGetContext)( HWND ) = CEtUIIME::Dummy_ImmGetContext;
BOOL (WINAPI * CEtUIIME::_ImmReleaseContext)( HWND, HIMC ) = CEtUIIME::Dummy_ImmReleaseContext;
HIMC (WINAPI * CEtUIIME::_ImmAssociateContext)( HWND, HIMC ) = CEtUIIME::Dummy_ImmAssociateContext;
BOOL (WINAPI * CEtUIIME::_ImmGetOpenStatus)( HIMC ) = CEtUIIME::Dummy_ImmGetOpenStatus;
BOOL (WINAPI * CEtUIIME::_ImmSetOpenStatus)( HIMC, BOOL ) = CEtUIIME::Dummy_ImmSetOpenStatus;
BOOL (WINAPI * CEtUIIME::_ImmGetConversionStatus)( HIMC, LPDWORD, LPDWORD ) = CEtUIIME::Dummy_ImmGetConversionStatus;
HWND (WINAPI * CEtUIIME::_ImmGetDefaultIMEWnd)( HWND ) = CEtUIIME::Dummy_ImmGetDefaultIMEWnd;
UINT (WINAPI * CEtUIIME::_ImmGetIMEFileNameA)( HKL, LPSTR, UINT ) = CEtUIIME::Dummy_ImmGetIMEFileNameA;
UINT (WINAPI * CEtUIIME::_ImmGetVirtualKey)( HWND ) = CEtUIIME::Dummy_ImmGetVirtualKey;
BOOL (WINAPI * CEtUIIME::_ImmNotifyIME)( HIMC, DWORD, DWORD, DWORD ) = CEtUIIME::Dummy_ImmNotifyIME;
BOOL (WINAPI * CEtUIIME::_ImmSetConversionStatus)( HIMC, DWORD, DWORD ) = CEtUIIME::Dummy_ImmSetConversionStatus;
BOOL (WINAPI * CEtUIIME::_ImmSimulateHotKey)( HWND, DWORD ) = CEtUIIME::Dummy_ImmSimulateHotKey;
BOOL (WINAPI * CEtUIIME::_ImmIsIME)( HKL ) = CEtUIIME::Dummy_ImmIsIME;
UINT (WINAPI * CEtUIIME::_GetReadingString)( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT ) = CEtUIIME::Dummy_GetReadingString; // Traditional Chinese IME
BOOL (WINAPI * CEtUIIME::_ShowReadingWindow)( HIMC, BOOL ) = CEtUIIME::Dummy_ShowReadingWindow; // Traditional Chinese IME
BOOL (APIENTRY * CEtUIIME::_VerQueryValueA)( const LPVOID, LPSTR, LPVOID *, PUINT ) = CEtUIIME::Dummy_VerQueryValueA;
BOOL (APIENTRY * CEtUIIME::_GetFileVersionInfoA)( LPSTR, DWORD, DWORD, LPVOID )= CEtUIIME::Dummy_GetFileVersionInfoA;
DWORD (APIENTRY * CEtUIIME::_GetFileVersionInfoSizeA)( LPSTR, LPDWORD ) = CEtUIIME::Dummy_GetFileVersionInfoSizeA;
int CEtUIIME::s_nRefCount = 0;
HINSTANCE CEtUIIME::s_hDllImm32 = NULL;
HINSTANCE CEtUIIME::s_hDllIme = NULL;
HINSTANCE CEtUIIME::s_hDllVer = NULL;
HIMC CEtUIIME::s_hImcDef = NULL;
CEtUIIME::IMESTATE CEtUIIME::s_ImeState;
bool CEtUIIME::s_bEnableImeSystem = true;
int CEtUIIME::s_nCompCaret = 0;
int CEtUIIME::s_nFirstTargetConv = -1;
float CEtUIIME::s_fCompStringX;
float CEtUIIME::s_fCompStringY;
BYTE CEtUIIME::s_abyCompStringAttr[ MAX_COMPSTRING_SIZE ];
DWORD CEtUIIME::s_adwCompStringClause[ MAX_COMPSTRING_SIZE ];
WCHAR CEtUIIME::s_wszReadingString[ 32 ];
HKL CEtUIIME::s_hklCurrent = NULL;
SCandList CEtUIIME::s_CandList;
bool CEtUIIME::s_bVerticalCand = true;
bool CEtUIIME::s_bShowReadingWindow = false;
bool CEtUIIME::s_bHorizontalReading = true;
CEtUIUniBuffer CEtUIIME::s_CompString;
std::vector< SInputLocale > CEtUIIME::s_vecLocale;
LPWSTR CEtUIIME::s_pwszCurrIndicator = NULL;
WCHAR CEtUIIME::s_aszIndicator[ 5 ][ 3 ] =
{
L"En",
L"\x7B80",
L"\x7E41",
L"\xAC00",
L"\x3042",
};
bool CEtUIIME::s_bChineseIME = false;
bool CEtUIIME::s_bInsertOnType = false;
#if defined(DEBUG) || defined(_DEBUG)
bool CEtUIIME::m_bIMEStaticMsgProcCalled = true;
#endif
bool CEtUIIME::s_bHideCaret = false;
bool CEtUIIME::s_bDisableIMEonKillFocus = false;
bool CEtUIIME::s_bRESULTSTR_NotSendComp = false;
bool CEtUIIME::s_bProcess_GCS_COMPCLAUSE = true;
bool CEtUIIME::s_bDisableIMEonIMEControl = false;
CEtUIIME::CEtUIIME( void )
{
Initialize();
if( _ImmDisableTextFrameService )
{
_ImmDisableTextFrameService( 0 ); // Disable TSF for the current process
}
s_bEnableImeSystem = true;
}
CEtUIIME::~CEtUIIME(void)
{
Uninitialize();
}
void CEtUIIME::Initialize()
{
++s_nRefCount;
if( s_hDllImm32 )
{
return;
}
char szPath[ MAX_PATH + 1 ];
s_CompString.SetBufferSize( MAX_COMPSTRING_SIZE );
if( !::GetSystemDirectory( szPath, MAX_PATH + 1 ) )
{
return;
}
strcat( szPath, IMM32_DLLNAME );
s_hDllImm32 = LoadLibrary( szPath );
if( s_hDllImm32 )
{
*( FARPROC * )&_ImmLockIMC = GetProcAddress( s_hDllImm32, "ImmLockIMC" );
*( FARPROC * )&_ImmUnlockIMC = GetProcAddress( s_hDllImm32, "ImmUnlockIMC" );
*( FARPROC * )&_ImmLockIMCC = GetProcAddress( s_hDllImm32, "ImmLockIMCC" );
*( FARPROC * )&_ImmUnlockIMCC = GetProcAddress( s_hDllImm32, "ImmUnlockIMCC" );
*( FARPROC * )&_ImmDisableTextFrameService = GetProcAddress( s_hDllImm32, "ImmDisableTextFrameService" );
*( FARPROC * )&_ImmGetCompositionStringW = GetProcAddress( s_hDllImm32, "ImmGetCompositionStringW" );
*( FARPROC * )&_ImmGetCandidateListW = GetProcAddress( s_hDllImm32, "ImmGetCandidateListW" );
*( FARPROC * )&_ImmGetContext = GetProcAddress( s_hDllImm32, "ImmGetContext" );
*( FARPROC * )&_ImmReleaseContext = GetProcAddress( s_hDllImm32, "ImmReleaseContext" );
*( FARPROC * )&_ImmAssociateContext = GetProcAddress( s_hDllImm32, "ImmAssociateContext" );
*( FARPROC * )&_ImmGetOpenStatus = GetProcAddress( s_hDllImm32, "ImmGetOpenStatus" );
*( FARPROC * )&_ImmSetOpenStatus = GetProcAddress( s_hDllImm32, "ImmSetOpenStatus" );
*( FARPROC * )&_ImmGetConversionStatus = GetProcAddress( s_hDllImm32, "ImmGetConversionStatus" );
*( FARPROC * )&_ImmGetDefaultIMEWnd = GetProcAddress( s_hDllImm32, "ImmGetDefaultIMEWnd" );
*( FARPROC * )&_ImmGetIMEFileNameA = GetProcAddress( s_hDllImm32, "ImmGetIMEFileNameA" );
*( FARPROC * )&_ImmGetVirtualKey = GetProcAddress( s_hDllImm32, "ImmGetVirtualKey" );
*( FARPROC * )&_ImmNotifyIME = GetProcAddress( s_hDllImm32, "ImmNotifyIME" );
*( FARPROC * )&_ImmSetConversionStatus = GetProcAddress( s_hDllImm32, "ImmSetConversionStatus" );
*( FARPROC * )&_ImmSimulateHotKey = GetProcAddress( s_hDllImm32, "ImmSimulateHotKey" );
*( FARPROC * )&_ImmIsIME = GetProcAddress( s_hDllImm32, "ImmIsIME" );
}
if( !::GetSystemDirectory( szPath, MAX_PATH + 1 ) )
{
return;
}
strcat( szPath, VER_DLLNAME );
s_hDllVer = LoadLibrary( szPath );
if( s_hDllVer )
{
*( FARPROC * )&_VerQueryValueA = GetProcAddress( s_hDllVer, "VerQueryValueA" );
*( FARPROC * )&_GetFileVersionInfoA = GetProcAddress( s_hDllVer, "GetFileVersionInfoA" );
*( FARPROC * )&_GetFileVersionInfoSizeA = GetProcAddress( s_hDllVer, "GetFileVersionInfoSizeA" );
}
StaticOnCreateDevice();
}
void CEtUIIME::Uninitialize()
{
--s_nRefCount;
if( s_nRefCount > 0 )
return;
if( s_hDllImm32 )
{
_ImmLockIMC = Dummy_ImmLockIMC;
_ImmUnlockIMC = Dummy_ImmUnlockIMC;
_ImmLockIMCC = Dummy_ImmLockIMCC;
_ImmUnlockIMCC = Dummy_ImmUnlockIMCC;
_ImmDisableTextFrameService = Dummy_ImmDisableTextFrameService;
_ImmGetCompositionStringW = Dummy_ImmGetCompositionStringW;
_ImmGetCandidateListW = Dummy_ImmGetCandidateListW;
_ImmGetContext = Dummy_ImmGetContext;
_ImmReleaseContext = Dummy_ImmReleaseContext;
_ImmAssociateContext = Dummy_ImmAssociateContext;
_ImmGetOpenStatus = Dummy_ImmGetOpenStatus;
_ImmSetOpenStatus = Dummy_ImmSetOpenStatus;
_ImmGetConversionStatus = Dummy_ImmGetConversionStatus;
_ImmGetDefaultIMEWnd = Dummy_ImmGetDefaultIMEWnd;
_ImmGetIMEFileNameA = Dummy_ImmGetIMEFileNameA;
_ImmGetVirtualKey = Dummy_ImmGetVirtualKey;
_ImmNotifyIME = Dummy_ImmNotifyIME;
_ImmSetConversionStatus = Dummy_ImmSetConversionStatus;
_ImmSimulateHotKey = Dummy_ImmSimulateHotKey;
_ImmIsIME = Dummy_ImmIsIME;
FreeLibrary( s_hDllImm32 );
s_hDllImm32 = NULL;
}
if( s_hDllIme )
{
_GetReadingString = Dummy_GetReadingString;
_ShowReadingWindow = Dummy_ShowReadingWindow;
FreeLibrary( s_hDllIme );
s_hDllIme = NULL;
}
if( s_hDllVer )
{
_VerQueryValueA = Dummy_VerQueryValueA;
_GetFileVersionInfoA = Dummy_GetFileVersionInfoA;
_GetFileVersionInfoSizeA = Dummy_GetFileVersionInfoSizeA;
FreeLibrary( s_hDllVer );
s_hDllVer = NULL;
}
}
void CEtUIIME::StaticOnCreateDevice()
{
s_hImcDef = _ImmGetContext( GetEtDevice()->GetHWnd() );
_ImmReleaseContext( GetEtDevice()->GetHWnd(), s_hImcDef );
}
bool CEtUIIME::StaticMsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
HIMC hImc;
if( !s_bEnableImeSystem )
{
return false;
}
#if defined(DEBUG) || defined(_DEBUG)
m_bIMEStaticMsgProcCalled = true;
#endif
switch( uMsg )
{
case WM_ACTIVATEAPP:
if( wParam )
{
UINT i, cKL;
HKL *phKL;
cKL = GetKeyboardLayoutList( 0, NULL );
s_vecLocale.clear();
phKL = new HKL[ cKL ];
if( phKL )
{
GetKeyboardLayoutList( cKL, phKL );
for( i = 0; i < cKL; i++ )
{
int e;
SInputLocale Locale;
bool bBreak;
if( ( PRIMARYLANGID( LOWORD( phKL[ i ] ) ) == LANG_CHINESE || PRIMARYLANGID( LOWORD( phKL[ i ] ) ) == LANG_JAPANESE ||
PRIMARYLANGID( LOWORD( phKL[ i ] ) ) == LANG_KOREAN ) && ( !_ImmIsIME( phKL[ i ] ) ) )
{
continue;
}
bBreak = false;
for( e = 0; e < ( int )s_vecLocale.size(); e++ )
{
if( LOWORD( s_vecLocale[ e ].m_hKL ) == LOWORD( phKL[ i ] ) )
{
bBreak = true;
break;
}
}
if( bBreak )
{
break;
}
WCHAR wszDesc[ 128 ] = L"";
Locale.m_hKL = phKL[ i ];
switch( PRIMARYLANGID( LOWORD( phKL[ i ] ) ) )
{
case LANG_CHINESE:
switch( SUBLANGID( LOWORD( phKL[ i ] ) ) )
{
case SUBLANG_CHINESE_SIMPLIFIED:
wcscpy_s( Locale.m_wszLangAbb, 3, s_aszIndicator[ INDICATOR_CHS ] );
break;
case SUBLANG_CHINESE_TRADITIONAL:
wcscpy_s( Locale.m_wszLangAbb, 3, s_aszIndicator[ INDICATOR_CHT ] );
break;
default:
GetLocaleInfoW( MAKELCID( LOWORD( phKL[ i ] ), SORT_DEFAULT ), LOCALE_SABBREVLANGNAME, wszDesc, 128 );
Locale.m_wszLangAbb[ 0 ] = wszDesc[ 0 ];
Locale.m_wszLangAbb[ 1 ] = towlower( wszDesc[ 1 ] );
Locale.m_wszLangAbb[ 2 ] = L'\0';
break;
}
break;
case LANG_KOREAN:
wcscpy_s( Locale.m_wszLangAbb, 3, s_aszIndicator[ INDICATOR_KOREAN ] );
break;
case LANG_JAPANESE:
wcscpy_s( Locale.m_wszLangAbb, 3, s_aszIndicator[ INDICATOR_JAPANESE ] );
break;
default:
GetLocaleInfoW( MAKELCID( LOWORD( phKL[ i ] ), SORT_DEFAULT ), LOCALE_SABBREVLANGNAME, wszDesc, 128 );
Locale.m_wszLangAbb[ 0 ] = wszDesc[ 0 ];
Locale.m_wszLangAbb[ 1 ] = towlower( wszDesc[ 1 ] );
Locale.m_wszLangAbb[ 2 ] = L'\0';
break;
}
GetLocaleInfoW( MAKELCID( LOWORD( phKL[ i ] ), SORT_DEFAULT ), LOCALE_SLANGUAGE, wszDesc, 128 );
wcscpy_s( Locale.m_wszLang, 64, wszDesc );
s_vecLocale.push_back( Locale );
}
delete [] phKL;
}
}
break;
case WM_INPUTLANGCHANGE:
{
UINT uLang;
uLang = GetPrimaryLanguage();
CheckToggleState();
if( uLang != GetPrimaryLanguage() )
{
s_bInsertOnType = ( GetPrimaryLanguage() == LANG_KOREAN );
}
SetupImeApi();
if( _ShowReadingWindow )
{
hImc = _ImmGetContext( GetEtDevice()->GetHWnd() );
if( hImc )
{
_ShowReadingWindow( hImc, false );
_ImmReleaseContext( GetEtDevice()->GetHWnd(), hImc );
}
}
}
return true;
case WM_IME_SETCONTEXT:
lParam = 0;
return false;
case WM_IME_STARTCOMPOSITION:
ResetCompositionString();
s_bHideCaret = true;
return true;
case WM_IME_COMPOSITION:
return false;
}
return false;
}
void CEtUIIME::SendKey( BYTE nVirtKey )
{
keybd_event( nVirtKey, 0, 0, 0 );
keybd_event( nVirtKey, 0, KEYEVENTF_KEYUP, 0 );
}
#define LCID_INVARIANT MAKELCID( MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ), SORT_DEFAULT )
DWORD CEtUIIME::GetImeId( UINT uIndex )
{
static HKL hklPrev = 0;
static DWORD dwID[ 2 ] = { 0, 0 };
DWORD dwVerSize;
DWORD dwVerHandle;
void *pVerBuffer;
void *pVerData;
UINT uVerData;
char szTmp[ 1024 ];
if( uIndex >= sizeof( dwID ) / sizeof( dwID[ 0 ] ) )
{
return 0;
}
if( hklPrev == s_hklCurrent )
{
return dwID[ uIndex ];
}
hklPrev = s_hklCurrent;
if( !( ( s_hklCurrent == _CHT_HKL ) || ( s_hklCurrent == _CHT_HKL2 ) || ( s_hklCurrent == _CHS_HKL ) ) )
{
dwID[ 0 ] = dwID[ 1 ] = 0;
return dwID[ uIndex ];
}
if( !_ImmGetIMEFileNameA( s_hklCurrent, szTmp, ( sizeof( szTmp ) / sizeof( szTmp[ 0 ] ) ) - 1 ) )
{
dwID[ 0 ] = dwID[ 1 ] = 0;
return dwID[ uIndex ];
}
if( !_GetReadingString )
{
if( ( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHT_IMEFILENAME1, -1 ) != CSTR_EQUAL ) &&
( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHT_IMEFILENAME2, -1 ) != CSTR_EQUAL ) &&
( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHT_IMEFILENAME3, -1 ) != CSTR_EQUAL ) &&
( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHS_IMEFILENAME1, -1 ) != CSTR_EQUAL ) &&
( CompareStringA( LCID_INVARIANT, NORM_IGNORECASE, szTmp, -1, CHS_IMEFILENAME2, -1 ) != CSTR_EQUAL ) )
{
dwID[ 0 ] = dwID[ 1 ] = 0;
return dwID[ uIndex ];
}
}
dwVerSize = _GetFileVersionInfoSizeA( szTmp, &dwVerHandle );
if( dwVerSize )
{
pVerBuffer = HeapAlloc( GetProcessHeap(), 0, dwVerSize );
if( pVerBuffer )
{
if( _GetFileVersionInfoA( szTmp, dwVerHandle, dwVerSize, pVerBuffer ) )
{
if( _VerQueryValueA( pVerBuffer, "\\", &pVerData, &uVerData ) )
{
DWORD dwVer;
dwVer = ( ( VS_FIXEDFILEINFO * )pVerData )->dwFileVersionMS;
dwVer = ( dwVer & 0x00ff0000 ) << 8 | ( dwVer & 0x000000ff ) << 16;
if( _GetReadingString
||
( GetLanguage() == LANG_CHT &&
( dwVer == MAKEIMEVERSION( 4, 2 ) ||
dwVer == MAKEIMEVERSION( 4, 3 ) ||
dwVer == MAKEIMEVERSION( 4, 4 ) ||
dwVer == MAKEIMEVERSION( 5, 0 ) ||
dwVer == MAKEIMEVERSION( 5, 1 ) ||
dwVer == MAKEIMEVERSION( 5, 2 ) ||
dwVer == MAKEIMEVERSION( 6, 0 ) ) )
||
( GetLanguage() == LANG_CHS &&
( dwVer == MAKEIMEVERSION( 4, 1 ) ||
dwVer == MAKEIMEVERSION( 4, 2 ) ||
dwVer == MAKEIMEVERSION( 5, 3 ) ) )
)
{
dwID[ 0 ] = dwVer | GetLanguage();
dwID[ 1 ] = ( ( VS_FIXEDFILEINFO * )pVerData )->dwFileVersionLS;
}
}
}
HeapFree( GetProcessHeap(), 0, pVerBuffer );
}
}
return dwID[ uIndex ];
}
void CEtUIIME::CheckInputLocale()
{
static HKL hklPrev = 0;
s_hklCurrent = GetKeyboardLayout( 0 );
if( hklPrev == s_hklCurrent )
{
return;
}
hklPrev = s_hklCurrent;
switch ( GetPrimaryLanguage() )
{
case LANG_CHINESE:
s_bVerticalCand = true;
switch ( GetSubLanguage() )
{
case SUBLANG_CHINESE_SIMPLIFIED:
s_pwszCurrIndicator = s_aszIndicator[ INDICATOR_CHS ];
s_bVerticalCand = GetImeId() == 0;
break;
case SUBLANG_CHINESE_TRADITIONAL:
s_pwszCurrIndicator = s_aszIndicator[ INDICATOR_CHT ];
break;
default:
s_pwszCurrIndicator = s_aszIndicator[ INDICATOR_NON_IME ];
break;
}
break;
case LANG_KOREAN:
s_pwszCurrIndicator = s_aszIndicator[ INDICATOR_KOREAN ];
s_bVerticalCand = false;
break;
case LANG_JAPANESE:
s_pwszCurrIndicator = s_aszIndicator[ INDICATOR_JAPANESE ];
s_bVerticalCand = true;
break;
default:
s_pwszCurrIndicator = s_aszIndicator[ INDICATOR_NON_IME ];
break;
}
if( s_pwszCurrIndicator == s_aszIndicator[ INDICATOR_NON_IME ] )
{
WCHAR wszLang[ 5 ];
GetLocaleInfoW( MAKELCID( LOWORD( s_hklCurrent ), SORT_DEFAULT ), LOCALE_SABBREVLANGNAME, wszLang, 5 );
s_pwszCurrIndicator[ 0 ] = wszLang[ 0 ];
s_pwszCurrIndicator[ 1 ] = towlower( wszLang[ 1 ] );
}
}
void CEtUIIME::CheckToggleState()
{
bool bIme;
HIMC hImc;
CheckInputLocale();
bIme = _ImmIsIME( s_hklCurrent ) != 0;
s_bChineseIME = ( GetPrimaryLanguage() == LANG_CHINESE ) && bIme;
hImc = _ImmGetContext( GetEtDevice()->GetHWnd() );
if( hImc != NULL )
{
if( s_bChineseIME )
{
DWORD dwConvMode, dwSentMode;
_ImmGetConversionStatus( hImc, &dwConvMode, &dwSentMode );
if( dwConvMode & IME_CMODE_NATIVE )
{
s_ImeState = IMEUI_STATE_ON;
}
else
{
s_ImeState = IMEUI_STATE_ENGLISH;
}
}
else
{
if( ( bIme ) && ( _ImmGetOpenStatus( hImc ) != 0 ) )
{
s_ImeState = IMEUI_STATE_ON;
}
else
{
s_ImeState = IMEUI_STATE_OFF;
}
}
_ImmReleaseContext( GetEtDevice()->GetHWnd(), hImc );
}
else
{
s_ImeState = IMEUI_STATE_OFF;
}
}
void CEtUIIME::SetIMEMode ( DWORD dwNewConvMode, DWORD dwNewSentMode, BOOL fFlag )
{
HIMC hImc;
DWORD dwConvMode, dwSentMode;
BOOL fRet;
// Note : <20>Է<EFBFBD> <20><><EFBFBD>ؽ<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ɴϴ<C9B4>.
//
hImc = _ImmGetContext(GetEtDevice()->GetHWnd());
if (hImc)
{
// Note : <20><><EFBFBD><EFBFBD> IME <20><><EFBFBD>¸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ɴϴ<C9B4>.
//
_ImmGetConversionStatus ( hImc, &dwConvMode, &dwSentMode );
// Note : <20><><EFBFBD>޵<EFBFBD> <20>ɼ<EFBFBD><C9BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> IME <20><><EFBFBD>¸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
//
if (fFlag)
{
fRet = _ImmSetConversionStatus ( hImc, dwConvMode | dwNewConvMode, dwSentMode | dwNewSentMode );
if( dwNewConvMode&IME_CMODE_JAPANESE )
{
// Note : <20>Ϻ<EFBFBD><CFBA><EFBFBD> <20>Է¸<D4B7><C2B8><EFBFBD><E5BFA1> <20>׻<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> !<21><> <20>ٿ<EFBFBD><D9BF><EFBFBD>.
//
_ImmSetOpenStatus ( hImc, !fFlag );
}
}
else
{
_ImmSetConversionStatus ( hImc, dwConvMode&~dwNewConvMode, dwSentMode&~dwNewSentMode );
if( dwNewConvMode&IME_CMODE_JAPANESE )
{
_ImmSetOpenStatus ( hImc, fFlag );
}
}
// Note : <20>Է<EFBFBD> <20><><EFBFBD>ؽ<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.
//
_ImmReleaseContext ( GetEtDevice()->GetHWnd(), hImc );
}
}
bool CEtUIIME::IsNativeMode()
{
HIMC hIMC = _ImmGetContext(GetEtDevice()->GetHWnd());
if ( hIMC )
{
DWORD dwComposition, dwSentence;
_ImmGetConversionStatus(hIMC, &dwComposition, &dwSentence);
_ImmReleaseContext ( GetEtDevice()->GetHWnd(), hIMC );
if ( (dwComposition&IME_CMODE_NATIVE)!=NULL ) return true;
}
return false;
}
void CEtUIIME::SetupImeApi()
{
char szImeFile[ MAX_PATH + 1 ];
_GetReadingString = NULL;
_ShowReadingWindow = NULL;
if( _ImmGetIMEFileNameA( s_hklCurrent, szImeFile, sizeof( szImeFile ) / sizeof( szImeFile[ 0 ] ) - 1 ) == 0 )
{
return;
}
if( s_hDllIme )
{
FreeLibrary( s_hDllIme );
}
s_hDllIme = LoadLibraryA( szImeFile );
if( !s_hDllIme )
{
return;
}
_GetReadingString = ( UINT ( WINAPI * )( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT ) )( GetProcAddress( s_hDllIme, "GetReadingString" ) );
_ShowReadingWindow =( BOOL ( WINAPI * )( HIMC, BOOL ) )( GetProcAddress( s_hDllIme, "ShowReadingWindow" ) );
}
void CEtUIIME::ResetCompositionString()
{
s_nCompCaret = 0;
s_CompString.SetText( L"" );
memset( s_abyCompStringAttr, 0, sizeof( s_abyCompStringAttr ) );
}
void CEtUIIME::GetReadingWindowOrientation( DWORD dwId )
{
s_bHorizontalReading = ( s_hklCurrent == _CHS_HKL ) || ( s_hklCurrent == _CHT_HKL2 ) || ( dwId == 0 );
if( ( !s_bHorizontalReading ) && ( ( dwId & 0x0000FFFF ) == LANG_CHT ) )
{
WCHAR wszRegPath[ MAX_PATH ];
HKEY hKey;
DWORD dwVer;
LONG lRc;
dwVer = dwId & 0xFFFF0000;
wcscpy_s( wszRegPath, MAX_PATH, L"software\\microsoft\\windows\\currentversion\\" );
wcscat_s( wszRegPath, MAX_PATH, ( dwVer >= MAKEIMEVERSION( 5, 1 ) ) ? L"MSTCIPH" : L"TINTLGNT" );
lRc = RegOpenKeyExW( HKEY_CURRENT_USER, wszRegPath, 0, KEY_READ, &hKey );
if(lRc == ERROR_SUCCESS)
{
DWORD dwSize, dwMapping, dwType;
dwSize = sizeof( DWORD );
lRc = RegQueryValueExW( hKey, L"Keyboard Mapping", NULL, &dwType, ( PBYTE )&dwMapping, &dwSize );
if(lRc == ERROR_SUCCESS)
{
if( ( dwVer <= MAKEIMEVERSION( 5, 0 ) &&
( ( BYTE )dwMapping == 0x22 || ( BYTE )dwMapping == 0x23 ) )
||
( ( dwVer == MAKEIMEVERSION( 5, 1 ) || dwVer == MAKEIMEVERSION( 5, 2 ) ) &&
( BYTE )dwMapping >= 0x22 && ( BYTE )dwMapping <= 0x24 )
)
{
s_bHorizontalReading = true;
}
}
RegCloseKey( hKey );
}
}
}
void CEtUIIME::GetPrivateReadingString()
{
DWORD dwId;
dwId = GetImeId();
if( !dwId )
{
s_bShowReadingWindow = false;
return;
}
HIMC hImc;
hImc = _ImmGetContext( GetEtDevice()->GetHWnd() );
if( !hImc )
{
s_bShowReadingWindow = false;
return;
}
DWORD dwReadingStrLen, dwErr;
WCHAR *pwszReadingStringBuffer, *wstr;
bool bUnicodeIme;
INPUTCONTEXT *lpIC;
dwReadingStrLen = 0;
dwErr = 0;
pwszReadingStringBuffer = NULL;
wstr = NULL;
bUnicodeIme = false;
lpIC = NULL;
if( _GetReadingString )
{
UINT uMaxUiLen;
BOOL bVertical;
dwReadingStrLen = _GetReadingString( hImc, 0, NULL, ( PINT )&dwErr, &bVertical, &uMaxUiLen );
if( dwReadingStrLen )
{
wstr = pwszReadingStringBuffer = ( LPWSTR )HeapAlloc( GetProcessHeap(), 0, sizeof( WCHAR ) * dwReadingStrLen );
if( !pwszReadingStringBuffer )
{
_ImmReleaseContext( GetEtDevice()->GetHWnd(), hImc );
return;
}
dwReadingStrLen = _GetReadingString( hImc, dwReadingStrLen, wstr, ( PINT )&dwErr, &bVertical, &uMaxUiLen );
}
s_bHorizontalReading = !bVertical;
bUnicodeIme = true;
}
else
{
LPBYTE p;
lpIC = _ImmLockIMC( hImc );
p = 0;
switch( dwId )
{
case IMEID_CHT_VER42:
case IMEID_CHT_VER43:
case IMEID_CHT_VER44:
p = *( LPBYTE * )( ( LPBYTE )_ImmLockIMCC( lpIC->hPrivate ) + 24 );
if( !p )
{
break;
}
dwReadingStrLen = *( DWORD * )( p + 7 * 4 + 32 * 4 );
dwErr = *( DWORD * )( p + 8 * 4 + 32 * 4 );
wstr = ( WCHAR * )( p + 56 );
bUnicodeIme = true;
break;
case IMEID_CHT_VER50:
p = *( LPBYTE * )( ( LPBYTE )_ImmLockIMCC( lpIC->hPrivate ) + 3 * 4 );
if( !p )
{
break;
}
p = *( LPBYTE * )( ( LPBYTE )p + 1 * 4 + 5 * 4 + 4 * 2 );
if( !p )
{
break;
}
dwReadingStrLen = *( DWORD * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 );
dwErr = *( DWORD * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 + 1 * 4 );
wstr = ( WCHAR * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 );
bUnicodeIme = false;
break;
case IMEID_CHT_VER51:
case IMEID_CHT_VER52:
case IMEID_CHS_VER53:
p = *( LPBYTE * )( ( LPBYTE )_ImmLockIMCC( lpIC->hPrivate ) + 4 );
if( !p )
{
break;
}
p = *( LPBYTE * )( ( LPBYTE )p + 1 * 4 + 5 * 4 );
if( !p )
{
break;
}
dwReadingStrLen = *( DWORD * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * 2 );
dwErr = *( DWORD * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * 2 + 1 * 4 );
wstr = ( WCHAR * ) ( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 );
bUnicodeIme = true;
break;
case IMEID_CHS_VER41:
{
int nOffset;
if( GetImeId( 1 ) >= 0x00000002 )
{
nOffset = 8;
}
else
{
nOffset = 7;
}
p = *( LPBYTE * )( ( LPBYTE )_ImmLockIMCC( lpIC->hPrivate ) + nOffset * 4 );
if( !p )
{
break;
}
dwReadingStrLen = *( DWORD * )( p + 7 * 4 + 16 * 2 * 4 );
dwErr = *( DWORD * )( p + 8 * 4 + 16 * 2 * 4 );
dwErr = min( dwErr, dwReadingStrLen );
wstr = ( WCHAR * )( p + 6 * 4 + 16 * 2 * 1 );
bUnicodeIme = true;
break;
}
case IMEID_CHS_VER42:
{
OSVERSIONINFOW osi;
int nTcharSize;
osi.dwOSVersionInfoSize = sizeof( OSVERSIONINFOW );
GetVersionExW( &osi );
if( osi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
nTcharSize = sizeof( WCHAR );
}
else
{
nTcharSize = sizeof( char );
}
p = *( LPBYTE * )( ( LPBYTE )_ImmLockIMCC( lpIC->hPrivate ) + 1 * 4 + 1 * 4 + 6 * 4 );
if( !p )
{
break;
}
dwReadingStrLen = *( DWORD * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * nTcharSize);
dwErr = *( DWORD * )( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 + 16 * nTcharSize + 1 * 4 );
wstr = ( WCHAR * ) ( p + 1 * 4 + ( 16 * 2 + 2 * 4 ) + 5 * 4 );
if( osi.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
bUnicodeIme = true;
}
else
{
bUnicodeIme = false;
}
}
}
}
s_CandList.awszCandidate[ 0 ][ 0 ] = 0;
s_CandList.awszCandidate[ 1 ][ 0 ] = 0;
s_CandList.awszCandidate[ 2 ][ 0 ] = 0;
s_CandList.awszCandidate[ 3 ][ 0 ] = 0;
s_CandList.dwCount = dwReadingStrLen;
s_CandList.dwSelection = ( DWORD ) - 1;
if( bUnicodeIme )
{
int i;
for( i = 0; i < ( int )dwReadingStrLen; i++ )
{
if( ( i >= ( int )dwErr ) && ( s_CandList.dwSelection == ( DWORD ) - 1 ) )
{
s_CandList.dwSelection = i;
}
s_CandList.awszCandidate[ i ][ 0 ] = wstr[ i ];
s_CandList.awszCandidate[ i ][ 1 ] = 0;
}
s_CandList.awszCandidate[ i ][ 0 ] = 0;
}
else
{
char *p;
DWORD i, j;
p = ( char * )wstr;
for( i = 0, j = 0; i < dwReadingStrLen; i++, j++ )
{
WCHAR wszCodePage[ 8 ];
UINT uCodePage;
if( ( dwErr <= i ) && ( s_CandList.dwSelection == ( DWORD ) - 1 ) )
{
s_CandList.dwSelection = j;
}
uCodePage = CP_ACP;
if( GetLocaleInfoW( MAKELCID( GetLanguage(), SORT_DEFAULT ), LOCALE_IDEFAULTANSICODEPAGE, wszCodePage, sizeof( wszCodePage ) / sizeof( wszCodePage[ 0 ] ) ) )
{
uCodePage = wcstoul( wszCodePage, NULL, 0 );
}
if( IsDBCSLeadByteEx( uCodePage, p[ i ] ) )
{
MultiByteToWideChar( uCodePage, 0, p + i, 2, s_CandList.awszCandidate[ j ], 1 );
}
else
{
MultiByteToWideChar( uCodePage, 0, p + i, 1, s_CandList.awszCandidate[ j ], 1 );
}
if( IsDBCSLeadByteEx( uCodePage, p[ i ] ) )
{
i++;
}
}
s_CandList.awszCandidate[ j ][ 0 ] = 0;
s_CandList.dwCount = j;
}
if( !_GetReadingString )
{
_ImmUnlockIMCC( lpIC->hPrivate );
_ImmUnlockIMC( hImc );
GetReadingWindowOrientation( dwId );
}
_ImmReleaseContext( GetEtDevice()->GetHWnd(), hImc );
if( pwszReadingStringBuffer )
{
HeapFree( GetProcessHeap(), 0, pwszReadingStringBuffer );
}
if( s_CandList.dwCount > 0 )
{
s_bShowReadingWindow = true;
}
else
{
s_bShowReadingWindow = false;
}
if( s_bHorizontalReading )
{
int i;
s_CandList.nReadingError = -1;
s_wszReadingString[ 0 ] = 0;
for( i = 0; i < ( int )s_CandList.dwCount; i++ )
{
if( s_CandList.dwSelection == i )
{
s_CandList.nReadingError = lstrlenW( s_wszReadingString );
}
wcscat_s( s_wszReadingString, 32, s_CandList.awszCandidate[ i ] );
}
}
s_CandList.dwPageSize = MAX_CANDLIST;
}