// LangUtils.cpp
#include "StdAfx.h"
#include "LangUtils.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
#include "Windows/Synchronization.h"
#include "Windows/Window.h"
#include "Windows/FileFind.h"
#include "RegistryUtils.h"
#include "ProgramLocation.h"
using namespace NWindows;
static CLang g_Lang;
UString g_LangID;
#ifndef _UNICODE
extern bool g_IsNT;
#endif
void ReloadLang()
{
ReadRegLang(g_LangID);
g_Lang.Clear();
if (!g_LangID.IsEmpty() && g_LangID != L"-")
{
UString langPath = g_LangID;
if (langPath.Find(WCHAR_PATH_SEPARATOR) < 0)
{
if (langPath.Find(L'.') < 0)
langPath += L".txt";
UString folderPath;
if (GetProgramFolderPath(folderPath))
langPath = folderPath + UString(L"Lang" WSTRING_PATH_SEPARATOR) + langPath;
}
g_Lang.Open(langPath);
}
}
static bool g_Loaded = false;
static NSynchronization::CCriticalSection g_CriticalSection;
void LoadLangOneTime()
{
NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
if (g_Loaded)
return;
g_Loaded = true;
ReloadLang();
}
void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems)
{
for (int i = 0; i < numItems; i++)
{
const CIDLangPair &idLangPair = idLangPairs[i];
UString message;
if (g_Lang.GetMessage(idLangPair.LangID, message))
{
NWindows::CWindow window(GetDlgItem(dialogWindow, idLangPair.ControlID));
window.SetText(message);
}
}
}
void LangSetWindowText(HWND window, UInt32 langID)
{
UString message;
if (g_Lang.GetMessage(langID, message))
MySetWindowText(window, message);
}
UString LangString(UInt32 langID)
{
UString message;
if (g_Lang.GetMessage(langID, message))
return message;
return UString();
}
UString LangString(UINT resourceID, UInt32 langID)
{
UString message;
if (g_Lang.GetMessage(langID, message))
return message;
return NWindows::MyLoadStringW(resourceID);
}
void LoadLangs(CObjectVector<CLangEx> &langs)
{
langs.Clear();
UString folderPath;
if (!::GetProgramFolderPath(folderPath))
return;
folderPath += L"Lang" WSTRING_PATH_SEPARATOR;
NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt");
NWindows::NFile::NFind::CFileInfoW fileInfo;
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDir())
continue;
CLangEx lang;
UString filePath = folderPath + fileInfo.Name;
const int kExtSize = 4;
const UString ext = fileInfo.Name.Right(kExtSize);
if (ext.CompareNoCase(L".txt") != 0)
continue;
lang.ShortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize);
if (lang.Lang.Open(filePath))
langs.Add(lang);
}
}
bool SplidID(const UString &id, WORD &primID, WORD &subID)
{
primID = 0;
subID = 0;
const wchar_t *start = id;
const wchar_t *end;
UInt64 value = ConvertStringToUInt64(start, &end);
if (start == end)
return false;
primID = (WORD)value;
if (*end == 0)
return true;
if (*end != L'-')
return false;
start = end + 1;
value = ConvertStringToUInt64(start, &end);
if (start == end)
return false;
subID = (WORD)value;
return (*end == 0);
}
typedef LANGID (WINAPI *GetUserDefaultUILanguageP)();
void FindMatchLang(UString &shortName)
{
shortName.Empty();
LANGID SystemDefaultLangID = GetSystemDefaultLangID(); // Lang for non-Unicode in XP64
LANGID UserDefaultLangID = GetUserDefaultLangID(); // Standarts and formats in XP64
if (SystemDefaultLangID != UserDefaultLangID)
return;
LANGID langID = UserDefaultLangID;
/*
LANGID SystemDefaultUILanguage; // english in XP64
LANGID UserDefaultUILanguage; // english in XP64
GetUserDefaultUILanguageP fn = (GetUserDefaultUILanguageP)GetProcAddress(
GetModuleHandle("kernel32"), "GetUserDefaultUILanguage");
if (fn != NULL)
UserDefaultUILanguage = fn();
fn = (GetUserDefaultUILanguageP)GetProcAddress(
GetModuleHandle("kernel32"), "GetSystemDefaultUILanguage");
if (fn != NULL)
SystemDefaultUILanguage = fn();
*/
WORD primLang = (WORD)(PRIMARYLANGID(langID));
WORD subLang = (WORD)(SUBLANGID(langID));
CObjectVector<CLangEx> langs;
LoadLangs(langs);
for (int i = 0; i < langs.Size(); i++)
{
const CLangEx &lang = langs[i];
UString id;
if (lang.Lang.GetMessage(0x00000002, id))
{
WORD primID;
WORD subID;
if (SplidID(id, primID, subID))
if (primID == primLang)
{
if (subID == 0)
shortName = lang.ShortName;
if (subLang == subID)
{
shortName = lang.ShortName;
return;
}
}
}
}
}
void ReloadLangSmart()
{
#ifndef _UNICODE
if (g_IsNT)
#endif
{
ReadRegLang(g_LangID);
if (g_LangID.IsEmpty())
{
UString shortName;
FindMatchLang(shortName);
if (shortName.IsEmpty())
shortName = L"-";
SaveRegLang(shortName);
}
}
ReloadLang();
}