Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ///////////////////////////////////////////////////////////////////////
- // Microsoft Windows //
- // Copyright(c) Microsoft Corp., 1995 //
- ///////////////////////////////////////////////////////////////////////
- //
- // LANG.CPP - "Language" property page for InetCpl
- //
- // HISTORY:
- //
- // 1/10/97 beomoh created
- //
- #include "inetcplp.h"
- #include <tchar.h>
- #include <mlang.h>
- #include "psapi.h"
- #include "tlhelp32.h"
- #include "process.h"
- #include <mluisupp.h>
- #include <shdocvw.h>
- #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
- #define FORMAT_STR TEXT("%s [%s]")
- #define MAX_LIST_STRING_LEN MAX_LOCALE_NAME + MAX_RFC1766_NAME + 3
- #define MAX_ACCEPT_LANG_LEN 2048
- #define CP_THAI 874
- #define CP_ARABIC 1256
- #define CP_HEBREW 1255
- // used as the return value from setlang dialog
- #define RETURN_SETLANG_ENDLANGDIALOG 2
- #define RETURN_SETLANG_CLOSEDNORMAL 1
- #define RETURN_SETLANG_CANCELED 0
- typedef HRESULT (* PCOINIT) (LPVOID);
- typedef VOID (* PCOUNINIT) (VOID);
- typedef VOID (* PCOMEMFREE) (LPVOID);
- typedef HRESULT (* PCOCREINST) (REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID * );
- extern HMODULE hOLE32;
- extern PCOINIT pCoInitialize;
- extern PCOUNINIT pCoUninitialize;
- extern PCOMEMFREE pCoTaskMemFree;
- extern PCOCREINST pCoCreateInstance;
- extern BOOL _StartOLE32();
- class CUILangList;
- INT_PTR KickSetLang(HWND hDlg, CUILangList * pLangList);
- static const TCHAR s_szResourceLocale[] = TEXT("ResourceLocale");
- // HKLM\Software\Microsoft\Internet Explorer\International used for url string
- static const TCHAR s_szUrlSPK[]
- = TEXT("http://www.microsoft.com/isapi/redir.dll?prd=ie&pver=6&ar=plugui&sba=install");
- static const TCHAR c_szInstall[]
- = TEXT("Software\\Microsoft\\Active Setup\\Installed Components\\{89820200-ECBD-11CF-8B85-00AA005B4383}");
- static const TCHAR c_szLocale[] = TEXT("Locale");
- static const TCHAR s_szLangPackPath[] = TEXT("Software\\Microsoft\\Internet Explorer");
- static const TCHAR s_szVersion[] = TEXT("LPKInstalled");
- typedef struct
- {
- WORD wlangid;
- BOOL fValid;
- TCHAR szName[MAX_LOCALE_NAME];
- } LANGLIST;
- static LANGLIST s_arryLangList[] =
- {
- {0x0409, FALSE, {0}},
- {0x0407, FALSE, {0}},
- {0x0411, FALSE, {0}},
- {0x0412, FALSE, {0}},
- {0x0404, FALSE, {0}},
- {0x0804, FALSE, {0}},
- {0x040c, FALSE, {0}},
- {0x0c0a, FALSE, {0}},
- {0x0416, FALSE, {0}},
- {0x0410, FALSE, {0}},
- {0x0413, FALSE, {0}},
- {0x041d, FALSE, {0}},
- {0x0406, FALSE, {0}},
- {0x040b, FALSE, {0}},
- {0x040e, FALSE, {0}},
- {0x0414, FALSE, {0}},
- {0x0408, FALSE, {0}},
- {0x0415, FALSE, {0}},
- {0x0419, FALSE, {0}},
- {0x0405, FALSE, {0}},
- {0x0816, FALSE, {0}},
- {0x041f, FALSE, {0}},
- {0x041b, FALSE, {0}},
- {0x0424, FALSE, {0}},
- {0x0401, FALSE, {0}},
- {0x040d, FALSE, {0}},
- {0x042d, FALSE, {0}},
- {0x040f, FALSE, {0}},
- };
- //
- // ISO639 ID table
- //
- typedef struct tagISO639
- {
- LPCTSTR ISO639;
- LANGID LangID;
- } ISO639, *LPISO639;
- const ISO639 c_ISO639[] =
- {
- { TEXT("EN"), 0x0409 },
- { TEXT("DE"), 0x0407 },
- { TEXT("JA"), 0x0411 },
- { TEXT("KO"), 0x0412 },
- { TEXT("TW"), 0x0404 },
- { TEXT("CN"), 0x0804 },
- { TEXT("FR"), 0x040C },
- { TEXT("ES"), 0x0C0A },
- { TEXT("BR"), 0x0416 },
- { TEXT("IT"), 0x0410 },
- { TEXT("NL"), 0x0413 },
- { TEXT("SV"), 0x041D },
- { TEXT("DA"), 0x0406 },
- { TEXT("FI"), 0x040B },
- { TEXT("HU"), 0x040E },
- { TEXT("NO"), 0x0414 },
- { TEXT("EL"), 0x0408 },
- { TEXT("PL"), 0x0415 },
- { TEXT("RU"), 0x0419 },
- { TEXT("CS"), 0x0405 },
- { TEXT("PT"), 0x0816 },
- { TEXT("TR"), 0x041F },
- { TEXT("SK"), 0x041B },
- { TEXT("SL"), 0x0424 },
- { TEXT("AR"), 0x0401 },
- { TEXT("HE"), 0x040D },
- { TEXT("EU"), 0x042D },
- { TEXT("IS"), 0x040F },
- };
- // GetInstallLanguage
- //
- // synopsis - borrowed this function from shlwapi. we can remove this
- // once we have it exported from shlwapi.dll
- //
- LANGID GetInstallLanguage(void)
- {
- static LANGID LangID = 0;
- TCHAR szISO639[3];
- DWORD cb;
- if (0 == LangID)
- {
- cb = sizeof(szISO639);
- if (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE, c_szInstall, c_szLocale, NULL, szISO639, &cb))
- {
- int i;
- for (i = 0; i < ARRAYSIZE(c_ISO639); i++)
- {
- if (!StrCmpNI(szISO639, c_ISO639[i].ISO639, ARRAYSIZE(szISO639)))
- {
- LangID = c_ISO639[i].LangID;
- break;
- }
- }
- }
- }
- return LangID;
- }
- // CUILangList
- //
- // maintains the list of UI languages for user to choose
- //
- class CUILangList
- {
- public:
- CUILangList() {_iLangIdx = -1; lang = s_arryLangList;
- _nLangList = ARRAYSIZE(s_arryLangList);
- _fOffice9Installed = -1;};
- void ValidateLangList();
- BOOL IsValidLang(int idx) { return (idx < _nLangList) ? lang[idx].fValid: FALSE; };
- int GetCurrentLangIdx();
- void SetCurrentLangIdx(int idx);
- LPCTSTR GetCurrentLangName();
- LPCTSTR GetLangNameOfIdx(int idx);
- WORD GetLangIdOfIdx(int idx) { return (idx < _nLangList) ? lang[idx].wlangid:0; };
- UINT GetIds(int idx);
- int GetListSize() {return _nLangList;};
- BOOL IsOffice9Installed();
- static HRESULT GetLangList(HWND hdlg, CUILangList ** ppLangList);
- static HRESULT RemoveLangList(HWND hdlg);
- private:
- int _iLangIdx;
- int _nLangList;
- int _fOffice9Installed;
- LANGLIST *lang;
- };
- // CShutDownProcInfo
- //
- // manages information about processes we want
- // to shutdown/restart.
- //
- typedef enum
- {
- PS_UNKNOWN=0,
- PS_CANDIDATE,
- PS_TO_BE_SHUTDOWN,
- PS_IGNORE,
- PS_SHUTDOWN_OK,
- PS_WAITING,
- PS_TO_BE_SHUTDOWN_WITH_NO_RELAUNCH,
- PS_SHUTDOWN_OK_NO_RELAUNCH_NEEDED,
- } PROCSTATE;
- class CShutDownProcInfo : public CProcessInfo
- {
- public:
- CShutDownProcInfo(HWND hdlgParent);
- ~CShutDownProcInfo();
- HRESULT EnsureProcList();
- HRESULT IncreaseProcList();
- HRESULT NotifyShutDownToFolks(int *nProccess);
- HRESULT AddToProcList(HWND hwndShutDown);
- HRESULT WaitForOneProcess(int iProc);
- HRESULT WaitForFolksShutDown();
- HRESULT GetRestartAppPath(LPTSTR szPath, int cchPath, int iProc);
- HRESULT RestartFolks();
- static DWORD CALLBACK ShutDownThreadProc(void *pv);
- protected:
- typedef struct
- {
- DWORD dwPID;
- TCHAR szExeName[32];
- PROCSTATE State;
- } PROCLIST;
- PROCLIST *_pProcList;
- int _nAlloced;
- int _iProcList;
- HWND _hdlgParent;
- BOOL _fAllShutDown;
- };
- // this always fills '0' to empty digits
- // caller has to make sure sz has cdigit+1 of buffer
- void IntToHex(OUT LPTSTR sz, IN int cdigit, IN int value)
- {
- int i, idigit;
- if (sz && value > 0 && cdigit > 0)
- {
- // nul terminate the buffer
- sz[cdigit] = TEXT('\0');
- for (i = cdigit-1; i >= 0; i--, value /= 16)
- {
- idigit = value%16;
- if (idigit < 10)
- sz[i] = (TCHAR)idigit + TEXT('0');
- else
- sz[i] = (TCHAR)idigit - 10 + TEXT('A');
- }
- }
- }
- // set valid flags for the lang list
- // very expensive so expects to be called only once in a session
- // from CUILangList::GetLangList
- //
- #define MAX_SATELLITEPACKS 30 // 30 must be a practical number for satellite packs
- void CUILangList::ValidateLangList()
- {
- HKEY hKey;
- HRESULT hr;
- TCHAR szValueName[32];
- WORD aryValidLang[MAX_SATELLITEPACKS +1+1] = {0}; // +1 for install lang,
- // +1 for terminator
- int nMaxValidLang = ARRAYSIZE(aryValidLang)-1; // -1 for terminator
- WORD *pwValid = aryValidLang;
- // make the install language always valid
- *pwValid = GetInstallLanguage();
- if (*pwValid != 0)
- {
- *(pwValid+1) = 0; // terminator
- pwValid++;
- nMaxValidLang--;
- }
- if (ERROR_SUCCESS ==
- RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_INTERNATIONAL, NULL, KEY_READ, &hKey))
- {
- int i = 0;
- do {
- // see if the value has a match in the list
- DWORD dwType;
- DWORD cb = ARRAYSIZE(szValueName)-2;
- hr = SHEnumValue(hKey, i++, szValueName+2, &cb, &dwType, NULL, NULL);
- if (SUCCEEDED(hr) && dwType == REG_SZ)
- {
- UINT uiInstalled ;
- szValueName[0] = TEXT('0');
- szValueName[1] = TEXT('x');
- StrToIntEx(szValueName, STIF_SUPPORT_HEX, (LPINT)&uiInstalled);
- if (uiInstalled > 0)
- {
- *pwValid = (unsigned short) uiInstalled;
- *(pwValid+1) = 0; // terminator
- pwValid++;
- }
- }
- } while(hr == ERROR_SUCCESS && i < nMaxValidLang);
- RegCloseKey(hKey);
- }
- // this assumes we can use StrChrW to search a value in
- // a word array, it also assumes we never have 0 as a langid
- //
- Assert(sizeof(WORD) == sizeof(WCHAR)); // unix?
- int nValidLang = (int)(pwValid-aryValidLang);
- for(int idx = 0; idx < GetListSize(); idx++ )
- {
- // abusing the string function but this is a fast way
- if (StrChrW((WCHAR *)aryValidLang, (WCHAR)lang[idx].wlangid))
- {
- lang[idx].fValid = TRUE;
- if(--nValidLang <= 0)
- break;
- }
- }
- }
- static const TCHAR s_szPropLangList[] = TEXT("langlist");
- HRESULT CUILangList::GetLangList(HWND hdlg, CUILangList ** ppLangList)
- {
- HRESULT hr=S_OK;
- CUILangList *pLangList = (CUILangList *)GetProp(hdlg, s_szPropLangList);
- if (!pLangList)
- {
- pLangList = new CUILangList();
- if (pLangList)
- {
- pLangList->ValidateLangList();
- SetProp(hdlg, s_szPropLangList, (HANDLE)pLangList);
- }
- else
- hr = E_FAIL;
- }
- ASSERT(ppLangList);
- if (ppLangList)
- *ppLangList = pLangList;
- return hr;
- }
- HRESULT CUILangList::RemoveLangList(HWND hdlg)
- {
- HRESULT hr = S_OK;
- CUILangList *pLangList = (CUILangList *)GetProp(hdlg, s_szPropLangList);
- if (pLangList)
- {
- delete pLangList;
- RemoveProp(hdlg, s_szPropLangList);
- }
- else
- hr = S_FALSE;
- return hr;
- }
- void CUILangList::SetCurrentLangIdx(int idx)
- {
- TCHAR sz[4+1];
- if (idx != _iLangIdx)
- {
- // the resource id is always 4 digit
- IntToHex(sz, 4, lang[idx].wlangid);
- SHSetValue(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL,
- s_szResourceLocale, REG_SZ, (void *)sz, sizeof(sz));
- _iLangIdx = idx;
- }
- }
- // returns idx to the lang array
- int CUILangList::GetCurrentLangIdx()
- {
- // show the current selection
- TCHAR sz[64];
- DWORD dwType;
- int isel;
- // see if it's cached already
- if (_iLangIdx == -1)
- {
- // We basically wants what we've set in the registry,
- // but if Office9 is installed we'll show whatever
- // Office sets, and we can't change the Office setting anyway
- // MLGetUILanguage returns Office's setting if its there
- // Also I suppose we want to show NT5's UI language here
- //
- if (IsOffice9Installed() || IsOS(OS_WIN2000ORGREATER))
- isel = INETCPL_GetUILanguage();
- else
- {
- DWORD dwcbData = sizeof(sz);
- HRESULT hr = SHGetValue(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL,
- s_szResourceLocale, &dwType, (void *)&sz[2], &dwcbData);
- if (hr == ERROR_SUCCESS && dwType == REG_SZ)
- {
- sz[0] = TEXT('0');
- sz[1] = TEXT('x');
- StrToIntEx(sz, STIF_SUPPORT_HEX, (LPINT)&isel);
- }
- else
- {
- isel = GetInstallLanguage();
- }
- }
- for(int i = 0; i < GetListSize(); i++ )
- {
- if (isel == lang[i].wlangid)
- {
- _iLangIdx = i;
- break;
- }
- }
- // english for error case
- if (_iLangIdx < 0)
- _iLangIdx = 0;
- }
- return _iLangIdx;
- }
- LPCTSTR CUILangList::GetLangNameOfIdx(int idx)
- {
- LPCTSTR pszRet = NULL;
- IMultiLanguage2 *pML2;
- HRESULT hr;
- RFC1766INFO Rfc1766Info={0};
- if(!hOLE32)
- {
- if(!_StartOLE32())
- {
- ASSERT(FALSE);
- return NULL;
- }
- }
- hr = pCoInitialize(NULL);
- if (FAILED(hr))
- return NULL;
- hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2);
- if (SUCCEEDED(hr))
- {
- if (idx >= 0)
- {
- if (!lang[idx].szName[0])
- {
- pML2->GetRfc1766Info(lang[idx].wlangid, INETCPL_GetUILanguage(), &Rfc1766Info);
- StrCpyNW(lang[idx].szName, Rfc1766Info.wszLocaleName, ARRAYSIZE(lang[0].szName));
- }
- pszRet = lang[idx].szName;
- }
- pML2->Release();
- }
- pCoUninitialize();
- return pszRet;
- }
- LPCTSTR CUILangList::GetCurrentLangName()
- {
- int idx = GetCurrentLangIdx();
- return GetLangNameOfIdx(idx);
- }
- BOOL CUILangList::IsOffice9Installed()
- {
- DWORD dwVersion;
- DWORD cb = sizeof(dwVersion);
- if (_fOffice9Installed < 0)
- {
- _fOffice9Installed ++;
- if (ERROR_SUCCESS ==
- SHGetValue(HKEY_LOCAL_MACHINE, s_szLangPackPath, s_szVersion, NULL, &dwVersion, &cb)
- && dwVersion > 0) // magic number - christw tells me so
- _fOffice9Installed ++;
- }
- return (BOOL)_fOffice9Installed;
- }
- void InitCurrentUILang(HWND hDlg)
- {
- BOOL fChanged = FALSE;
- CUILangList *pLangList;
- LPCTSTR pszLangSel = NULL;
- HRESULT hr;
- hr = CUILangList::GetLangList(hDlg, &pLangList);
- if (SUCCEEDED(hr))
- pszLangSel = pLangList->GetCurrentLangName();
- if (pszLangSel)
- {
- TCHAR szBig[1024], szSmall[256];
- GetDlgItemText(hDlg, IDC_LANG_CURSEL, szBig, ARRAYSIZE(szBig));
- if (szBig[0])
- fChanged = (StrStr(szBig, pszLangSel) == NULL);
- if (MLLoadString((fChanged)? IDS_LANG_FUTUREUSE: IDS_LANG_CURRENTUSE, szSmall, ARRAYSIZE(szSmall)) > 0)
- {
- wnsprintf(szBig, ARRAYSIZE(szBig), szSmall, pszLangSel);
- Static_SetText(GetDlgItem(hDlg, IDC_LANG_CURSEL), szBig);
- }
- }
- }
- //
- // FillAcceptListBox()
- //
- // Fills the accept language listbox with names of selected language
- //
- void FillAcceptListBox(IN HWND hDlg)
- {
- IMultiLanguage2 *pML2;
- HRESULT hr;
- HKEY hKey;
- DWORD cb;
- TCHAR sz[MAX_LIST_STRING_LEN], szBuf[MAX_ACCEPT_LANG_LEN], *p1, *p2, *p3;
- HWND hwndList = GetDlgItem(hDlg, IDC_LANG_ACCEPT_LIST);
- if(!hOLE32)
- {
- if(!_StartOLE32())
- {
- ASSERT(FALSE);
- return;
- }
- }
- hr = pCoInitialize(NULL);
- if (FAILED(hr))
- return;
- hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2);
- if (SUCCEEDED(hr))
- {
- if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL, NULL, NULL, NULL, KEY_SET_VALUE|KEY_READ, NULL, &hKey, NULL))
- {
- LCID lcid;
- RFC1766INFO Rfc1766Info;
- TCHAR sz1[MAX_LIST_STRING_LEN], sz2[MAX_RFC1766_NAME];
- cb = sizeof(szBuf);
- if (ERROR_SUCCESS == RegQueryValueEx(hKey, REGSTR_VAL_ACCEPT_LANGUAGE, NULL, NULL, (LPBYTE)szBuf, &cb))
- {
- p1 = p2 = szBuf;
- while (NULL != *p1)
- {
- WCHAR wsz[MAX_LIST_STRING_LEN];
- BOOL bEnd = FALSE;
- while (TEXT(',') != *p2 && NULL != *p2)
- p2 = CharNext(p2);
- if (NULL != *p2)
- *p2 = NULL;
- else
- bEnd = TRUE;
- p3 = p1;
- while (TEXT(';') != *p3 && NULL != *p3)
- p3 = CharNext(p3);
- if (NULL != *p3)
- *p3 = NULL;
- #ifdef UNICODE
- StrCpyN(wsz, p1, ARRAYSIZE(wsz));
- #else
- MultiByteToWideChar(CP_ACP, 0, p1, -1, wsz, MAX_RFC1766_NAME);
- #endif
- hr = pML2->GetLcidFromRfc1766(&lcid, wsz);
- if (SUCCEEDED(hr))
- {
- hr = pML2->GetRfc1766Info(lcid, INETCPL_GetUILanguage(), &Rfc1766Info);
- if (SUCCEEDED(hr))
- {
- #ifdef UNICODE
- StrCpyN(sz1, Rfc1766Info.wszLocaleName, ARRAYSIZE(sz1));
- #else
- WideCharToMultiByte(CP_ACP, 0, Rfc1766Info.wszLocaleName, -1, sz1, MAX_LIST_STRING_LEN, NULL, NULL);
- #endif
- wnsprintf(sz, ARRAYSIZE(sz), FORMAT_STR, sz1, p1);
- }
- }
- else
- {
- MLLoadString(IDS_USER_DEFINED, sz1, ARRAYSIZE(sz1));
- wnsprintf(sz, ARRAYSIZE(sz), FORMAT_STR, sz1, p1);
- }
- ListBox_AddString(hwndList, sz);
- if (TRUE == bEnd)
- p1 = p2;
- else
- p1 = p2 = p2 + 1;
- }
- }
- else
- {
- lcid = GetUserDefaultLCID();
- hr = pML2->GetRfc1766Info(lcid, INETCPL_GetUILanguage(), &Rfc1766Info);
- if (SUCCEEDED(hr))
- {
- #ifdef UNICODE
- StrCpyN(sz1, Rfc1766Info.wszLocaleName, ARRAYSIZE(sz1));
- StrCpyN(sz2, Rfc1766Info.wszRfc1766, ARRAYSIZE(sz2));
- #else
- WideCharToMultiByte(CP_ACP, 0, Rfc1766Info.wszLocaleName, -1, sz1, MAX_LIST_STRING_LEN, NULL, NULL);
- WideCharToMultiByte(CP_ACP, 0, Rfc1766Info.wszRfc1766, -1, sz2, MAX_RFC1766_NAME, NULL, NULL);
- #endif
- wnsprintf(sz, ARRAYSIZE(sz), FORMAT_STR, sz1, sz2);
- ListBox_AddString(hwndList, sz);
- }
- }
- RegCloseKey(hKey);
- }
- pML2->Release();
- }
- pCoUninitialize();
- }
- //
- // LanguageDlgInit()
- //
- // Initializes the Language dialog.
- //
- BOOL LanguageDlgInit(IN HWND hDlg)
- {
- if (!hDlg)
- return FALSE; // nothing to initialize
- FillAcceptListBox(hDlg);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_REMOVE_BUTTON), FALSE);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_UP_BUTTON), FALSE);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_DOWN_BUTTON), FALSE);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_ADD_BUTTON), !g_restrict.fInternational);
- // On NT5, we use NT5's MUI feature instead of IE5 plugui
- if (IsOS(OS_WIN2000ORGREATER))
- ShowWindow(GetDlgItem(hDlg, IDC_LANG_UI_PREF), SW_HIDE);
- else
- {
- UINT uiACP = GetACP();
- // We don't support PlugUI on these platforms
- if (uiACP == CP_ARABIC || uiACP == CP_HEBREW || uiACP == CP_THAI)
- ShowWindow(GetDlgItem(hDlg, IDC_LANG_UI_PREF), SW_HIDE);
- else
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_UI_PREF), !g_restrict.fInternational);
- }
- // show the current UI lang
- InitCurrentUILang(hDlg);
- // everything ok
- return TRUE;
- }
- //
- // SaveLanguageData()
- //
- // Save the new language settings into regestry
- //
- void SaveLanguageData(IN HWND hDlg)
- {
- HKEY hKey;
- DWORD dw;
- int i, iNumItems, iQ, n;
- TCHAR szBuf[MAX_ACCEPT_LANG_LEN];
- if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_INTERNATIONAL, NULL, NULL, NULL, KEY_WRITE, NULL, &hKey, &dw ))
- {
- HWND hwndList = GetDlgItem(hDlg, IDC_LANG_ACCEPT_LIST);
- iNumItems = ListBox_GetCount(hwndList);
- for (n = 1, iQ = 10; iQ < iNumItems; iQ *= 10, n++)
- ;
- szBuf[0] = NULL;
- for (i = 0; i < iNumItems; i++)
- {
- TCHAR sz[MAX_LIST_STRING_LEN], *p1, *p2;
- ListBox_GetText(hwndList, i, sz);
- p1 = sz;
- // We can assume safely there is '[' and ']' in this string.
- while (TEXT('[') != *p1)
- p1 = CharNext(p1);
- p1 = p2 = p1 + 1;
- while (TEXT(']') != *p2)
- p2 = CharNext(p2);
- *p2 = NULL;
- if (0 == i)
- StrCpyN(szBuf, p1, ARRAYSIZE(szBuf));
- else
- {
- TCHAR szF[MAX_ACCEPT_LANG_LEN], szQ[MAX_ACCEPT_LANG_LEN];
- int len = lstrlen(szBuf);
- StrCpyN(szBuf + len, TEXT(","), ARRAYSIZE(szBuf) - len);
- len++;
- StrCpyN(szBuf + len, p1, ARRAYSIZE(szBuf) - len);
- wnsprintf(szF, ARRAYSIZE(szF), TEXT(";q=0.%%0%dd"), n);
- wnsprintf(szQ, ARRAYSIZE(szQ), szF, ((iNumItems - i) * iQ + (iNumItems / 2)) / iNumItems);
- len = lstrlen(szBuf);
- StrCpyN(szBuf + len , szQ, ARRAYSIZE(szBuf) - len);
- }
- }
- RegSetValueEx(hKey, REGSTR_VAL_ACCEPT_LANGUAGE, NULL, REG_SZ, (LPBYTE)szBuf, (lstrlen(szBuf)+1)*sizeof(TCHAR));
- RegCloseKey(hKey);
- }
- }
- // MoveUpDownListItem()
- //
- // Move selected list item up or down
- //
- void MoveUpDownListItem(HWND hDlg, HWND hwndList, BOOL bUp)
- {
- int i, iNumItems;
- TCHAR sz[MAX_LIST_STRING_LEN];
- i = ListBox_GetCurSel(hwndList);
- iNumItems = ListBox_GetCount(hwndList);
- ListBox_GetText(hwndList, i, sz);
- ListBox_DeleteString(hwndList, i);
- i += (bUp)? -1: 1;
- if (i < 0)
- i = 0;
- else if (i >= iNumItems)
- i = iNumItems - 1;
- ListBox_InsertString(hwndList, i, sz);
- ListBox_SetSel(hwndList, TRUE, i);
- ListBox_SetCurSel(hwndList, i);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_UP_BUTTON), i != 0);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_DOWN_BUTTON), i < iNumItems - 1);
- if (NULL == GetFocus()) // This prevent keyboard access disable
- SetFocus(hwndList);
- }
- //
- // FillLanguageListBox()
- //
- // Fills the language listbox with the names of available languages
- //
- BOOL FillLanguageListBox(IN HWND hDlg)
- {
- IMultiLanguage2 *pML2;
- HRESULT hr;
- TCHAR sz[MAX_LIST_STRING_LEN], sz1[MAX_LOCALE_NAME], sz2[MAX_RFC1766_NAME];
- HWND hwndEdit = GetDlgItem(hDlg, IDC_LANG_USER_DEFINED_EDIT);
- HWND hwndList = GetDlgItem(hDlg, IDC_LANG_AVAILABLE_LIST);
- HWND hwndAccept = GetDlgItem(GetParent(hDlg), IDC_LANG_ACCEPT_LIST);
- SendMessage(hwndEdit, EM_SETLIMITTEXT, 16, 0L); // Set Limit text as 16 characters
- if(!hOLE32)
- {
- if(!_StartOLE32())
- {
- ASSERT(FALSE);
- return FALSE;
- }
- }
- hr = pCoInitialize(NULL);
- if (FAILED(hr))
- return FALSE;
- hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2);
- if (SUCCEEDED(hr))
- {
- IEnumRfc1766 *pEnumRfc1766;
- RFC1766INFO Rfc1766Info;
- if (SUCCEEDED(pML2->EnumRfc1766(INETCPL_GetUILanguage(), &pEnumRfc1766)))
- {
- while (S_OK == pEnumRfc1766->Next(1, &Rfc1766Info, NULL))
- {
- #ifdef UNICODE
- StrCpyN(sz1, Rfc1766Info.wszLocaleName, ARRAYSIZE(sz1));
- StrCpyN(sz2, Rfc1766Info.wszRfc1766, ARRAYSIZE(sz2));
- #else
- WideCharToMultiByte(CP_ACP, 0, Rfc1766Info.wszLocaleName, -1, sz1, MAX_LOCALE_NAME, NULL, NULL);
- WideCharToMultiByte(CP_ACP, 0, Rfc1766Info.wszRfc1766, -1, sz2, MAX_RFC1766_NAME, NULL, NULL);
- #endif
- wnsprintf(sz, ARRAYSIZE(sz), FORMAT_STR, sz1, sz2);
- if (LB_ERR == ListBox_FindStringExact(hwndAccept, -1, sz))
- ListBox_AddString(hwndList, sz);
- }
- pEnumRfc1766->Release();
- }
- pML2->Release();
- }
- pCoUninitialize();
- // everything ok
- return TRUE;
- }
- //
- // AddLanguage()
- //
- // Add selected language to accept language listbox.
- //
- void AddLanguage(IN HWND hDlg)
- {
- int i, j, *pItems, iNumItems, iIndex;
- TCHAR sz[MAX_LIST_STRING_LEN];
- HWND hdlgParent = GetParent(hDlg);
- HWND hwndFrom = GetDlgItem(hDlg, IDC_LANG_AVAILABLE_LIST);
- HWND hwndTo = GetDlgItem(hdlgParent, IDC_LANG_ACCEPT_LIST);
- i = ListBox_GetSelCount(hwndFrom);
- if (0 < i && (pItems = (PINT)LocalAlloc(LPTR, sizeof(int)*i)))
- {
- ListBox_GetSelItems(hwndFrom, i, pItems);
- for (j = 0; j < i; j++)
- {
- ListBox_GetText(hwndFrom, pItems[j], sz);
- ListBox_AddString(hwndTo, sz);
- }
- LocalFree(pItems);
- }
- if (GetWindowTextLength(GetDlgItem(hDlg, IDC_LANG_USER_DEFINED_EDIT)))
- {
- TCHAR *p, sz1[MAX_LIST_STRING_LEN], sz2[MAX_LIST_STRING_LEN];
- BOOL fValid = TRUE;
- GetWindowText(GetDlgItem(hDlg, IDC_LANG_USER_DEFINED_EDIT), sz2, ARRAYSIZE(sz2));
- p = sz2;
- while (NULL != *p && TRUE == fValid)
- {
- switch (*p)
- {
- // Invalid characters for user-defined string
- case TEXT(','):
- case TEXT(';'):
- case TEXT('['):
- case TEXT(']'):
- case TEXT('='):
- fValid = FALSE;
- break;
- default:
- p = CharNext(p);
- }
- }
- if (FALSE == fValid)
- {
- TCHAR szTitle[256], szErr[1024];
- MLLoadShellLangString(IDS_USER_DEFINED_ERR, szErr, ARRAYSIZE(szErr));
- GetWindowText(hDlg, szTitle, ARRAYSIZE(szTitle));
- MessageBox(hDlg, szErr, szTitle, MB_OK | MB_ICONHAND);
- }
- else
- {
- MLLoadString(IDS_USER_DEFINED, sz1, ARRAYSIZE(sz1));
- wnsprintf(sz, ARRAYSIZE(sz), FORMAT_STR, sz1, sz2);
- ListBox_AddString(hwndTo, sz);
- }
- }
- iIndex = ListBox_GetCurSel(hwndTo);
- if (LB_ERR != iIndex)
- {
- iNumItems = ListBox_GetCount(hwndTo);
- EnableWindow(GetDlgItem(hdlgParent, IDC_LANG_REMOVE_BUTTON), iNumItems > 0);
- EnableWindow(GetDlgItem(hdlgParent, IDC_LANG_MOVE_UP_BUTTON), iIndex > 0);
- EnableWindow(GetDlgItem(hdlgParent, IDC_LANG_MOVE_DOWN_BUTTON), iIndex < iNumItems - 1);
- }
- }
- int ComboBoxEx_AddString(IN HWND hwndCtl, IN LPCTSTR sz)
- {
- COMBOBOXEXITEM cbexItem = {0};
- int csz = _tcslen(sz);
- cbexItem.mask = CBEIF_TEXT;
- cbexItem.pszText = (LPTSTR)sz;
- cbexItem.cchTextMax = csz;
- // sort the string based on the current locale
- // we don't bother to use binary search because
- // the list is up to 25 item
- TCHAR szItem[MAX_LOCALE_NAME];
- int i, itemCount = ComboBox_GetCount(hwndCtl);
- for (i = 0; i < itemCount; i++)
- {
- ComboBox_GetLBText(hwndCtl, i, szItem);
- if (CompareString(INETCPL_GetUILanguage(),
- 0,
- sz,
- csz,
- szItem,
- ARRAYSIZE(szItem)) == CSTR_LESS_THAN)
- {
- break;
- }
- }
- cbexItem.iItem = i;
- SendMessage(hwndCtl, CBEM_INSERTITEM, (WPARAM)0, (LPARAM)(LPVOID)&cbexItem);
- return i;
- }
- BOOL FillUILangListBox(IN HWND hDlg, CUILangList *pLangList)
- {
- HWND hwndCombo = GetDlgItem(hDlg, IDC_COMBO_UILANG);
- BOOL bNT5 = IsOS(OS_WIN2000ORGREATER);
- DWORD dwAcp = GetACP();
- LPCTSTR pszLangName;
- if (!pLangList)
- return FALSE;
- // fill the list up.
- for (int i = 0; i < pLangList->GetListSize(); i++)
- {
- if (!pLangList->IsValidLang(i))
- continue;
- if (!bNT5)
- {
- LANGID lid = pLangList->GetLangIdOfIdx(i);
- if (dwAcp == CP_THAI || dwAcp == CP_ARABIC || dwAcp == CP_HEBREW)
- {
- // do not support cross codepage PlugUI
- // on Thai or Middle East platform(Arabic/Hebrew)
- static DWORD dwDefCP = 0;
- if (dwDefCP == 0)
- {
- TCHAR szLcData[6+1]; // +2 for '0x' +1 for terminator
- GetLocaleInfo( MAKELCID(lid, SUBLANG_NEUTRAL),
- LOCALE_IDEFAULTANSICODEPAGE, szLcData, ARRAYSIZE(szLcData));
- dwDefCP = StrToInt(szLcData);
- }
- if (dwDefCP != dwAcp && lid != 0x0409 && lid != GetInstallLanguage())
- continue;
- }
- else
- {
- // skip Arabic and Hebrew on non-supporting platform
- if (lid == 0x401 || lid == 0x40d)
- continue;
- }
- }
- pszLangName = pLangList->GetLangNameOfIdx(i);
- // ComboBox_FindStringExact has problems to handle DBCS Unicode characters
- if (pszLangName)
- {
- int ipos = ComboBoxEx_AddString(hwndCombo, pszLangName);
- if (ipos >= 0)
- {
- ComboBox_SetItemData(hwndCombo, ipos, i);
- }
- }
- }
- // show the current selection
- int iLangIdx = pLangList->GetCurrentLangIdx();
- if (iLangIdx >= 0)
- {
- int iCBPos;
- int iCBSize = ComboBox_GetCount(hwndCombo);
- for (iCBPos = 0; iCBPos < iCBSize; iCBPos++)
- {
- if (iLangIdx == ComboBox_GetItemData(hwndCombo, iCBPos))
- break;
- }
- if (iCBPos < iCBSize)
- ComboBox_SetCurSel(hwndCombo, iCBPos);
- }
- return TRUE;
- }
- //
- // Shutdown/reboot procedures implementation
- //
- // synopsis: CShutDownInfo class implements the method and the process list
- // which handle the sequence.
- // s_arryClsNames[] holds the list of target application
- // ChangeLanguage() (global) triggers the sequence being called from
- // LangChangeDlgProc().
- //
- static const LPTSTR s_arryClsNames[] =
- {
- TEXT("IEFrame"), // browser instance
- TEXT("ThorBrowserWndClass"), // OE
- TEXT("HH Parent"), // Html Help
- TEXT("MPWClass"), //
- TEXT("Outlook Express Browser Class"), // OE
- TEXT("ATH_Note"), // OE?
- TEXT("WABBrowseView"), // WAB
- TEXT("Afx:400000:8:10008:0:900d6"),
- TEXT("Media Player 2"),
- TEXT("FrontPageExpressWindow"),
- TEXT("MSBLUIManager"), // Messenger
- };
- //
- // CShutDownInfo
- // class methods implementation
- //
- #define SHUTDOWN_TIMEOUT 2000 // 2 sec
- #define RELAUNCH_TIMEOUT 1000 // 1 sec
- CShutDownProcInfo::CShutDownProcInfo(HWND hDlg)
- {
- _pProcList = NULL;
- _nAlloced = 0;
- _iProcList = 0;
- _hdlgParent = hDlg;
- _fAllShutDown = FALSE;
- }
- CShutDownProcInfo::~CShutDownProcInfo()
- {
- if (_pProcList)
- LocalFree(_pProcList);
- }
- HRESULT CShutDownProcInfo::EnsureProcList()
- {
- HRESULT hr = S_OK;
- if (!_pProcList)
- {
- // alloc mem for practical # of processes
- _nAlloced = ARRAYSIZE(s_arryClsNames);
- _pProcList = (PROCLIST *)LocalAlloc(LPTR, sizeof(PROCLIST)*_nAlloced);
- }
- if (!_pProcList)
- {
- _nAlloced = 0;
- hr = E_FAIL;
- }
- return hr;
- }
- HRESULT CShutDownProcInfo::IncreaseProcList()
- {
- HRESULT hr = S_OK;
- PROCLIST * pl = NULL;
- // realloc mem every so often
- if (_iProcList+1 > _nAlloced)
- {
- pl = (PROCLIST *)LocalReAlloc(_pProcList, sizeof(PROCLIST)*(ARRAYSIZE(s_arryClsNames)+_nAlloced),
- LMEM_MOVEABLE | LMEM_ZEROINIT);
- if (pl)
- {
- _nAlloced += ARRAYSIZE(s_arryClsNames);
- _pProcList = pl;
- }
- else
- hr = E_FAIL;
- }
- if (hr == S_OK)
- _iProcList++;
- return hr;
- }
- // CShutDownProcInfo::AddToProcList()
- //
- // synopsis: Get process info from given window handle
- // store it for shutdown procedure
- //
- //
- //
- HRESULT CShutDownProcInfo::AddToProcList(HWND hwnd)
- {
- HRESULT hr = S_OK;
- hr = EnsureProcList();
- if (SUCCEEDED(hr) && hwnd)
- {
- DWORD dwPID;
- BOOL fFoundDup = FALSE;
- GetWindowThreadProcessId(hwnd, &dwPID);
- // check to see if we already have the PID in the list
- for (int i=0; i < _iProcList; i++)
- {
- if (_pProcList[i].dwPID == dwPID)
- {
- fFoundDup = TRUE;
- break;
- }
- }
- // add proccess info only if we don't have it already
- if (!fFoundDup)
- {
- hr = IncreaseProcList();
- if (SUCCEEDED(hr))
- {
- int iCur = _iProcList-1;
- GetExeNameFromPID(dwPID,
- _pProcList[iCur].szExeName,
- ARRAYSIZE(_pProcList[iCur].szExeName));
- _pProcList[iCur].dwPID = dwPID;
- _pProcList[iCur].State = PS_UNKNOWN;
- }
- }
- }
- return hr;
- }
- // CShutDownProcInfo::WaitForOneProcess
- //
- // synopsis: ensures the given process
- // has terminated
- //
- //
- HRESULT CShutDownProcInfo::WaitForOneProcess(int iProc)
- {
- HRESULT hr = S_OK;
- if (iProc < _iProcList && _pProcList[iProc].State != PS_SHUTDOWN_OK)
- {
- DWORD dwProcessFlags = PROCESS_ALL_ACCESS |
- (_fNT ? SYNCHRONIZE : 0 );
- HANDLE hProc = OpenProcess(dwProcessFlags,
- FALSE,
- _pProcList[iProc].dwPID);
- // pressume it has terminated, get it marked so
- _pProcList[iProc].State = PS_SHUTDOWN_OK;
- if (hProc)
- {
- // if the proccess in query is still alive,
- // we'll wait with time out here
- //
- DWORD dwRet = WaitForSingleObject (hProc, SHUTDOWN_TIMEOUT);
- if (dwRet == WAIT_TIMEOUT)
- {
- _pProcList[iProc].State = PS_WAITING;
- }
- CloseHandle(hProc);
- }
- }
- return hr;
- }
- // CShutDownProcInfo::WaitForFolksShutDown
- //
- // synopsis: ensure the nominated processes terminate. If anyone
- // doesn't want to terminate, wait for her retrying a couple of
- // times and note her name so we can show it to the user.
- //
- //
- #define MAXSHUTDOWNTRY 10
- HRESULT CShutDownProcInfo::WaitForFolksShutDown()
- {
- HRESULT hr = S_OK;
- int iTry = 0;
- do
- {
- // pressume all will be fine
- _fAllShutDown = TRUE;
- // waiting loop
- for (int i = 0; i < _iProcList; i++)
- {
- WaitForOneProcess(i);
- if (_pProcList[i].State != PS_SHUTDOWN_OK)
- _fAllShutDown = FALSE;
- }
- }
- while( !_fAllShutDown && iTry++ < MAXSHUTDOWNTRY );
- // FEATURE: here we should put up a dialog
- // to ask user if they want to wait
- // for the apps
- return hr;
- }
- // CShutDownProcInfo::NotifyShutDownToFolks
- //
- // synopsis: send POI_OFFICE_COMMAND to possible candidates on the desktop
- // if a candidate replies with valid value, save the proccess
- // information for the later restart procedure.
- //
- HRESULT CShutDownProcInfo::NotifyShutDownToFolks(int *pnProcess)
- {
- HWND hwndShutDown, hwndAfter;
- PLUGUI_QUERY pq;
- HRESULT hr = S_OK;
- int nProcToShutDown = 0;
- for (int i = 0; i < ARRAYSIZE(s_arryClsNames); i++)
- {
- hwndAfter = NULL;
- while (hwndShutDown = FindWindowEx(NULL, hwndAfter, s_arryClsNames[i], NULL))
- {
- pq.uQueryVal = (UINT)SendMessage(hwndShutDown, PUI_OFFICE_COMMAND, PLUGUI_CMD_QUERY, 0);
- if (pq.uQueryVal)
- {
- if(pq.PlugUIInfo.uMajorVersion == OFFICE_VERSION_9)
- {
- PostMessage(hwndShutDown, PUI_OFFICE_COMMAND, (WPARAM)PLUGUI_CMD_SHUTDOWN, 0);
- // store the information about the process which this window belongs to
- // we only need to remember non OLE processes here for re-starting.
- if (!pq.PlugUIInfo.uOleServer)
- {
- AddToProcList(hwndShutDown);
- nProcToShutDown ++;
- }
- }
- }
- hwndAfter = hwndShutDown;
- }
- }
- if (!nProcToShutDown)
- hr = S_FALSE;
- if (pnProcess)
- *pnProcess = nProcToShutDown;
- return hr;
- }
- const TCHAR c_szRegAppPaths[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
- HRESULT CShutDownProcInfo::GetRestartAppPath(LPTSTR szPath, int cchPath, int iProc)
- {
- HRESULT hr = S_OK;
- TCHAR szAppPath[MAX_PATH];
- TCHAR szRegKey[MAX_PATH];
- ASSERT(szPath && cchPath > 0);
- if (iProc < _iProcList)
- {
- _tcscpy(szRegKey, c_szRegAppPaths);
- _tcscat(szRegKey, _pProcList[iProc].szExeName);
- DWORD cb = sizeof(szAppPath);
- if (ERROR_SUCCESS != SHGetValue(HKEY_LOCAL_MACHINE, szRegKey, NULL, NULL, szAppPath, &cb))
- {
- szPath[0] = TEXT('0');
- hr = E_FAIL;
- }
- else
- _tcsncpy(szPath, szAppPath, cchPath);
- }
- return hr;
- }
- HRESULT CShutDownProcInfo::RestartFolks()
- {
- PROCESS_INFORMATION pi;
- for (int i = 0; i < _iProcList; i++)
- {
- STARTUPINFO si = {0};
- si.cb = sizeof(si);
- if (_pProcList[i].State == PS_SHUTDOWN_OK)
- {
- TCHAR szAppPath[MAX_PATH];
- HRESULT hr = GetRestartAppPath(szAppPath, ARRAYSIZE(szAppPath), i);
- if (hr == S_OK)
- {
- BOOL fLaunchedOK =
- CreateProcess (szAppPath, // name of app to launch
- NULL, // lpCmdLine
- NULL, // lpProcessAttributes
- NULL, // lpThreadAttributes
- TRUE, // bInheritHandles
- NORMAL_PRIORITY_CLASS, // dwCreationFlags
- NULL, // lpEnvironment
- NULL, // lpCurrentDirectory
- &si, // lpStartupInfo
- &pi); // lpProcessInformation
- if (fLaunchedOK)
- {
- DWORD dwRet = WaitForInputIdle (pi.hProcess,
- RELAUNCH_TIMEOUT);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
- }
- }
- }
- return S_OK;
- }
- //
- // CShutDownProcInfo::ShutDownThreadProc
- //
- // synopsis: launched from changelang dialog so the dialog
- // wouldn't get blocked when we're waiting for our apps
- // to shutdown/restart. this is a static proc
- // so we should be able to delete the class instance
- // in this proc.
- //
- DWORD CALLBACK CShutDownProcInfo::ShutDownThreadProc(void *pv)
- {
- CShutDownProcInfo *pspi = (CShutDownProcInfo *)pv;
- if (pspi)
- {
- HRESULT hr;
- int nToShutDown;
- // send PUI_OFFICE_COMMAND to corresponding folks...
- hr = pspi->NotifyShutDownToFolks(&nToShutDown);
- // and wait until all processes shutdown
- if (SUCCEEDED(hr) && nToShutDown > 0)
- {
- hr = pspi->WaitForFolksShutDown();
- // then restart here
- if (SUCCEEDED(hr))
- pspi->RestartFolks();
- }
- // now the parent dialog should go away
- int iret = (nToShutDown > 0) ?
- RETURN_SETLANG_ENDLANGDIALOG: RETURN_SETLANG_CLOSEDNORMAL;
- EndDialog(pspi->_hdlgParent, iret);
- // delete this class instance
- delete pspi;
- }
- return 0;
- }
- void OpenSatelliteDownloadUrl(HWND hDlg)
- {
- // get the default Url from registry
- TCHAR szSatelliteUrl[INTERNET_MAX_URL_LENGTH];
- // reg api needs size in byte
- DWORD dwType, dwcbData = sizeof(szSatelliteUrl);
- DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_INTERNATIONAL,
- NULL, &dwType, (void *)szSatelliteUrl, &dwcbData);
- if (dwRet != ERROR_SUCCESS || !szSatelliteUrl[0])
- {
- // use the hard coded Url instead
- _tcscpy(szSatelliteUrl, s_szUrlSPK);
- }
- if(!hOLE32)
- {
- if(!_StartOLE32())
- {
- ASSERT(FALSE);
- return;
- }
- }
- HRESULT hr = pCoInitialize(NULL);
- if (SUCCEEDED(hr))
- {
- NavToUrlUsingIE(szSatelliteUrl, TRUE);
- pCoUninitialize();
- }
- }
- INT_PTR CALLBACK LangMsgDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_COMMAND:
- {
- switch (GET_WM_COMMAND_ID(wParam, lParam))
- {
- case IDYES:
- case IDNO:
- case IDOK:
- case IDCANCEL:
- EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam));
- break;
- }
- return TRUE;
- }
- case WM_HELP: // F1
- ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
- HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- case WM_CONTEXTMENU: // right mouse click
- ResWinHelp( (HWND) wParam, IDS_HELPFILE,
- HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- }
- return FALSE;
- }
- BOOL ChangeLanguage(IN HWND hDlg, CUILangList *pLangList)
- {
- HWND hwndCombo = GetDlgItem(hDlg, IDC_COMBO_UILANG);
- int iSel = ComboBox_GetCurSel(hwndCombo);
- INT_PTR idxSel = 0;
- int idxCur;
- if (iSel != CB_ERR)
- idxSel = ComboBox_GetItemData(hwndCombo, iSel);
- if ( idxSel != CB_ERR
- && idxSel < pLangList->GetListSize())
- {
- idxCur = pLangList->GetCurrentLangIdx();
- if (idxCur != idxSel)
- {
- INT_PTR iRet = DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_LANG_WARNING), hDlg, LangMsgDlgProc);
- if (IDCANCEL != iRet)
- {
- pLangList->SetCurrentLangIdx((int)idxSel);
- if (IDYES == iRet)
- {
- CShutDownProcInfo *pspi = new CShutDownProcInfo(hDlg);
- if (!SHCreateThread(pspi->ShutDownThreadProc, (void *)pspi, 0, NULL))
- delete pspi;
- // returning TRUE to indicate that we do shutdown/restart
- return TRUE;
- }
- else
- {
- DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_LANG_INFO), hDlg, LangMsgDlgProc);
- }
- }
- }
- }
- // returning FALSE to indicate that we haven't changed the language
- return FALSE;
- }
- //
- // LangChangeDlgProc()
- //
- // Message handler for the "Change Language" subdialog.
- //
- INT_PTR CALLBACK LangChangeDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- CUILangList *pLangList;
- switch (uMsg)
- {
- case WM_INITDIALOG:
- CUILangList::GetLangList(GetParent(hDlg), &pLangList);
- return FillUILangListBox(hDlg, pLangList);
- case WM_DESTROY:
- break;
- case WM_COMMAND:
- switch(GET_WM_COMMAND_ID(wParam, lParam))
- {
- case IDC_LANG_ADDSPK:
- // open url from resource
- OpenSatelliteDownloadUrl(hDlg);
- EndDialog(hDlg, RETURN_SETLANG_ENDLANGDIALOG);
- break;
- case IDOK:
- if(!SUCCEEDED(CUILangList::GetLangList(GetParent(hDlg), &pLangList))
- || !ChangeLanguage(hDlg, pLangList))
- EndDialog(hDlg, 0);
- // EndDialog() is called in separate thread
- // when shutdown/restart is done
- //
- break;
- case IDCANCEL:
- EndDialog(hDlg, 0);
- break;
- }
- break;
- case WM_HELP: // F1
- ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
- HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- case WM_CONTEXTMENU: // right mouse click
- ResWinHelp( (HWND) wParam, IDS_HELPFILE,
- HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- //
- // LangAddDlgProc()
- //
- // Message handler for the "Add Language" subdialog.
- //
- INT_PTR CALLBACK LangAddDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_INITDIALOG:
- return FillLanguageListBox(hDlg);
- case WM_DESTROY:
- break;
- case WM_COMMAND:
- switch(GET_WM_COMMAND_ID(wParam, lParam))
- {
- case IDOK:
- AddLanguage(hDlg);
- EndDialog(hDlg, 0);
- break;
- case IDCANCEL:
- EndDialog(hDlg, 0);
- break;
- }
- break;
- case WM_HELP: // F1
- ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
- HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- case WM_CONTEXTMENU: // right mouse click
- ResWinHelp( (HWND) wParam, IDS_HELPFILE,
- HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- // put any cleanup procedures for language dialog here
- void LangDlgCleanup(HWND hDlg)
- {
- // also delete and remove the instance of
- // UI language list from window prop
- CUILangList::RemoveLangList(hDlg);
- }
- //
- // LanguageDlgProc()
- //
- // Message handler for the "Language Preference" subdialog.
- //
- INT_PTR CALLBACK LanguageDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- CUILangList *pLangList;
- switch (uMsg)
- {
- case WM_INITDIALOG:
- return LanguageDlgInit(hDlg);
- case WM_DESTROY:
- LangDlgCleanup(hDlg);
- break;
- case WM_COMMAND:
- switch(GET_WM_COMMAND_ID(wParam, lParam))
- {
- HWND hwndList;
- int iIndex, iNumItems;
- INT_PTR iret;
- case IDOK:
- SaveLanguageData(hDlg);
- EndDialog(hDlg, 0);
- break;
- case IDCANCEL:
- EndDialog(hDlg, 0);
- break;
- case IDC_LANG_ADD_BUTTON:
- DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_LANG_ADD), hDlg, LangAddDlgProc);
- break;
- case IDC_LANG_UI_PREF:
- CUILangList::GetLangList(hDlg, &pLangList);
- iret = KickSetLang(hDlg, pLangList);
- if (iret == RETURN_SETLANG_ENDLANGDIALOG)
- {
- // we're outa job
- EndDialog(hDlg, 0);
- }
- else
- {
- InitCurrentUILang(hDlg);
- }
- break;
- case IDC_LANG_REMOVE_BUTTON:
- hwndList = GetDlgItem(hDlg, IDC_LANG_ACCEPT_LIST);
- iIndex = ListBox_GetCurSel(hwndList);
- ListBox_DeleteString(hwndList, iIndex);
- iNumItems = ListBox_GetCount(hwndList);
- if (iNumItems == iIndex)
- iIndex--;
- ListBox_SetCurSel(hwndList, iIndex);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_REMOVE_BUTTON), (iNumItems > 0) && !g_restrict.fInternational);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_UP_BUTTON), (iIndex > 0) && !g_restrict.fInternational);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_DOWN_BUTTON), (iIndex < iNumItems - 1) && !g_restrict.fInternational);
- if (NULL == GetFocus()) // This prevent keyboard access disable
- SetFocus(hwndList);
- break;
- case IDC_LANG_ACCEPT_LIST:
- hwndList = GetDlgItem(hDlg, IDC_LANG_ACCEPT_LIST);
- iIndex = ListBox_GetCurSel(hwndList);
- if (0 <= iIndex)
- {
- iNumItems = ListBox_GetCount(hwndList);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_REMOVE_BUTTON), (iNumItems > 0) && !g_restrict.fInternational);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_UP_BUTTON), (iIndex > 0) && !g_restrict.fInternational);
- EnableWindow(GetDlgItem(hDlg, IDC_LANG_MOVE_DOWN_BUTTON), (iIndex < iNumItems - 1) && !g_restrict.fInternational);
- }
- break;
- case IDC_LANG_MOVE_UP_BUTTON:
- MoveUpDownListItem(hDlg, GetDlgItem(hDlg, IDC_LANG_ACCEPT_LIST), TRUE);
- break;
- case IDC_LANG_MOVE_DOWN_BUTTON:
- MoveUpDownListItem(hDlg, GetDlgItem(hDlg, IDC_LANG_ACCEPT_LIST), FALSE);
- break;
- }
- break;
- case WM_HELP: // F1
- ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
- HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- case WM_CONTEXTMENU: // right mouse click
- ResWinHelp( (HWND) wParam, IDS_HELPFILE,
- HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
- //
- // KickLanguageDialog
- //
- // synopsis : used for launching Language Preference sub dialog.
- // we need to launch the dialogbox as a separate process if inetcpl is
- // invoked from Tools->Internet options.
- // The reason: we shutdown every browser instances on desktop
- // user chooses different UI language than the current,
- // including the browser that launched inetcpl.
- //
- static const TCHAR s_szRunDll32[] = TEXT("RunDll32.exe");
- static const TCHAR s_szKickLangDialog[] = TEXT(" inetcpl.cpl,OpenLanguageDialog");
- void KickLanguageDialog(HWND hDlg)
- {
- // 1: here we want to check to see if inetcpl was launched
- // as a rundll32 process already, which would happen if user
- // clicks on it at control panel folder
- //
- //
- BOOL fLaunchedOnBrowser = FALSE;
- // this tells me whether we got invoked from Tools->Internet Options...
- if (g_szCurrentURL[0])
- {
- fLaunchedOnBrowser = TRUE;
- }
- if (fLaunchedOnBrowser)
- {
- TCHAR szCommandLine[MAX_PATH];
- TCHAR szTitle[MAX_PATH];
- HWND hwndParent = GetParent(hDlg);
- StrCpy(szCommandLine, s_szRunDll32);
- StrCat(szCommandLine, s_szKickLangDialog);
- if (GetWindowText(hwndParent, szTitle, ARRAYSIZE(szTitle)) > 0)
- {
- StrCat(szCommandLine, TEXT(" "));
- StrCat(szCommandLine, szTitle);
- }
- #ifdef USE_CREATE_PROCESS
- PROCESS_INFORMATION pi;
- STARTUPINFO si = {0};
- si.cb = sizeof(si);
- BOOL fLaunchedOK =
- CreateProcess (szCommandLine, // name of app to launch
- NULL, // lpCmdLine
- NULL, // lpProcessAttributes
- NULL, // lpThreadAttributes
- TRUE, // bInheritHandles
- NORMAL_PRIORITY_CLASS, // dwCreationFlags
- NULL, // lpEnvironment
- NULL, // lpCurrentDirectory
- &si, // lpStartupInfo
- &pi); // lpProcessInformation
- #else
- char szAnsiPath[MAX_PATH];
- SHUnicodeToAnsi(szCommandLine, szAnsiPath, ARRAYSIZE(szAnsiPath));
- WinExec(szAnsiPath, SW_SHOWNORMAL);
- #endif
- }
- else
- {
- DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_LANG), hDlg, LanguageDlgProc, NULL);
- }
- }
- //
- // KickSetLang
- //
- // synopsis : tries to find setlang.exe of Office9 first, if found it'll be kicked
- // if not, it uses our own setlang dialog.
- //
- //
- static const TCHAR s_szOfficeInstallRoot[] = TEXT("Software\\Microsoft\\Office\\9.0\\Common\\InstallRoot");
- static const TCHAR s_szOffice10InstallRoot[] = TEXT("Software\\Microsoft\\Shared");
- static const TCHAR s_szPath[] = TEXT("Path");
- static const TCHAR s_szOffice10Path[] = TEXT("OfficeSetLangInstallLocation");
- static const TCHAR s_szSetLangExe[] = TEXT("setlang.exe");
- INT_PTR KickSetLang(HWND hDlg, CUILangList *pLangList)
- {
- BOOL fOfficeSetLangInstalled = FALSE;
- INT_PTR iret;
- TCHAR szSetLangPath[MAX_PATH];
- // deleting the key this way makes the key invalid for this process
- // this way the inetcpl doesnt get bogus cached values
- SHDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache"));
- // try to get Office's setlang path
- if(pLangList && pLangList->IsOffice9Installed())
- {
- DWORD cb = sizeof(szSetLangPath);
- DWORD dwRet = SHGetValue(HKEY_LOCAL_MACHINE, s_szOffice10InstallRoot, s_szOffice10Path, NULL, szSetLangPath, &cb);
- // fall back to Office9 langpack setting if Office10 langpack setting isn't there
- if (ERROR_SUCCESS != dwRet)
- {
- cb = sizeof(szSetLangPath);
- dwRet = SHGetValue(HKEY_LOCAL_MACHINE, s_szOfficeInstallRoot, s_szPath, NULL, szSetLangPath, &cb);
- }
- if (ERROR_SUCCESS == dwRet)
- {
- // If last character is a backslash
- if (szSetLangPath[lstrlen(szSetLangPath)-1] == TEXT('\\'))
- {
- // Then concatenate the exe name
- //
- StrCat(szSetLangPath, s_szSetLangExe);
- }
- if (PathFileExists(szSetLangPath) == TRUE)
- fOfficeSetLangInstalled = TRUE;
- }
- }
- if (fOfficeSetLangInstalled)
- {
- PROCESS_INFORMATION pi;
- STARTUPINFO si = {0};
- si.cb = sizeof(si);
- BOOL fLaunchedOK = CreateProcess(
- szSetLangPath, // name of app to launch
- NULL, // lpCmdLine
- NULL, // lpProcessAttributes
- NULL, // lpThreadAttributes
- TRUE, // bInheritHandles
- NORMAL_PRIORITY_CLASS, // dwCreationFlags
- NULL, // lpEnvironment
- NULL, // lpCurrentDirectory
- &si, // lpStartupInfo
- &pi); // lpProcessInformation
- // just wait a while
- if (fLaunchedOK)
- {
- WaitForInputIdle (pi.hProcess, RELAUNCH_TIMEOUT);
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- }
- iret = RETURN_SETLANG_ENDLANGDIALOG;
- }
- else
- {
- iret = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_LANG_CHANGE), hDlg, LangChangeDlgProc, NULL);
- }
- return iret;
- }
- //
- // entry point for rundll32
- // NOTE: the following function was written intentionally as non-Unicode
- // mainly because we don't have Wide wrapper mechanism for rundll32
- // function on win95
- //
- extern void GetRestrictFlags(RESTRICT_FLAGS *pRestrict);
- void CALLBACK OpenLanguageDialog(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
- {
- // hinst is ignored because we set it at our LibMain()
- INITCOMMONCONTROLSEX icex;
- GetRestrictFlags(&g_restrict);
- icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
- icex.dwICC = ICC_USEREX_CLASSES|ICC_NATIVEFNTCTL_CLASS;
- InitCommonControlsEx(&icex);
- if (lpszCmdLine && *lpszCmdLine)
- {
- HWND hwndParent = FindWindowA(NULL, lpszCmdLine);
- if (hwndParent)
- hwnd = hwndParent;
- }
- DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_LANG), hwnd, LanguageDlgProc, NULL);
- }
- // MLGetUILanguage in shlwapi returns current MUI language regardless version.
- // MUI architecture doesn't display string correctly when main dll and satellite
- // pack versions are mismatched.
- // A good example is IE version upgrade without upgrading satellite.
- // So here is more clever way to get the MUI language.
- //
- // 1. Get MLGetUILangauge from shlwapi
- // 2. Compare it with current installed language.
- // 3. if those are different, try to get resource dll.
- // 4. if the resource dll is not in correct path just return current installed
- // language.
- // 5. Or return the langid of MLGetUILanguage.
- LANGID INETCPL_GetUILanguage()
- {
- HINSTANCE hMLInst;
- TCHAR szPath[MAX_PATH], szMUI[16];
- LANGID lidUI = MLGetUILanguage();
- if (IsOS(OS_WIN2000ORGREATER))
- return lidUI;
- if (lidUI != GetInstallLanguage())
- {
- hMLInst = MLGetHinst();
- if (GetModuleFileName(hMLInst, szPath, ARRAYSIZE(szPath)))
- {
- IntToHex(szMUI, 4, lidUI);
- if (StrStrI(szPath, szMUI) == NULL)
- lidUI = GetInstallLanguage();
- }
- }
- return lidUI;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement