|
|
/*++
Copyright (c) 2001, Microsoft Corporation
Module Name:
profile.cpp
Abstract:
This file implements the CicProfiles Class.
Author:
Revision History:
Notes:
--*/
#include "private.h"
#include "profile.h"
//+---------------------------------------------------------------------------
//
// CicProfile::Callbacks
//
//----------------------------------------------------------------------------
HRESULT CicProfile::ActiveLanguageProfileNotifySinkCallback( REFGUID rguid, REFGUID rguidProfile, BOOL fActivated, void *pv) { DebugMsg(TF_FUNC, TEXT("ActiveLanguageProfileNotifySinkCallback"));
CicProfile* _this = (CicProfile*)pv;
_this->ResetCache();
return S_OK; }
//+---------------------------------------------------------------------------
//
// CicProfile::ctor
// CicProfile::dtor
//
//----------------------------------------------------------------------------
CicProfile::CicProfile() { m_ref = 1;
m_profile = NULL; m_pActiveLanguageProfileNotifySink = NULL;
m_SavedLangId = LANG_NEUTRAL;
m_fActivateThread = FALSE; ResetCache();
m_cp = CP_ACP; m_LangID = LANG_NEUTRAL; m_hKL = 0; }
CicProfile::~CicProfile() { if (m_profile) { if (m_SavedLangId != LANG_NEUTRAL) { HRESULT hr = m_profile->ChangeCurrentLanguage(m_SavedLangId); if (FAILED(hr)) { DebugMsg(TF_ERROR, TEXT("CicProfile::~CicProfile: failed for ChangeCurrentLanguage")); } } m_profile->Release(); m_profile = NULL; }
if (m_pActiveLanguageProfileNotifySink) { m_pActiveLanguageProfileNotifySink->_Unadvise(); m_pActiveLanguageProfileNotifySink->Release(); m_pActiveLanguageProfileNotifySink = NULL; } }
//+---------------------------------------------------------------------------
//
// CicProfile::QueryInterface
// CicProfile::AddRef
// CicProfile::Release
//
//----------------------------------------------------------------------------
HRESULT CicProfile::QueryInterface( REFIID riid, void** ppvObj) { *ppvObj = NULL; return E_NOINTERFACE; }
ULONG CicProfile::AddRef( ) { return InterlockedIncrement(&m_ref); }
ULONG CicProfile::Release( ) { ULONG cr = InterlockedDecrement(&m_ref);
if (cr == 0) { delete this; }
return cr; }
//+---------------------------------------------------------------------------
//
// CicProfile::InitProfileInstance
//
//----------------------------------------------------------------------------
HRESULT CicProfile::InitProfileInstance( TLS* ptls) { HRESULT hr;
hr = TF_CreateInputProcessorProfiles(&m_profile);
if (FAILED(hr)) { DebugMsg(TF_ERROR, TEXT("CicProfile::InitProfileInstance: failed for CoCreate")); } else if (m_pActiveLanguageProfileNotifySink == NULL) { m_pActiveLanguageProfileNotifySink = new CActiveLanguageProfileNotifySink(CicProfile::ActiveLanguageProfileNotifySinkCallback, this); if (m_pActiveLanguageProfileNotifySink == NULL) { DebugMsg(TF_ERROR, TEXT("Couldn't create ActiveLanguageProfileNotifySink!"));
m_profile->Release(); m_profile = NULL; return E_FAIL; }
ITfThreadMgr_P* ptim_P = ptls->GetTIM(); if (ptim_P != NULL) { m_pActiveLanguageProfileNotifySink->_Advise(ptim_P); } }
return hr; }
//+---------------------------------------------------------------------------
//
// CicProfile::Activate
// CicProfile::Deactivate
//
//----------------------------------------------------------------------------
HRESULT CicProfile::Activate(void) { m_fActivateThread = TRUE; ResetCache(); return S_OK; }
HRESULT CicProfile::Deactivate(void) { m_fActivateThread = FALSE; return S_OK; }
//+---------------------------------------------------------------------------
//
// CicProfile::ChangeCurrentKeyboardLayout
//
//----------------------------------------------------------------------------
HRESULT CicProfile::ChangeCurrentKeyboardLayout( HKL hKL) { HRESULT hr;
LANGID CurrentLangId; hr = m_profile->GetCurrentLanguage(&CurrentLangId); if (FAILED(hr)) { DebugMsg(TF_ERROR, TEXT("CicProfile::ChangeCurrentKeyboardLayout: failed for GetCurrentLanguage")); } else if (hKL != NULL) { LANGID LangId = LangIdFromKL(hKL); if (LangId != CurrentLangId) { hr = m_profile->ChangeCurrentLanguage(LangId); if (FAILED(hr)) { m_SavedLangId = LANG_NEUTRAL; DebugMsg(TF_ERROR, TEXT("CicProfile::ChangeCurrentKeyboardLayout: failed for ChangeCurrentLanguage")); } m_SavedLangId = LangId; } } return hr; }
//+---------------------------------------------------------------------------
//
// CicProfile::GetLangId
//
//----------------------------------------------------------------------------
HRESULT CicProfile::GetLangId( LANGID *plid) { if (!m_profile) return E_FAIL;
if (!plid) return E_INVALIDARG;
HRESULT hr = S_OK;
if (m_fInitLangID) { *plid = m_LangID; } else { *plid = LANG_NEUTRAL;
hr = m_profile->GetCurrentLanguage(plid); if (FAILED(hr)) { DebugMsg(TF_ERROR, TEXT("CicProfile::GetLangId: failed for GetCurrentLanguage")); } else { m_LangID = *plid; m_fInitLangID = TRUE; } }
return hr; }
//+---------------------------------------------------------------------------
//
// CicProfile::GetCodePageA
//
//----------------------------------------------------------------------------
HRESULT CicProfile::GetCodePageA( UINT *puCodePage ) { if (!puCodePage) return E_INVALIDARG;
if (m_fInitCP) { *puCodePage = m_cp; } else { *puCodePage = CP_ACP;
LANGID langid; if (FAILED(GetLangId(&langid))) return E_FAIL;
WCHAR szCodePage[12]; int ret = GetLocaleInfoW(MAKELCID(langid, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szCodePage, sizeof(szCodePage)/sizeof(WCHAR)); if (ret) { szCodePage[ret] = L'\0'; *puCodePage = wcstoul(szCodePage, NULL, 10); m_cp = *puCodePage; m_fInitCP = TRUE; } } return S_OK; }
//+---------------------------------------------------------------------------
//
// CicProfile::GetKeyboardLayout
//
//----------------------------------------------------------------------------
HRESULT CicProfile::GetKeyboardLayout( HKL* phkl) { if (! phkl) return E_INVALIDARG;
*phkl = NULL;
if (m_fInitHKL) { *phkl = m_hKL; } else if (! m_fActivateThread) { return E_FAIL; } else { LANGID langid; GUID guidProfile; HRESULT hr = m_profile->GetActiveLanguageProfile(GUID_TFCAT_TIP_KEYBOARD, &langid, &guidProfile); if (FAILED(hr)) return hr;
//
// Instead of (!IsEqualGUID(guidProfil, GUID_NULL)), we check
// 2nd, 3r and 4th DWORD of guidProfile. Because
// GetActivelanguageProfile(category guid) may return hKL in
// guidProfile
//
if ((((unsigned long *) &guidProfile)[1] != 0) || (((unsigned long *) &guidProfile)[2] != 0) || (((unsigned long *) &guidProfile)[3] != 0)) { /*
* Current keyboard layout is Cicero. */ m_hKL = (HKL)LongToHandle(langid); // Don't use ::GetKeyboardLayout(0);
// Cicero awre doesn't case hKL.
} else if (!IsEqualGUID(guidProfile, GUID_NULL)) { /*
* Current keyboard layout is regacy IME. */ m_hKL = (HKL)LongToHandle(*(DWORD *)&guidProfile); } else { m_hKL = 0; }
*phkl = m_hKL; m_fInitHKL = TRUE; } return S_OK; }
//+---------------------------------------------------------------------------
//
// CicProfile::IsIME
//
//----------------------------------------------------------------------------
HRESULT CicProfile::IsIME( HKL hKL) { LANGID LangId = LangIdFromKL(hKL);
Interface<IEnumTfLanguageProfiles> LanguageProfiles; HRESULT hr = m_profile->EnumLanguageProfiles(LangId, LanguageProfiles); if (FAILED(hr)) return S_FALSE;
//
// AIMM12 compat.
// we don't set GUID_TFCAT_TIP_KEYBOARD catid to enumerate profiles.
// so if we have some other TIP than Keyboard TIP, we may return S_OK.
//
CEnumrateValue<IEnumTfLanguageProfiles, TF_LANGUAGEPROFILE, LANG_PROF_ENUM_ARG> Enumrate(LanguageProfiles, LanguageProfilesCallback);
ENUM_RET ret = Enumrate.DoEnumrate(); if (ret != ENUM_FIND) return S_FALSE; else return S_OK; }
//+---------------------------------------------------------------------------
//
// CicProfile::GetActiveLanguageProfile
// CicProfile::LanguageProfilesCallback
//
//----------------------------------------------------------------------------
HRESULT CicProfile::GetActiveLanguageProfile( IN HKL hKL, IN GUID catid, OUT TF_LANGUAGEPROFILE* pLanguageProfile) { LANGID LangId = LangIdFromKL(hKL);
Interface<IEnumTfLanguageProfiles> LanguageProfiles; HRESULT hr = m_profile->EnumLanguageProfiles(LangId, LanguageProfiles); if (FAILED(hr)) return S_FALSE;
LANG_PROF_ENUM_ARG LangProfEnumArg; LangProfEnumArg.catid = catid;
CEnumrateValue<IEnumTfLanguageProfiles, TF_LANGUAGEPROFILE, LANG_PROF_ENUM_ARG> Enumrate(LanguageProfiles, LanguageProfilesCallback, &LangProfEnumArg);
ENUM_RET ret = Enumrate.DoEnumrate(); if (ret != ENUM_FIND || pLanguageProfile == NULL) return S_FALSE; else { *pLanguageProfile = LangProfEnumArg.LanguageProfile; return S_OK; } }
ENUM_RET CicProfile::LanguageProfilesCallback( TF_LANGUAGEPROFILE LanguageProfile, LANG_PROF_ENUM_ARG* pLangProfEnumArg) { if (LanguageProfile.fActive && ! IsEqualGUID(LanguageProfile.clsid, GUID_NULL)) { if (pLangProfEnumArg) { if (! IsEqualGUID(LanguageProfile.catid, pLangProfEnumArg->catid)) { return ENUM_CONTINUE; } pLangProfEnumArg->LanguageProfile = LanguageProfile; } return ENUM_FIND; }
return ENUM_CONTINUE; }
|