|
|
//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1999 **
//*********************************************************************
//
// LANGUAGE.CPP - Header for the implementation of CLanguage
//
// HISTORY:
//
// 1/27/99 a-jaswed Created.
//
#include "precomp.h"
#include "msobmain.h"
#include "language.h"
#include "appdefs.h"
#include "dispids.h"
#define DEFAULT_BUFFER_SIZE BYTES_REQUIRED_BY_CCH(2048)
DISPATCHLIST LanguageExternalInterface[] = { {L"get_NumOfRegions", DISPID_GETNUMOFREGIONS }, {L"get_RegionName", DISPID_GETREGIONNAME }, {L"get_RegionIndex", DISPID_GETREGIONINDEX }, {L"set_RegionIndex", DISPID_SETREGIONINDEX }, {L"get_NumOfLangs", DISPID_GETNUMOFLANGS }, {L"get_LangName", DISPID_GETLANGNAME }, {L"get_LangIndex", DISPID_GETLANGINDEX }, {L"set_LangIndex", DISPID_SETLANGINDEX }, {L"get_NumOfKeyboardLayouts", DISPID_GETNUMOFKEYLAYOUTS }, {L"get_KeyboardLayoutName", DISPID_GETKEYNAME }, {L"get_KeyboardLayoutIndex", DISPID_GETKEYLAYOUTINDEX }, {L"set_KeyboardLayoutIndex", DISPID_SETKEYLAYOUTINDEX }, {L"get_RebootState", DISPID_LANGUAGE_GETREBOOTSTATE }, {L"SaveSettings", DISPID_LANGUAGE_SAVESETTINGS }, {L"get_PhoneCountries", DISPID_GETPHONECOUNTRIES } };
//+---------------------------------------------------------------------------
//
// Function: CompareNameLookUpElements()
//
// Synopsis: Function to compare names used by sort
//
//+---------------------------------------------------------------------------
int __cdecl CompareNameLookUpElements(const void *e1, const void *e2) {
LPNAMELOOKUPELEMENT pCUE1 = (LPNAMELOOKUPELEMENT)e1; LPNAMELOOKUPELEMENT pCUE2 = (LPNAMELOOKUPELEMENT)e2;
return CompareString(LOCALE_USER_DEFAULT, 0, pCUE1->pszName, -1, pCUE2->pszName, -1) - 2; }
/////////////////////////////////////////////////////////////
// CLanguage::CLanguage
CLanguage::CLanguage() { WCHAR szINIPath[MAX_PATH] = L""; WCHAR Answer[MAX_PATH];
// Init member vars
m_cRef = 0; m_lRebootState = LANGUAGE_REBOOT_NEVER;
m_poliRegions = NULL; m_lRegionTotal = 0; m_lRegionDefault = -1;
m_poliLangs = NULL; m_lLangTotal = 0; m_lLangDefault = -1;
m_poliKeyboards = NULL; m_lKeyboardLayoutTotal = 0; m_lKeyboardLayoutDefault = -1;
GetCanonicalizedPath(szINIPath, INI_SETTINGS_FILENAME);
m_DefaultRegion = GetPrivateProfileInt( OPTIONS_SECTION, DEFAULT_REGION, 0, szINIPath );
GetPrivateProfileString( OPTIONS_SECTION, DEFAULT_LANGUAGE, L"", Answer, MAX_PATH, szINIPath ); m_DefaultLanguage = wcstoul(Answer, NULL, 16);
GetPrivateProfileString( OPTIONS_SECTION, DEFAULT_KEYBOARD, L"", Answer, MAX_PATH, szINIPath ); m_DefaultKeyboard = wcstoul(Answer, NULL, 16);
SetupGetGeoOptions( m_DefaultRegion, &m_poliRegions, (LPDWORD) &m_lRegionTotal, (LPDWORD) &m_lRegionDefault ); MYASSERT( m_poliRegions );
SetupGetLocaleOptions( m_DefaultLanguage, &m_poliLangs, (LPDWORD) &m_lLangTotal, (LPDWORD) &m_lLangDefault ); MYASSERT( m_poliLangs );
SetupGetKeyboardOptions( m_DefaultKeyboard, &m_poliKeyboards, (LPDWORD) &m_lKeyboardLayoutTotal, (LPDWORD) &m_lKeyboardLayoutDefault); MYASSERT( m_poliKeyboards );
// The current index should be the defaults.
//
m_lRegionIndex = m_lRegionDefault; m_lLangIndex = m_lLangDefault; m_lKeyboardLayoutIndex = m_lKeyboardLayoutDefault; }
/////////////////////////////////////////////////////////////
// CLanguage::~CLanguage
CLanguage::~CLanguage() { if ( m_poliRegions ) SetupDestroyLanguageList( m_poliRegions, m_lRegionTotal ); if ( m_poliLangs ) SetupDestroyLanguageList( m_poliLangs, m_lLangTotal ); if ( m_poliKeyboards ) SetupDestroyLanguageList( m_poliKeyboards, m_lKeyboardLayoutTotal );
MYASSERT(m_cRef == 0); }
HRESULT CLanguage::get_NumOfRegions(long* plVal) { *plVal = m_lRegionTotal;
return S_OK; }
HRESULT CLanguage::get_NumOfKeyboardLayouts(long* plVal) { *plVal = m_lKeyboardLayoutTotal;
return S_OK; }
HRESULT CLanguage::get_RegionName(long lIndex, BSTR* pbstrVal) {
if ( lIndex >= m_lRegionTotal ) return E_FAIL;
// *pbstrVal = SysAllocString(m_pRegionNameLookUp[lIndex].pszName);
*pbstrVal = SysAllocString( m_poliRegions[lIndex].Name );
return S_OK; }
HRESULT CLanguage::get_KeyboardLayoutName(long lIndex, BSTR* pbstrVal) {
if ( lIndex >= m_lKeyboardLayoutTotal ) return E_FAIL;
// *pbstrVal = SysAllocString(m_pKeyboardNameLookUp[lIndex].pszName);
*pbstrVal = SysAllocString( m_poliKeyboards[lIndex].Name );
return S_OK; }
HRESULT CLanguage::get_RebootState(long* plVal) { *plVal = m_lRebootState;
return S_OK; }
HRESULT CLanguage::SaveSettings() { // Only save the settings if they changed.
//
if ( ( m_lRegionIndex >= 0 ) && ( m_lLangIndex >= 0 ) && ( m_lKeyboardLayoutIndex >= 0 ) && m_poliRegions && m_poliLangs && m_poliKeyboards ) //( m_lRegionDefault != m_lRegionIndex ) ||
//( m_lKeyboardLayoutDefault != m_lKeyboardLayoutIndex ) )
{ if (SetupSetIntlOptions( m_poliRegions[m_lRegionIndex].Id, m_poliLangs[m_lLangIndex].Id, m_poliKeyboards[m_lKeyboardLayoutIndex].Id )) { // BUGBUG: The return value from SetIntlOptions on Win9x is
// interpreted as a reboot state. How do we determine reboot state
// on Whistler?
// Now the defaults are what is currently saved.
//
m_lRegionDefault = m_lRegionIndex; m_lLangDefault = m_lLangIndex; m_lKeyboardLayoutDefault = m_lKeyboardLayoutIndex; }
}
return S_OK; }
////////////////////////////////////////////////
////////////////////////////////////////////////
//// GET / SET :: RegionIndex
////
HRESULT CLanguage::get_RegionIndex(long* plVal) { *plVal = m_lRegionIndex;
return S_OK; }
HRESULT CLanguage::set_RegionIndex(long lVal) { m_lRegionIndex = lVal; // m_lRegionIndex = m_pRegionNameLookUp[lVal].nIndex;
return S_OK; }
////////////////////////////////////////////////
////////////////////////////////////////////////
//// GET / SET :: KeyboardLayoutIndex
////
HRESULT CLanguage::get_KeyboardLayoutIndex(long* plVal) { *plVal = m_lKeyboardLayoutIndex;
return S_OK; }
HRESULT CLanguage::set_KeyboardLayoutIndex(long lVal) { m_lKeyboardLayoutIndex = lVal; // m_lKeyboardLayoutIndex = m_pKeyboardNameLookUp[lVal].nIndex;;
return S_OK; }
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////// IUnknown implementation
///////
///////
/////////////////////////////////////////////////////////////
// CLanguage::QueryInterface
STDMETHODIMP CLanguage::QueryInterface(REFIID riid, LPVOID* ppvObj) { // must set out pointer parameters to NULL
*ppvObj = NULL;
if ( riid == IID_IUnknown) { AddRef(); *ppvObj = (IUnknown*)this; return ResultFromScode(S_OK); }
if (riid == IID_IDispatch) { AddRef(); *ppvObj = (IDispatch*)this; return ResultFromScode(S_OK); }
// Not a supported interface
return ResultFromScode(E_NOINTERFACE); }
/////////////////////////////////////////////////////////////
// CLanguage::AddRef
STDMETHODIMP_(ULONG) CLanguage::AddRef() { return ++m_cRef; }
/////////////////////////////////////////////////////////////
// CLanguage::Release
STDMETHODIMP_(ULONG) CLanguage::Release() { return --m_cRef; }
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
/////// IDispatch implementation
///////
///////
/////////////////////////////////////////////////////////////
// CLanguage::GetTypeInfo
STDMETHODIMP CLanguage::GetTypeInfo(UINT, LCID, ITypeInfo**) { return E_NOTIMPL; }
/////////////////////////////////////////////////////////////
// CLanguage::GetTypeInfoCount
STDMETHODIMP CLanguage::GetTypeInfoCount(UINT* pcInfo) { return E_NOTIMPL; }
/////////////////////////////////////////////////////////////
// CLanguage::GetIDsOfNames
STDMETHODIMP CLanguage::GetIDsOfNames(REFIID riid, OLECHAR** rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) {
HRESULT hr = DISP_E_UNKNOWNNAME; rgDispId[0] = DISPID_UNKNOWN;
for (int iX = 0; iX < sizeof(LanguageExternalInterface)/sizeof(DISPATCHLIST); iX ++) { if(lstrcmp(LanguageExternalInterface[iX].szName, rgszNames[0]) == 0) { rgDispId[0] = LanguageExternalInterface[iX].dwDispID; hr = NOERROR; break; } }
// Set the disid's for the parameters
if (cNames > 1) { // Set a DISPID for function parameters
for (UINT i = 1; i < cNames ; i++) rgDispId[i] = DISPID_UNKNOWN; }
return hr; }
/////////////////////////////////////////////////////////////
// CLanguage::Invoke
HRESULT CLanguage::Invoke ( DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr ) { HRESULT hr = S_OK;
switch(dispidMember) { case DISPID_GETNUMOFREGIONS: {
TRACE(L"DISPID_GETNUMOFREGIONS\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
get_NumOfRegions(&(pvarResult->lVal)); } break; }
case DISPID_GETREGIONINDEX: {
TRACE(L"DISPID_GETREGIONINDEX\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
get_RegionIndex(&(pvarResult->lVal)); } break; }
case DISPID_SETREGIONINDEX: {
TRACE(L"DISPID_SETREGIONINDEX\n");
if(pdispparams && &pdispparams[0].rgvarg[0]) set_RegionIndex(pdispparams[0].rgvarg[0].lVal); break; }
case DISPID_GETREGIONNAME: {
TRACE(L"DISPID_GETREGIONNAME\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_BSTR;
if(pdispparams && &pdispparams[0].rgvarg[0]) get_RegionName(pdispparams[0].rgvarg[0].lVal, &(pvarResult->bstrVal)); } break; }
// BUGBUG: Need to Lang processing to syssetup.dll
case DISPID_GETNUMOFLANGS: {
TRACE(L"DISPID_GETNUMOFFLANGS\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
pvarResult->lVal = m_lLangTotal; } break; }
case DISPID_GETLANGINDEX: {
TRACE(L"DISPID_GETLANGINDEX\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
pvarResult->lVal = m_lLangIndex; } break; }
case DISPID_SETLANGINDEX: {
TRACE(L"DISPID_SETLANGINDEX\n");
if(pdispparams && &pdispparams[0].rgvarg[0]) { m_lLangIndex = pdispparams[0].rgvarg[0].lVal; } break; }
case DISPID_GETLANGNAME: {
TRACE(L"DISPID_GETLANGNAME\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_BSTR;
if(pdispparams && &pdispparams[0].rgvarg[0]) {
long lIndex = pdispparams[0].rgvarg[0].lVal;
// BUGBUG: What if lIndex < 0??
if ( lIndex >= m_lLangTotal ) return E_FAIL;
pvarResult->bstrVal = SysAllocString( m_poliLangs[lIndex].Name ); } } break; }
case DISPID_GETNUMOFKEYLAYOUTS: {
TRACE(L"DISPID_GETNUMOFKEYLAYOUTS\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
get_NumOfKeyboardLayouts(&(pvarResult->lVal)); } break; }
case DISPID_GETKEYLAYOUTINDEX: {
TRACE(L"DISPID_GETKEYLAYOUTINDEX\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
get_KeyboardLayoutIndex(&(pvarResult->lVal)); } break; }
case DISPID_SETKEYLAYOUTINDEX: {
TRACE(L"DISPID_SETKEYLAYOUTINDEX\n");
if(pdispparams && &pdispparams[0].rgvarg[0]) set_KeyboardLayoutIndex(pdispparams[0].rgvarg[0].lVal); break; }
case DISPID_GETKEYNAME: {
TRACE(L"DISPID_GETKEYNAME\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_BSTR;
if(pdispparams && &pdispparams[0].rgvarg[0]) get_KeyboardLayoutName(pdispparams[0].rgvarg[0].lVal, &(pvarResult->bstrVal)); } break; }
case DISPID_LANGUAGE_GETREBOOTSTATE: {
TRACE(L"DISPID_LANGUAGE_GETREBOOTSTATE\n");
if(pvarResult) { VariantInit(pvarResult); V_VT(pvarResult) = VT_I4;
get_RebootState(&(pvarResult->lVal)); } break; }
case DISPID_LANGUAGE_SAVESETTINGS: {
TRACE(L"DISPID_LANGUAGE_SAVESETTINGS\n");
SaveSettings(); break; }
case DISPID_GETPHONECOUNTRIES: {
TRACE(L"DISPID_GETPHONECOUNTRIES");
if(pvarResult) { WCHAR PhoneInfName[MAX_PATH];
GetOOBEMUIPath( PhoneInfName ); lstrcat( PhoneInfName, L"\\phone.inf" );
VariantInit(pvarResult); V_VT(pvarResult) = VT_BSTR;
pvarResult->bstrVal = SysAllocString( SetupReadPhoneList( PhoneInfName ) ); } break; }
default: { hr = DISP_E_MEMBERNOTFOUND; break; } } return hr; }
|