You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
741 lines
20 KiB
741 lines
20 KiB
// cutil.cpp
|
|
//
|
|
// file to put misc utility classes implementation
|
|
//
|
|
#include "private.h"
|
|
#include "sapilayr.h"
|
|
#include "sphelper.h"
|
|
#include "xstring.h"
|
|
#include "cregkey.h"
|
|
#include "ctflbui.h"
|
|
#include "nui.h"
|
|
|
|
|
|
const GUID c_guidProfileBogus = { /* 09ea4e4b-46ce-4469-b450-0de76a435bbb */
|
|
0x09ea4e4b,
|
|
0x46ce,
|
|
0x4469,
|
|
{0xb4, 0x50, 0x0d, 0xe7, 0x6a, 0x43, 0x5b, 0xbb}
|
|
};
|
|
|
|
|
|
/* a5239e24-2bcf-4915-9c5c-fd50c0f69db2 */
|
|
const CLSID CLSID_MSLBUI = {
|
|
0xa5239e24,
|
|
0x2bcf,
|
|
0x4915,
|
|
{0x9c, 0x5c, 0xfd, 0x50, 0xc0, 0xf6, 0x9d, 0xb2}
|
|
};
|
|
|
|
// const GUID c_guidProfile0 = { /* 55122b58-15bb-11d4-bd48-00105a2799b5 */
|
|
// 0x55122b58,
|
|
// 0x15bb,
|
|
// 0x11d4,
|
|
// {0xbd, 0x48, 0x00, 0x10, 0x5a, 0x27, 0x99, 0xb5}
|
|
// };
|
|
// const GUID c_guidProfile1 = { /* 55122b59-15bb-11d4-bd48-00105a2799b5 */
|
|
// 0x55122b59,
|
|
// 0x15bb,
|
|
// 0x11d4,
|
|
// {0xbd, 0x48, 0x00, 0x10, 0x5a, 0x27, 0x99, 0xb5}
|
|
// };
|
|
// const GUID c_guidProfile2 = { /* 55122b5a-15bb-11d4-bd48-00105a2799b5 */
|
|
// 0x55122b5a,
|
|
// 0x15bb,
|
|
// 0x11d4,
|
|
// {0xbd, 0x48, 0x00, 0x10, 0x5a, 0x27, 0x99, 0xb5}
|
|
// };
|
|
|
|
#ifndef USE_SAPI_FOR_LANGDETECTION
|
|
static const char c_szSpeechRecognizersKey[] = "Software\\Microsoft\\Speech\\Recognizers";
|
|
static const char c_szSpeechRecognizersTokensKey[] = "Software\\Microsoft\\Speech\\Recognizers\\Tokens";
|
|
static const char c_szDefault[] = "DefaultTokenId";
|
|
|
|
static const char c_szAttribute[] = "Attributes";
|
|
static const char c_szLanguage[] = "Language";
|
|
|
|
static const char c_szUseSAPIForLang[] = "UseSAPIForLang";
|
|
#endif
|
|
|
|
static const char c_szProfileRemoved[] = "ProfileRemoved";
|
|
static const char c_szProfileInitialized[] = "ProfileInitialized";
|
|
|
|
_inline BOOL _IsCompatibleLangid(LANGID langidReq, LANGID langidCmp)
|
|
{
|
|
if (PRIMARYLANGID(langidReq) == LANG_CHINESE)
|
|
{
|
|
return langidReq == langidCmp;
|
|
}
|
|
else
|
|
{
|
|
return PRIMARYLANGID(langidReq) == PRIMARYLANGID(langidCmp);
|
|
}
|
|
}
|
|
|
|
void _RegisterOrUnRegisterMslbui(BOOL fRegister)
|
|
{
|
|
// we just assume the dll is copied to system32
|
|
TCHAR szMslbui[MAX_PATH];
|
|
int cch = GetSystemDirectory(szMslbui, ARRAYSIZE(szMslbui));
|
|
|
|
if (!cch)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// GetSystemDirectory appends no '\' unless the system
|
|
// directory is the root, such like "c:\"
|
|
if (cch != 3)
|
|
{
|
|
StringCchCat(szMslbui, ARRAYSIZE(szMslbui), TEXT("\\"));
|
|
}
|
|
StringCchCat(szMslbui, ARRAYSIZE(szMslbui), TEXT("mslbui.dll"));
|
|
|
|
if (fRegister)
|
|
{
|
|
// load mslbui.dll and register it
|
|
TF_RegisterLangBarAddIn(CLSID_MSLBUI, AtoW(szMslbui), TF_RLBAI_CURRENTUSER | TF_RLBAI_ENABLE);
|
|
|
|
}
|
|
else
|
|
{
|
|
TF_UnregisterLangBarAddIn(CLSID_MSLBUI, TF_RLBAI_CURRENTUSER);
|
|
}
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// dtor
|
|
//
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
CLangProfileUtil::~CLangProfileUtil()
|
|
{
|
|
if (m_langidRecognizers.Count() > 0)
|
|
m_langidRecognizers.Clear();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _RegisterProfiles
|
|
//
|
|
// synopsis: a rough equivalent of RegisterTIP lib function, only different in
|
|
// trying to cache the profile manager & the category manager
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
HRESULT CLangProfileUtil::_RegisterAProfile(HINSTANCE hInst, REFCLSID rclsid, const REGTIPLANGPROFILE *plp)
|
|
{
|
|
Assert(plp);
|
|
|
|
HRESULT hr = S_OK;
|
|
// ensure profile manager
|
|
if (!m_cpProfileMgr)
|
|
{
|
|
hr = TF_CreateInputProcessorProfiles(&m_cpProfileMgr);
|
|
}
|
|
|
|
// register the clsid
|
|
if (S_OK == hr)
|
|
{
|
|
hr = m_cpProfileMgr->Register(rclsid);
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
WCHAR wszFilePath[MAX_PATH];
|
|
WCHAR *pv = &wszFilePath[0];
|
|
|
|
wszFilePath[0] = L'\0';
|
|
|
|
if (wcslen(plp->szIconFile))
|
|
{
|
|
char szFilePath[MAX_PATH];
|
|
WCHAR *pvCur;
|
|
|
|
::GetModuleFileName(hInst, szFilePath, ARRAYSIZE(szFilePath));
|
|
StringCchCopyW(wszFilePath, ARRAYSIZE(wszFilePath), AtoW(szFilePath));
|
|
|
|
pv = pvCur = &wszFilePath[0];
|
|
while (*pvCur)
|
|
{
|
|
if (*pvCur == L'\\')
|
|
pv = pvCur + 1;
|
|
pvCur++;
|
|
}
|
|
*pv = L'\0';
|
|
}
|
|
StringCchCatW(wszFilePath, ARRAYSIZE(wszFilePath), plp->szIconFile);
|
|
|
|
hr = m_cpProfileMgr->AddLanguageProfile(rclsid,
|
|
plp->langid, *plp->pguidProfile, plp->szProfile,
|
|
wcslen(plp->szProfile), wszFilePath, wcslen(wszFilePath),
|
|
plp->uIconIndex);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// RegisterActiveProfiles(void)
|
|
//
|
|
// synopsis
|
|
//
|
|
//
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
HRESULT CLangProfileUtil::RegisterActiveProfiles(void)
|
|
{
|
|
if (_fUserRemovedProfile())
|
|
{
|
|
// remove mslbui when not one speech profile is enabled
|
|
if (!_IsAnyProfileEnabled())
|
|
_RegisterOrUnRegisterMslbui(FALSE);
|
|
|
|
return S_FALSE;
|
|
}
|
|
|
|
_SetUserInitializedProfile();
|
|
|
|
BOOL fEnabled;
|
|
HRESULT hr = _EnsureProfiles(TRUE, &fEnabled);
|
|
|
|
// if the speech TIP profile is correctly registered,
|
|
// then we're OK to register the persist UI (mslbui.dll)
|
|
//
|
|
if (S_OK == hr && fEnabled)
|
|
_RegisterOrUnRegisterMslbui(TRUE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// IsProfileAvailableForLang(LANGID langid, BOOL *pfAvailable)
|
|
//
|
|
// synopsis
|
|
//
|
|
//
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
HRESULT CLangProfileUtil::IsProfileAvailableForLang(LANGID langid, BOOL *pfAvailable)
|
|
{
|
|
if (pfAvailable)
|
|
{
|
|
*pfAvailable = _IsDictationEnabledForLang(langid);
|
|
return S_OK;
|
|
}
|
|
else
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetDisplayName(BSTR *pbstrName)
|
|
//
|
|
// synopsis
|
|
//
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
HRESULT CLangProfileUtil::GetDisplayName(BSTR *pbstrName)
|
|
{
|
|
HRESULT hr = E_INVALIDARG;
|
|
|
|
if (pbstrName)
|
|
{
|
|
*pbstrName = SysAllocString(L"Register Active profiles for SPTIP");
|
|
if (!*pbstrName)
|
|
hr = E_OUTOFMEMORY;
|
|
else
|
|
hr = S_OK;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CLangProfileUtil::_EnsureProfiles(BOOL fRegister, BOOL *pfEnabled)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pfEnabled)
|
|
*pfEnabled = FALSE;
|
|
|
|
if (fRegister)
|
|
{
|
|
m_langidRecognizers.Clear();
|
|
}
|
|
|
|
if (!m_cpProfileMgr || fRegister)
|
|
{
|
|
if (!m_cpProfileMgr)
|
|
{
|
|
hr = TF_CreateInputProcessorProfiles(&m_cpProfileMgr);
|
|
}
|
|
if (fRegister)
|
|
{
|
|
// if this is a first time initialization,
|
|
// obtain the list of all languages
|
|
//
|
|
if (S_OK == hr)
|
|
{
|
|
LANGID *pLangIds;
|
|
ULONG ulCount;
|
|
// plangid will be assigned cotaskmemalloc'd memory
|
|
//
|
|
hr = m_cpProfileMgr->GetLanguageList(&pLangIds, &ulCount);
|
|
if (S_OK == hr)
|
|
{
|
|
for (UINT i = 0; i < ulCount; i++)
|
|
{
|
|
// here we register profiles
|
|
// if SR engines are available
|
|
//
|
|
BOOL fEnable = FALSE;
|
|
if (_IsDictationEnabledForLang(pLangIds[i]))
|
|
{
|
|
fEnable = TRUE;
|
|
|
|
if (pfEnabled)
|
|
*pfEnabled = TRUE;
|
|
}
|
|
|
|
hr = m_cpProfileMgr->EnableLanguageProfile(
|
|
CLSID_SapiLayr,
|
|
pLangIds[i],
|
|
c_guidProfileBogus,
|
|
fEnable);
|
|
} // for
|
|
|
|
CoTaskMemFree(pLangIds);
|
|
}
|
|
}
|
|
} // fRegister
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
BOOL CLangProfileUtil::_IsAnyProfileEnabled()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (!m_cpProfileMgr)
|
|
{
|
|
hr = TF_CreateInputProcessorProfiles(&m_cpProfileMgr);
|
|
}
|
|
|
|
LANGID *pLangIds;
|
|
ULONG ulCount;
|
|
BOOL fEnable = FALSE;
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
//
|
|
// plangid will be assigned cotaskmemalloc'd memory
|
|
//
|
|
hr = m_cpProfileMgr->GetLanguageList(&pLangIds, &ulCount);
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
for (UINT i = 0; i < ulCount; i++)
|
|
{
|
|
hr = m_cpProfileMgr->IsEnabledLanguageProfile(CLSID_SapiLayr,
|
|
pLangIds[i],
|
|
c_guidProfileBogus,
|
|
&fEnable);
|
|
|
|
if (S_OK == hr && fEnable)
|
|
break;
|
|
}
|
|
|
|
CoTaskMemFree(pLangIds);
|
|
}
|
|
|
|
return fEnable;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _GetProfileLangID
|
|
//
|
|
// synopsis: handle language profiles
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
HRESULT CLangProfileUtil::_GetProfileLangID(LANGID *plangid)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
Assert(plangid);
|
|
|
|
hr = _EnsureProfiles(FALSE);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = m_cpProfileMgr->GetCurrentLanguage(plangid);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _DictationEnabled
|
|
//
|
|
// synopsis:
|
|
//
|
|
//---------------------------------------------------------------------------+
|
|
BOOL CLangProfileUtil::_DictationEnabled(LANGID *plangidRequested)
|
|
{
|
|
BOOL fret = FALSE;
|
|
LANGID langidReq = (LANGID)-1;
|
|
|
|
HRESULT hr = _GetProfileLangID(&langidReq);
|
|
if (S_OK == hr)
|
|
{
|
|
if (plangidRequested)
|
|
*plangidRequested = langidReq;
|
|
|
|
fret = _IsDictationActiveForLang(langidReq);
|
|
}
|
|
|
|
return fret;
|
|
}
|
|
|
|
//
|
|
// _IsDictationActiveForLang
|
|
//
|
|
// synopsis: see if the default SR engine is capable for
|
|
// the specified language
|
|
//
|
|
BOOL CLangProfileUtil::_IsDictationActiveForLang(LANGID langidReq)
|
|
{
|
|
return _IsDictationEnabledForLang(langidReq, TRUE);
|
|
}
|
|
|
|
BOOL CLangProfileUtil::_IsDictationEnabledForLang(LANGID langidReq, BOOL fUseDefault)
|
|
{
|
|
//
|
|
// try reg first and if it's not compatible try SAPI
|
|
//
|
|
BOOL fEnabled = FALSE;
|
|
if (_fUseSAPIForLanguageDetection() == FALSE
|
|
&& ERROR_SUCCESS ==
|
|
_IsDictationEnabledForLangInReg(langidReq, fUseDefault, &fEnabled))
|
|
{
|
|
return fEnabled;
|
|
}
|
|
return _IsDictationEnabledForLangSAPI(langidReq, fUseDefault);
|
|
}
|
|
|
|
BOOL CLangProfileUtil::_IsDictationEnabledForLangSAPI(LANGID langidReq, BOOL fUseDefault)
|
|
{
|
|
BOOL fEnabled = FALSE;
|
|
|
|
WCHAR * pszDefaultTokenId = NULL;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (fUseDefault)
|
|
{
|
|
if (langidReq == m_langidDefault)
|
|
return TRUE;
|
|
|
|
SpGetDefaultTokenIdFromCategoryId(SPCAT_RECOGNIZERS, &pszDefaultTokenId);
|
|
}
|
|
CComPtr<IEnumSpObjectTokens> cpEnum;
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
char szLang[MAX_PATH];
|
|
WCHAR wsz[MAX_PATH];
|
|
|
|
StringCchPrintfA(szLang, ARRAYSIZE(szLang), "Language=%x", langidReq);
|
|
MultiByteToWideChar(CP_ACP, NULL, szLang, -1, wsz, ARRAYSIZE(wsz));
|
|
hr = SpEnumTokens(SPCAT_RECOGNIZERS, wsz, NULL, &cpEnum);
|
|
}
|
|
|
|
while (!fEnabled && S_OK == hr)
|
|
{
|
|
CComPtr<ISpObjectToken> cpToken;
|
|
WCHAR * pszTokenId = NULL;
|
|
|
|
hr = cpEnum->Next(1, &cpToken, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
hr = cpToken->GetId(&pszTokenId);
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(!fUseDefault || pszDefaultTokenId);
|
|
|
|
if (!fUseDefault || wcscmp(pszDefaultTokenId, pszTokenId) == 0)
|
|
fEnabled = TRUE;
|
|
}
|
|
|
|
if (pszTokenId)
|
|
{
|
|
CoTaskMemFree(pszTokenId);
|
|
}
|
|
}
|
|
|
|
if (pszDefaultTokenId)
|
|
{
|
|
CoTaskMemFree(pszDefaultTokenId);
|
|
}
|
|
|
|
if (fUseDefault && fEnabled)
|
|
{
|
|
m_langidDefault = langidReq;
|
|
}
|
|
|
|
return fEnabled;
|
|
}
|
|
|
|
const TCHAR c_szDefaultDefaultToken[] = TEXT("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Recognizers\\Tokens\\MSASREnglish");
|
|
|
|
const TCHAR c_szDefaultDefaultTokenJpn[] = TEXT("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Recognizers\\Tokens\\MSASRJapanese");
|
|
|
|
const TCHAR c_szDefaultDefaultTokenChs[] = TEXT("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Recognizers\\Tokens\\MSASRChinese");
|
|
|
|
|
|
LONG CLangProfileUtil::_IsDictationEnabledForLangInReg(LANGID langidReq, BOOL fUseDefault, BOOL *pfEnabled)
|
|
{
|
|
LONG lret = ERROR_SUCCESS;
|
|
//
|
|
// fUseDefault == TRUE, just see if the current default recognizer
|
|
// matches with the requested langid
|
|
//
|
|
if (fUseDefault)
|
|
{
|
|
if( m_langidDefault == 0xFFFF)
|
|
{
|
|
char szRegkeyDefaultToken[MAX_PATH];
|
|
CMyRegKey regkey;
|
|
|
|
lret = regkey.Open(HKEY_CURRENT_USER,
|
|
c_szSpeechRecognizersKey,
|
|
KEY_READ);
|
|
|
|
if (ERROR_SUCCESS == lret)
|
|
{
|
|
// first obtain the regkey to look at for default token
|
|
lret = regkey.QueryValueCch(szRegkeyDefaultToken, c_szDefault, ARRAYSIZE(szRegkeyDefaultToken));
|
|
regkey.Close();
|
|
}
|
|
else
|
|
{
|
|
if (PRIMARYLANGID(langidReq) == LANG_JAPANESE)
|
|
{
|
|
StringCchCopy(szRegkeyDefaultToken, ARRAYSIZE(szRegkeyDefaultToken), c_szDefaultDefaultTokenJpn);
|
|
}
|
|
else if (langidReq == 0x804) // CHS
|
|
{
|
|
StringCchCopy(szRegkeyDefaultToken, ARRAYSIZE(szRegkeyDefaultToken), c_szDefaultDefaultTokenChs);
|
|
}
|
|
else
|
|
{
|
|
StringCchCopy(szRegkeyDefaultToken, ARRAYSIZE(szRegkeyDefaultToken), c_szDefaultDefaultToken);
|
|
}
|
|
lret = ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
// then get the attribute / language
|
|
if (ERROR_SUCCESS == lret)
|
|
{
|
|
char *psz = szRegkeyDefaultToken;
|
|
|
|
//
|
|
// eliminate "KKEY_LOCAL_MACHINE"
|
|
//
|
|
while(*psz && *psz != '\\')
|
|
psz++;
|
|
|
|
if (*psz == '\\')
|
|
{
|
|
psz++;
|
|
|
|
//
|
|
// open speech/recognizers/tokens key
|
|
//
|
|
lret = regkey.Open(HKEY_LOCAL_MACHINE, psz, KEY_READ);
|
|
}
|
|
else
|
|
m_langidDefault = 0x0000;
|
|
}
|
|
|
|
if (ERROR_SUCCESS == lret)
|
|
{
|
|
m_langidDefault = _GetLangIdFromRecognizerToken(regkey.m_hKey);
|
|
}
|
|
}
|
|
*pfEnabled = _IsCompatibleLangid(langidReq, m_langidDefault);
|
|
return lret;
|
|
}
|
|
|
|
//
|
|
// this is fUseDefault == FALSE case. We want to see
|
|
// if any installed recognizer can satisfy the langid requested.
|
|
//
|
|
if (m_langidRecognizers.Count() == 0)
|
|
{
|
|
CMyRegKey regkey;
|
|
char szRecognizerName[MAX_PATH];
|
|
lret = regkey.Open(HKEY_LOCAL_MACHINE,
|
|
c_szSpeechRecognizersTokensKey,
|
|
KEY_READ);
|
|
|
|
if(ERROR_SUCCESS == lret)
|
|
{
|
|
CMyRegKey regkeyReco;
|
|
DWORD dwIndex = 0;
|
|
|
|
while (ERROR_SUCCESS ==
|
|
regkey.EnumKey(dwIndex, szRecognizerName, ARRAYSIZE(szRecognizerName)))
|
|
{
|
|
lret = regkeyReco.Open(regkey.m_hKey, szRecognizerName, KEY_READ);
|
|
if (ERROR_SUCCESS == lret)
|
|
{
|
|
LANGID langid=_GetLangIdFromRecognizerToken(regkeyReco.m_hKey);
|
|
if (langid)
|
|
{
|
|
LANGID *pl = m_langidRecognizers.Append(1);
|
|
if (pl)
|
|
*pl = langid;
|
|
}
|
|
regkeyReco.Close();
|
|
}
|
|
dwIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL fEnabled = FALSE;
|
|
|
|
for (int i = 0 ; i < m_langidRecognizers.Count(); i++)
|
|
{
|
|
LANGID *p= m_langidRecognizers.GetPtr(i);
|
|
|
|
if (p)
|
|
{
|
|
if (_IsCompatibleLangid(langidReq, *p))
|
|
{
|
|
fEnabled = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
*pfEnabled = fEnabled;
|
|
|
|
return lret;
|
|
}
|
|
|
|
LANGID CLangProfileUtil::_GetLangIdFromRecognizerToken(HKEY hkeyToken)
|
|
{
|
|
LANGID langid = 0;
|
|
char szLang[MAX_PATH];
|
|
CMyRegKey regkeyAttr;
|
|
|
|
LONG lret = regkeyAttr.Open(hkeyToken, c_szAttribute, KEY_READ);
|
|
if (ERROR_SUCCESS == lret)
|
|
{
|
|
lret = regkeyAttr.QueryValueCch(szLang, c_szLanguage, ARRAYSIZE(szLang));
|
|
}
|
|
if (ERROR_SUCCESS == lret)
|
|
{
|
|
char *psz = szLang;
|
|
while(*psz && *psz != ';')
|
|
{
|
|
langid = langid << 4;
|
|
|
|
if (*psz >= 'a' && *psz <= 'f')
|
|
{
|
|
*psz -= ('a' - 'A');
|
|
}
|
|
|
|
if (*psz >= 'A' && *psz <= 'F')
|
|
{
|
|
langid += *psz - 'A' + 10;
|
|
}
|
|
else if (*psz >= '0' && *psz <= '9')
|
|
{
|
|
langid += *psz - '0';
|
|
}
|
|
psz++;
|
|
}
|
|
}
|
|
return langid;
|
|
}
|
|
|
|
BOOL CLangProfileUtil::_fUseSAPIForLanguageDetection(void)
|
|
{
|
|
if (m_uiUseSAPIForLangDetection == 0)
|
|
{
|
|
CMyRegKey regkey;
|
|
if (ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE, c_szSapilayrKey, KEY_READ))
|
|
{
|
|
DWORD dw;
|
|
if (ERROR_SUCCESS==regkey.QueryValue(dw, c_szUseSAPIForLang))
|
|
{
|
|
m_uiUseSAPIForLangDetection = dw;
|
|
}
|
|
}
|
|
|
|
if (m_uiUseSAPIForLangDetection == 0)
|
|
{
|
|
m_uiUseSAPIForLangDetection = 1;
|
|
}
|
|
}
|
|
return m_uiUseSAPIForLangDetection == 2 ? TRUE : FALSE;
|
|
}
|
|
|
|
|
|
BOOL CLangProfileUtil::_fUserRemovedProfile(void)
|
|
{
|
|
BOOL bret = FALSE;
|
|
|
|
CMyRegKey regkey;
|
|
|
|
if (ERROR_SUCCESS == regkey.Open(HKEY_CURRENT_USER, c_szSapilayrKey, KEY_READ))
|
|
{
|
|
DWORD dw;
|
|
if (ERROR_SUCCESS==regkey.QueryValue(dw, c_szProfileRemoved))
|
|
{
|
|
bret = dw > 0 ? TRUE : FALSE;
|
|
}
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
BOOL CLangProfileUtil::_fUserInitializedProfile(void)
|
|
{
|
|
BOOL bret = FALSE;
|
|
|
|
CMyRegKey regkey;
|
|
|
|
if (ERROR_SUCCESS == regkey.Open(HKEY_CURRENT_USER, c_szSapilayrKey, KEY_READ))
|
|
{
|
|
DWORD dw;
|
|
if (ERROR_SUCCESS==regkey.QueryValue(dw, c_szProfileInitialized))
|
|
{
|
|
bret = dw > 0 ? TRUE : FALSE;
|
|
}
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
BOOL CLangProfileUtil::_SetUserInitializedProfile(void)
|
|
{
|
|
CMyRegKey regkey;
|
|
|
|
if (ERROR_SUCCESS == regkey.Create(HKEY_CURRENT_USER, c_szSapilayrKey))
|
|
{
|
|
DWORD dw = 0x0001;
|
|
if (ERROR_SUCCESS==regkey.SetValue(dw, c_szProfileInitialized))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|