+ fix: some minor bugs around MUI Language selection

This commit is contained in:
Rainer Kottenhoff 2021-04-14 17:56:10 +02:00
parent e0e3f62a76
commit a29e2101fc
12 changed files with 345 additions and 297 deletions

View File

@ -31,8 +31,10 @@ extern "C" WCHAR g_wchIniFile[MAX_PATH];
extern "C" WCHAR g_wchIniFile2[MAX_PATH];
extern "C" WCHAR g_wchNP3IniFile[MAX_PATH];
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
extern "C" WCHAR g_tchPrefLngLocName[LOCALE_NAME_MAX_LENGTH + 1];
extern "C" LANGID g_iPrefLANGID;
#endif
extern "C" LANGID g_iUsedLANGID;
//=============================================================================
@ -912,12 +914,14 @@ void LoadFlags()
const WCHAR* const Settings_Section2 = L"Settings2";
if (!IniSectionGetString(Settings_Section2, L"PreferredLanguageLocaleName", L"",
g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName))) {
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
const WCHAR* const PrefLngLocName = L"PreferredLanguageLocaleName";
if (!IniSectionGetString(Settings_Section2, PrefLngLocName, L"", g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName))) {
// try to fetch Locale Name from Notepad3.ini
IniFileGetString(g_wchNP3IniFile, L"Settings2", L"PreferredLanguageLocaleName", L"",
g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName));
IniFileGetString(g_wchNP3IniFile, Settings_Section2, PrefLngLocName, L"", g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName));
}
#endif
if (!flagNoReuseWindow) {
@ -1134,7 +1138,7 @@ void LoadSettings()
void SaveSettings(BOOL bSaveSettingsNow)
{
WCHAR wchTmp[MAX_PATH];
WCHAR wchTmp[MAX_PATH] = { L'\0' };
if (StrIsEmpty(g_wchIniFile)) {
return;
@ -1210,10 +1214,21 @@ void SaveSettings(BOOL bSaveSettingsNow)
// cleanup
IniSectionDelete(Settings_Section, L"WriteTest", FALSE);
/*
SaveSettingsNow(): query Window Dimensions
*/
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
// === prevents "Preferred Language not available" next time ===
const WCHAR* const Section2_Section = L"Settings2";
const WCHAR* const PrefLngLocName = L"PreferredLanguageLocaleName";
if (!IniSectionGetString(Section2_Section, PrefLngLocName, L"", wchTmp, COUNTOF(wchTmp))) {
// try fetch Locale Name from Notepad3.ini
IniFileGetString(g_wchNP3IniFile, Section2_Section, PrefLngLocName, L"", wchTmp, COUNTOF(wchTmp));
if (!StrEqual(wchTmp, g_tchPrefLngLocName)) {
IniSectionSetString(Section2_Section, PrefLngLocName, g_tchPrefLngLocName);
}
}
#endif
// === SaveSettingsNow(): query current Window Dimensions ===
if (bSaveSettingsNow) {
WINDOWPLACEMENT wndpl;
ZeroMemory(&wndpl, sizeof(WINDOWPLACEMENT));

View File

@ -45,7 +45,7 @@
//
extern HWND hwndMain;
extern HICON g_hDlgIconSmall;
extern LANGID g_iPrefLANGID;
extern LANGID g_iUsedLANGID;
//=============================================================================
@ -2775,7 +2775,7 @@ int ErrorMessage(int iLevel, UINT uIdMsg, ...)
HWND focus = GetFocus();
HWND hwnd = focus ? focus : hwndMain;
return MessageBoxEx(hwnd, szText, szTitle, MB_SETFOREGROUND | iIcon, g_iPrefLANGID);
return MessageBoxEx(hwnd, szText, szTitle, MB_SETFOREGROUND | iIcon, g_iUsedLANGID);
}
@ -2797,7 +2797,7 @@ DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID)
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErrID,
g_iPrefLANGID,
g_iUsedLANGID,
(LPTSTR)&lpMsgBuf,
0, NULL);
@ -2815,7 +2815,7 @@ DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID)
HWND focus = GetFocus();
HWND hwnd = focus ? focus : hwndMain;
MessageBoxEx(hwnd, lpDisplayBuf, L"MiniPath - ERROR", MB_ICONERROR, g_iPrefLANGID);
MessageBoxEx(hwnd, lpDisplayBuf, L"MiniPath - ERROR", MB_ICONERROR, g_iUsedLANGID);
LocalFree(lpDisplayBuf);
}

View File

@ -44,7 +44,7 @@
#pragma warning( disable : 26451 )
// -----------------------------------------------------------------------------
extern LANGID g_iPrefLANGID;
extern LANGID g_iUsedLANGID;
extern WCHAR g_wchIniFile[MAX_PATH];
//=============================================================================
@ -145,7 +145,7 @@ DWORD GetLastErrorToMsgBox(LPWSTR lpszFunction, DWORD dwErrID)
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErrID,
g_iPrefLANGID,
g_iUsedLANGID,
(LPTSTR)&lpMsgBuf,
0, NULL);
@ -156,7 +156,7 @@ DWORD GetLastErrorToMsgBox(LPWSTR lpszFunction, DWORD dwErrID)
if (lpDisplayBuf) {
wsprintf((LPWSTR)lpDisplayBuf, L"Error: '%s' failed with error id %d:\n%s.\n", lpszFunction, dwErrID, (LPWSTR)lpMsgBuf);
MessageBoxEx(NULL, (LPCWSTR)lpDisplayBuf, L"MiniPath - ERROR", MB_OK | MB_ICONEXCLAMATION, g_iPrefLANGID);
MessageBoxEx(NULL, (LPCWSTR)lpDisplayBuf, L"MiniPath - ERROR", MB_OK | MB_ICONEXCLAMATION, g_iUsedLANGID);
}
LocalFree(lpMsgBuf);
@ -1720,7 +1720,7 @@ BOOL GetLocaleDefaultUIFont(LANGID lang, LPWSTR lpFaceName, WORD* wSize)
BOOL GetThemedDialogFont(LPWSTR lpFaceName, WORD* wSize)
{
BOOL bSucceed = GetLocaleDefaultUIFont(g_iPrefLANGID, lpFaceName, wSize);
BOOL bSucceed = GetLocaleDefaultUIFont(g_iUsedLANGID, lpFaceName, wSize);
HDC hDC = GetDC(NULL);
int const iLogPixelsY = GetDeviceCaps(hDC, LOGPIXELSY);

View File

@ -37,17 +37,10 @@ SETTINGS_T Settings;
SETTINGS_T Defaults;
SETTINGS2_T Settings2;
WCHAR g_wchIniFile[MAX_PATH];
WCHAR g_wchIniFile2[MAX_PATH];
WCHAR g_wchNP3IniFile[MAX_PATH];
//HICON g_hDlgIcon128 = NULL;
HICON g_hDlgIconBig = NULL;
HICON g_hDlgIconSmall = NULL;
WCHAR g_tchPrefLngLocName[LOCALE_NAME_MAX_LENGTH + 1];
LANGID g_iPrefLANGID;
HBRUSH g_hbrDarkModeBkgBrush = NULL;
HBRUSH g_hbrDarkModeBtnFcBrush = NULL;
@ -120,15 +113,18 @@ WCHAR szDDETopic[256] = L"";
BOOL bHasQuickview = FALSE;
UINT16 g_uWinVer;
UINT16 g_uWinVer;
HINSTANCE g_hInstance = NULL;
HMODULE g_hLngResContainer = NULL;
WCHAR g_tchPrefLngLocName[LOCALE_NAME_MAX_LENGTH + 1];
LANGID g_iPrefLANGID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
// 'en-US' internal default
static WCHAR* const g_tchAvailableLanguages = L"af-ZA be-BY de-DE el-GR en-GB es-419 es-ES fr-FR hi-IN hu-HU id-ID it-IT ja-JP ko-KR nl-NL pl-PL pt-BR pt-PT ru-RU sk-SK sv-SE tr-TR vi-VN zh-CN zh-TW";
LANGID g_iUsedLANGID = MUI_BASE_LNG_ID;
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
WCHAR g_tchPrefLngLocName[LOCALE_NAME_MAX_LENGTH + 1] = { L'\0' };
static WCHAR* const g_tchAvailableLanguages = L"af-ZA be-BY de-DE el-GR en-GB en-US es-419 es-ES fr-FR hi-IN hu-HU id-ID it-IT ja-JP ko-KR nl-NL pl-PL pt-BR pt-PT ru-RU sk-SK sv-SE tr-TR vi-VN zh-CN zh-TW";
#endif
//=============================================================================
@ -183,17 +179,31 @@ static BOOL __fastcall _LngStrToMultiLngStr(WCHAR* pLngStr, WCHAR* pLngMultiStr,
return rtnVal;
}
// fallback to buildin MUI_BASE_LNG_ID
inline HMODULE LangResourceInternalFallback() {
g_iUsedLANGID = MUI_BASE_LNG_ID;
SetThreadUILanguage(MUI_BASE_LNG_ID);
InitMUILanguage(MUI_BASE_LNG_ID);
return g_hInstance;
}
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
//=============================================================================
//
// _LoadLanguageResources
//
//
static HMODULE __fastcall _LoadLanguageResources(const WCHAR* localeName, LANGID const langID)
inline int LangIDToLocaleName(const LANGID lngID, LPWSTR lpName_out, size_t cchName) {
LCID const lcid = MAKELCID(lngID, SORT_DEFAULT);
return LCIDToLocaleName(lcid, lpName_out, (int)cchName, 0);
}
static HMODULE _LoadLanguageResources(const WCHAR* localeName, LANGID const langID)
{
BOOL bLngAvailable = (StrStrIW(g_tchAvailableLanguages, localeName) != NULL);
if (!bLngAvailable) {
return NULL;
BOOL const bLngAvailable = (StrStrIW(g_tchAvailableLanguages, localeName) != NULL);
if (!bLngAvailable || (MUI_BASE_LNG_ID == langID)) {
return LangResourceInternalFallback();
}
WCHAR tchAvailLngs[512] = { L'\0' };
@ -201,7 +211,7 @@ static HMODULE __fastcall _LoadLanguageResources(const WCHAR* localeName, LANGID
WCHAR tchUserLangMultiStrg[512] = { L'\0' };
if (!_LngStrToMultiLngStr(tchAvailLngs, tchUserLangMultiStrg, 512)) {
GetLastErrorToMsgBox(L"Trying to load Language resource!", ERROR_MUI_INVALID_LOCALE_NAME);
return NULL;
return LangResourceInternalFallback();
}
// set the appropriate fallback list
@ -209,7 +219,7 @@ static HMODULE __fastcall _LoadLanguageResources(const WCHAR* localeName, LANGID
// using SetProcessPreferredUILanguages is recommended for new applications (esp. multi-threaded applications)
if (!SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, tchUserLangMultiStrg, &langCount) || (langCount == 0)) {
GetLastErrorToMsgBox(L"Trying to set preferred Language!", ERROR_RESOURCE_LANG_NOT_FOUND);
return NULL;
return LangResourceInternalFallback();
}
SetThreadUILanguage(langID);
@ -225,18 +235,22 @@ static HMODULE __fastcall _LoadLanguageResources(const WCHAR* localeName, LANGID
// for standard Win32 resource loading this is normally a PE module - use LoadLibraryEx
HMODULE const hLangResourceContainer = LoadMUILibraryW(L"lng/mplng.dll", MUI_LANGUAGE_NAME, langID);
if (!hLangResourceContainer)
{
ErrorMessage(2, IDS_WARN_PREF_LNG_NOT_AVAIL, localeName);
// prevent (if saved) Error Dialog on next start
LangIDToLocaleName(MUI_BASE_LNG_ID, g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName));
return LangResourceInternalFallback();
}
// MUI Language for common controls
InitMUILanguage(langID);
//if (!hLangResourceContainer)
//{
// GetLastErrorToMsgBox(L"LoadMUILibrary", 0);
// return NULL;
//}
g_iUsedLANGID = langID;
return hLangResourceContainer;
}
#endif
//=============================================================================
@ -303,62 +317,59 @@ int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPWSTR lpCmdLine,int
// ----------------------------------------------------
// MultiLingual
//
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
int res = 0;
if (lstrlenW(g_tchPrefLngLocName) > 0) {
LANGID iPrefLANGID = MUI_BASE_LNG_ID;
if (StrIsNotEmpty(g_tchPrefLngLocName)) {
WCHAR wchLngLocalName[LOCALE_NAME_MAX_LENGTH];
res = ResolveLocaleName(g_tchPrefLngLocName, wchLngLocalName, LOCALE_NAME_MAX_LENGTH);
if (res > 0) {
StringCchCopy(g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName), wchLngLocalName); // put back resolved name
// get LANGID
DWORD value = MUI_BASE_LNG_ID;
res = GetLocaleInfoEx(g_tchPrefLngLocName, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, (LPWSTR)&value, sizeof(value) / sizeof(WCHAR));
if (res > 0) {
iPrefLANGID = (LANGID)value;
}
}
// get LANGID
g_iPrefLANGID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
res = GetLocaleInfoEx(g_tchPrefLngLocName, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, (LPWSTR)&g_iPrefLANGID, sizeof(LANGID));
}
if (res == 0) { // No preferred language defined or retrievable, try to get User UI Language
//~GetUserDefaultLocaleName(&g_tchPrefLngLocName[0], COUNTOF(g_tchPrefLngLocName));
ULONG numLngs = 0;
DWORD cchLngsBuffer = 0;
ULONG cchLngsBuffer = 0;
BOOL hr = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLngs, NULL, &cchLngsBuffer);
if (hr) {
WCHAR* pwszLngsBuffer = LocalAlloc(LPTR, (cchLngsBuffer + 2) * sizeof(WCHAR));
WCHAR* const pwszLngsBuffer = LocalAlloc(LPTR, (cchLngsBuffer + 2) * sizeof(WCHAR));
if (pwszLngsBuffer) {
hr = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLngs, pwszLngsBuffer, &cchLngsBuffer);
if (hr && (numLngs > 0)) {
// get the first
// get the first one
StringCchCopy(g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName), pwszLngsBuffer);
g_iPrefLANGID = LANGIDFROMLCID(LocaleNameToLCID(g_tchPrefLngLocName, 0));
iPrefLANGID = LANGIDFROMLCID(LocaleNameToLCID(g_tchPrefLngLocName, 0));
res = 1;
}
LocalFree(pwszLngsBuffer);
}
}
if (res == 0) { // last try
g_iPrefLANGID = GetUserDefaultUILanguage();
LCID const lcid = MAKELCID(g_iPrefLANGID, SORT_DEFAULT);
res = LCIDToLocaleName(lcid, g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName), 0);
iPrefLANGID = GetUserDefaultUILanguage();
res = LangIDToLocaleName(iPrefLANGID, g_tchPrefLngLocName, COUNTOF(g_tchPrefLngLocName));
}
}
#ifdef HAVE_DYN_LOAD_LIBS_MUI_LNGS
bool bPrefLngNotAvail = false;
g_hLngResContainer = _LoadLanguageResources(g_tchPrefLngLocName, g_iPrefLANGID);
if (!g_hLngResContainer) { // fallback en-US (1033)
g_hLngResContainer = g_hInstance;
g_iPrefLANGID = MUI_BASE_LNG_ID;
bPrefLngNotAvail = true;
}
g_hLngResContainer = _LoadLanguageResources(g_tchPrefLngLocName, iPrefLANGID);
#else
g_hLngResContainer = g_hInstance;
g_iPrefLANGID = MUI_BASE_LNG_ID;
g_hLngResContainer = LangResourceInternalFallback();
#endif
SetThreadUILanguage(g_iPrefLANGID);
InitMUILanguage(g_iPrefLANGID);
// ----------------------------------------------------
if (!InitApplication(hInstance)) {
return FALSE;
}
@ -370,12 +381,6 @@ int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPWSTR lpCmdLine,int
hAcc = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_MAINWND));
#ifdef HAVE_DYN_LOAD_LIBS_MUI_LNGS
if (bPrefLngNotAvail) {
ErrorMessage(2, IDS_WARN_PREF_LNG_NOT_AVAIL, g_tchPrefLngLocName);
}
#endif
while (GetMessage(&msg,NULL,0,0)) {
if (!TranslateAccelerator(hwnd,hAcc,&msg)) {
TranslateMessage(&msg);
@ -383,6 +388,9 @@ int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPWSTR lpCmdLine,int
}
}
if (g_hLngResContainer != g_hInstance) {
FreeMUILibrary(g_hLngResContainer);
}
OleUninitialize();
return(int)(msg.wParam);

View File

@ -17,13 +17,9 @@
// 1. Comment-Out the following line
#define HAVE_DYN_LOAD_LIBS_MUI_LNGS 1
// -----------------------------------------------------
#ifdef HAVE_DYN_LOAD_LIBS_MUI_LNGS
// currently only en-US allowed for Base-Lng in MUI env
// 2. Uncomment one of the following lines according to
// the desired Language (use en-US if undefined)
#define MUI_BASE_LNG_EN_US 1
#else
// 2. Uncomment one of the following lines
// according to the desired Language
//#define MUI_BASE_LNG_EN_US 1
//#define MUI_BASE_LNG_AF_ZA 1
//#define MUI_BASE_LNG_BE_BY 1
//#define MUI_BASE_LNG_DE_DE 1
@ -50,8 +46,6 @@
//#define MUI_BASE_LNG_ZH_CN 1
//#define MUI_BASE_LNG_ZH_TW 1
#endif
// -----------------------------------------------------
// 3. In case of a new language:
// Extent Minipath.rc file accordingly

View File

@ -1087,7 +1087,7 @@ void LoadSettings()
// --------------------------------------------------------------------------
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
LANGID lngID = 0;
LANGID lngID = MUI_BASE_LNG_ID;
Defaults2.PreferredLanguageLocaleName[0] = L'\0';
GetUserPreferredLanguage(Defaults2.PreferredLanguageLocaleName, COUNTOF(Defaults2.PreferredLanguageLocaleName), &lngID);
@ -2008,6 +2008,7 @@ static bool _SaveSettings(bool bForceSaveSettings)
// --- remove deprecated ---
IniSectionDelete(IniSecSettings2, L"MarkOccurrencesMaxCount", false);
// --------------------------------------------------------------------------
const WCHAR* const IniSecWindow = Constants.Window_Section;
// --------------------------------------------------------------------------

View File

@ -145,7 +145,7 @@ int MessageBoxLng(UINT uType, UINT uidMsg, ...)
HWND const hwnd = focus ? focus : Globals.hwndMain;
s_hCBThook = SetWindowsHookEx(WH_CBT, &SetPosRelatedToParent_Hook, 0, GetCurrentThreadId());
return MessageBoxEx(hwnd, szText, _W(SAPPNAME), uType, Globals.iPrefLANGID);
return MessageBoxEx(hwnd, szText, _W(SAPPNAME), uType, Globals.iCurrentLANGID);
}
@ -167,7 +167,7 @@ DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID)
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErrID,
Globals.iPrefLANGID,
Globals.iCurrentLANGID,
(LPWSTR)&lpMsgBuf,
0, NULL);
@ -186,7 +186,7 @@ DWORD MsgBoxLastError(LPCWSTR lpszMessage, DWORD dwErrID)
s_hCBThook = SetWindowsHookEx(WH_CBT, &SetPosRelatedToParent_Hook, 0, GetCurrentThreadId());
UINT uType = MB_ICONERROR | MB_TOPMOST | (Settings.DialogsLayoutRTL ? MB_RTLREADING : 0);
MessageBoxEx(hwnd, lpDisplayBuf, _W(SAPPNAME) L" - ERROR", uType, Globals.iPrefLANGID);
MessageBoxEx(hwnd, lpDisplayBuf, _W(SAPPNAME) L" - ERROR", uType, Globals.iCurrentLANGID);
FreeMem(lpDisplayBuf);
}
@ -455,7 +455,7 @@ LONG InfoBoxLng(UINT uType, LPCWSTR lpstrSetting, UINT uidMsg, ...)
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
Globals.dwLastError,
Globals.iPrefLANGID,
Globals.iCurrentLANGID,
(LPWSTR)&lpMsgBuf, 0,
NULL);
@ -722,7 +722,7 @@ void DisplayCmdLineHelp(HWND hwnd)
mbp.lpszIcon = MAKEINTRESOURCE(IDR_MAINWND);
mbp.dwContextHelpId = 0;
mbp.lpfnMsgBoxCallback = NULL;
mbp.dwLanguageId = Globals.iPrefLANGID;
mbp.dwLanguageId = Globals.iCurrentLANGID;
hhkMsgBox = SetWindowsHookEx(WH_CBT, &_MsgBoxProc, 0, GetCurrentThreadId());
@ -4715,27 +4715,23 @@ void DialogGrepWin(HWND hwnd, LPCWSTR searchPattern)
IniSectionSetString(globalSection, grepWinIniSettings[i].key, value);
}
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
// get grepWin language
int lngIdx = -1;
for (int i = 0; i < grepWinLang_CountOf(); ++i) {
if (grepWinLangResName[i].lngid == Globals.iPrefLANGID) {
lngIdx = i;
break;
}
// get grepWin language
int lngIdx = -1;
for (int i = 0; i < grepWinLang_CountOf(); ++i) {
if (grepWinLangResName[i].lngid == Globals.iCurrentLANGID) {
lngIdx = i;
break;
}
if (lngIdx >= 0) {
IniSectionGetString(globalSection, L"languagefile", grepWinLangResName[lngIdx].filename, tchTemp, COUNTOF(tchTemp));
IniSectionSetString(globalSection, L"languagefile", tchTemp);
} else {
IniSectionGetString(globalSection, L"languagefile", L"", tchTemp, COUNTOF(tchTemp));
if (StrIsEmpty(tchTemp)) {
IniSectionDelete(globalSection, L"languagefile", false);
}
}
if (lngIdx >= 0) {
IniSectionGetString(globalSection, L"languagefile", grepWinLangResName[lngIdx].filename, tchTemp, COUNTOF(tchTemp));
IniSectionSetString(globalSection, L"languagefile", tchTemp);
} else {
IniSectionGetString(globalSection, L"languagefile", L"", tchTemp, COUNTOF(tchTemp));
if (StrIsEmpty(tchTemp)) {
IniSectionDelete(globalSection, L"languagefile", false);
}
#else
IniSectionDelete(globalSection, L"languagefile", false);
#endif
}
bool const bDarkMode = UseDarkMode(); // <- override usr ~ IniSectionGetBool(globalSection, L"darkmode", UseDarkMode());
IniSectionSetBool(globalSection, L"darkmode", bDarkMode);
@ -5718,7 +5714,7 @@ bool GetLocaleDefaultUIFont(LANGID lang, LPWSTR lpFaceName, WORD* wSize)
bool GetThemedDialogFont(LPWSTR lpFaceName, WORD* wSize)
{
bool bSucceed = GetLocaleDefaultUIFont(Globals.iPrefLANGID, lpFaceName, wSize);
bool bSucceed = GetLocaleDefaultUIFont(Globals.iCurrentLANGID, lpFaceName, wSize);
if (!bSucceed) {
if (IsAppThemed()) {

View File

@ -15,6 +15,7 @@
#include "Helpers.h"
#include <assert.h>
#include <locale.h>
#include <commctrl.h>
#include <muiload.h>
@ -27,12 +28,108 @@
//=============================================================================
grepWinLng_t grepWinLangResName[] = {
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), L".\\lng\\gwLng\\English (United States) [en-US].lang" },
{ MAKELANGID(LANG_AFRIKAANS, SUBLANG_AFRIKAANS_SOUTH_AFRICA), L".\\lng\\gwLng\\Afrikaans (Suid-Afrika) [af-ZA].lang" },
{ MAKELANGID(LANG_BELARUSIAN, SUBLANG_BELARUSIAN_BELARUS), L".\\lng\\gwLng\\Беларуская (Беларусь) [be-BY].lang" },
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), L".\\lng\\gwLng\\Deutsch (Deutschland) [de-DE].lang" },
{ MAKELANGID(LANG_GREEK, SUBLANG_GREEK_GREECE), L".\\lng\\gwLng\\Ελληνικά (Ελλάδα) [el-GR].lang" },
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), L".\\lng\\gwLng\\English (United Kingdom) [en-GB].lang" },
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_LATIN_AMERICA), L".\\lng\\gwLng\\Español (América Latina) [es-419].lang" },
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), L".\\lng\\gwLng\\Español (España) [es-ES].lang" },
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), L".\\lng\\gwLng\\Français (France) [fr-FR].lang" },
{ MAKELANGID(LANG_HINDI, SUBLANG_HINDI_INDIA), L".\\lng\\gwLng\\हिन्दी (भारत) [hi-IN].lang" },
{ MAKELANGID(LANG_HUNGARIAN, SUBLANG_HUNGARIAN_HUNGARY), L".\\lng\\gwLng\\Magyar (Magyarország) [hu-HU].lang" },
{ MAKELANGID(LANG_INDONESIAN, SUBLANG_INDONESIAN_INDONESIA), L".\\lng\\gwLng\\Bahasa Indonesia (Indonesia) [id-ID].lang" },
{ MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN), L".\\lng\\gwLng\\Italiano (Italia) [it-IT].lang" },
{ MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), L".\\lng\\gwLng\\日本語 (日本)[ja-JP].lang" },
{ MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN), L".\\lng\\gwLng\\한국어 (대한민국) [ko-KR].lang" },
{ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH), L".\\lng\\gwLng\\Nederlands (Nederland) [nl-NL].lang" },
{ MAKELANGID(LANG_POLISH, SUBLANG_POLISH_POLAND), L".\\lng\\gwLng\\Polski (Polska) [pl-PL].lang" },
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN), L".\\lng\\gwLng\\Português Brasileiro (Brasil) [pt-BR].lang" },
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE), L".\\lng\\gwLng\\Português (Portugal) [pt-PT].lang" },
{ MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), L".\\lng\\gwLng\\Русский (Pоссия) [ru-RU].lang" },
{ MAKELANGID(LANG_SLOVAK, SUBLANG_SLOVAK_SLOVAKIA), L".\\lng\\gwLng\\Slovenčina (Slovensko) [sk-SK].lang" },
{ MAKELANGID(LANG_SWEDISH, SUBLANG_SWEDISH), L".\\lng\\gwLng\\Svenska (Sverige) [sv-SE].lang" },
{ MAKELANGID(LANG_TURKISH, SUBLANG_TURKISH_TURKEY), L".\\lng\\gwLng\\Türkçe (Türkiye) [tr-TR].lang" },
{ MAKELANGID(LANG_VIETNAMESE, SUBLANG_VIETNAMESE_VIETNAM), L".\\lng\\gwLng\\Tiếng Việt (Việt Nam) [vi-VN].lang" },
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), L".\\lng\\gwLng\\简体中文 (中国) [zh-CN].lang" },
{ MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL), L".\\lng\\gwLng\\繁體中文 (台灣) [zh-TW].lang" }
};
int grepWinLang_CountOf() {
return COUNTOF(grepWinLangResName);
};
//=============================================================================
//
// SetMuiLocaleAll
//
static void SetMuiLocaleAll(LPCWSTR pszLocaleStr) {
if (pszLocaleStr) {
const WCHAR *const pszLocaleCur = _wsetlocale(LC_ALL, pszLocaleStr);
if (pszLocaleCur && (StringCchCompareXI(pszLocaleStr, pszLocaleCur) != 0)) {
//const _locale_t pCurLocale = _get_current_locale();
_wsetlocale(LC_ALL, L""); // system standard
#ifdef _DEBUG
WCHAR msg[128];
StringCchPrintf(msg, COUNTOF(msg), L"Can't set desired locale '%s', using '%s' instead!",
pszLocaleStr, pszLocaleCur ? pszLocaleCur : L"<default>");
MsgBoxLastError(msg, ERROR_MUI_INVALID_LOCALE_NAME);
#endif
}
}
}
//=============================================================================
//
// SetCurrentLanguage
//
void SetCurrentLanguage(LANGID iLanguageID) {
int const langIdx = GetMUILanguageIndexByLangID(iLanguageID);
assert((langIdx >= 0) && "Faild to get LangID!");
if (iLanguageID != Globals.iCurrentLANGID) {
Globals.iCurrentLANGID = iLanguageID; // == MUI_LanguageDLLs[langIdx].LangId
const WCHAR *const szLocaleName = MUI_LanguageDLLs[langIdx].szLocaleName;
SetThreadUILanguage(iLanguageID);
InitMUILanguage(iLanguageID); // MUI Language for common controls
SetMuiLocaleAll(szLocaleName);
const WCHAR *const SettingName = L"PreferredLanguageLocaleName";
if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, szLocaleName) != 0) {
StringCchCopyW(Settings2.PreferredLanguageLocaleName, COUNTOF(Settings2.PreferredLanguageLocaleName), szLocaleName);
if (Globals.bCanSaveIniFile) {
if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, Defaults2.PreferredLanguageLocaleName) != 0) {
IniFileSetString(Paths.IniFile, Constants.Settings2_Section, SettingName, Settings2.PreferredLanguageLocaleName);
} else {
IniFileDelete(Paths.IniFile, Constants.Settings2_Section, SettingName, false);
}
}
}
}
}
//=============================================================================
//=============================================================================
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
extern prefix_t g_mxSBPrefix[STATUS_SECTOR_COUNT];
extern prefix_t g_mxSBPostfix[STATUS_SECTOR_COUNT];
//=============================================================================
MUILANGUAGE MUI_LanguageDLLs[] = {
{ IDS_MUI_LANG_EN_US, L"en-US", L"English (United States)\t\t\t[%s]", MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), true, false }, // internal - must be 1st
@ -71,46 +168,6 @@ int MuiLanguages_CountOf()
};
grepWinLng_t grepWinLangResName[] = {
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), L".\\lng\\gwLng\\English (United States) [en-US].lang"},
{ MAKELANGID(LANG_AFRIKAANS, SUBLANG_AFRIKAANS_SOUTH_AFRICA), L".\\lng\\gwLng\\Afrikaans (Suid-Afrika) [af-ZA].lang"},
{ MAKELANGID(LANG_BELARUSIAN, SUBLANG_BELARUSIAN_BELARUS), L".\\lng\\gwLng\\Беларуская (Беларусь) [be-BY].lang"},
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), L".\\lng\\gwLng\\Deutsch (Deutschland) [de-DE].lang"},
{ MAKELANGID(LANG_GREEK, SUBLANG_GREEK_GREECE), L".\\lng\\gwLng\\Ελληνικά (Ελλάδα) [el-GR].lang"},
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), L".\\lng\\gwLng\\English (United Kingdom) [en-GB].lang"},
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_LATIN_AMERICA), L".\\lng\\gwLng\\Español (América Latina) [es-419].lang"},
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), L".\\lng\\gwLng\\Español (España) [es-ES].lang"},
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), L".\\lng\\gwLng\\Français (France) [fr-FR].lang"},
{ MAKELANGID(LANG_HINDI, SUBLANG_HINDI_INDIA), L".\\lng\\gwLng\\हिन्दी (भारत) [hi-IN].lang"},
{ MAKELANGID(LANG_HUNGARIAN, SUBLANG_HUNGARIAN_HUNGARY), L".\\lng\\gwLng\\Magyar (Magyarország) [hu-HU].lang"},
{ MAKELANGID(LANG_INDONESIAN, SUBLANG_INDONESIAN_INDONESIA), L".\\lng\\gwLng\\Bahasa Indonesia (Indonesia) [id-ID].lang"},
{ MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN), L".\\lng\\gwLng\\Italiano (Italia) [it-IT].lang"},
{ MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), L".\\lng\\gwLng\\日本語 (日本)[ja-JP].lang"},
{ MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN), L".\\lng\\gwLng\\한국어 (대한민국) [ko-KR].lang"},
{ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH), L".\\lng\\gwLng\\Nederlands (Nederland) [nl-NL].lang"},
{ MAKELANGID(LANG_POLISH, SUBLANG_POLISH_POLAND), L".\\lng\\gwLng\\Polski (Polska) [pl-PL].lang"},
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN), L".\\lng\\gwLng\\Português Brasileiro (Brasil) [pt-BR].lang"},
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE), L".\\lng\\gwLng\\Português (Portugal) [pt-PT].lang"},
{ MAKELANGID(LANG_RUSSIAN, SUBLANG_RUSSIAN_RUSSIA), L".\\lng\\gwLng\\Русский (Pоссия) [ru-RU].lang"},
{ MAKELANGID(LANG_SLOVAK, SUBLANG_SLOVAK_SLOVAKIA), L".\\lng\\gwLng\\Slovenčina (Slovensko) [sk-SK].lang"},
{ MAKELANGID(LANG_SWEDISH, SUBLANG_SWEDISH), L".\\lng\\gwLng\\Svenska (Sverige) [sv-SE].lang"},
{ MAKELANGID(LANG_TURKISH, SUBLANG_TURKISH_TURKEY), L".\\lng\\gwLng\\Türkçe (Türkiye) [tr-TR].lang"},
{ MAKELANGID(LANG_VIETNAMESE, SUBLANG_VIETNAMESE_VIETNAM), L".\\lng\\gwLng\\Tiếng Việt (Việt Nam) [vi-VN].lang"},
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), L".\\lng\\gwLng\\简体中文 (中国) [zh-CN].lang"},
{ MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL), L".\\lng\\gwLng\\繁體中文 (台灣) [zh-TW].lang"}
};
int grepWinLang_CountOf()
{
return COUNTOF(grepWinLangResName);
};
// ----------------------------------------------------------------------------
//=============================================================================
//
// GetMUILanguageIndexByLangID
@ -138,15 +195,19 @@ static int _CheckAvailableLanguageDLLs()
int count = 1;
for (int lng = 1; lng < MuiLanguages_CountOf(); ++lng) {
if (IsValidLocaleName(MUI_LanguageDLLs[lng].szLocaleName)) {
//WCHAR wchLngLocalName[LOCALE_NAME_MAX_LENGTH];
//if (ResolveLocaleName(MUI_LanguageDLLs[i].szLocaleName, wchLngLocalName, LOCALE_NAME_MAX_LENGTH)) {
// StringCchCopy(MUI_LanguageDLLs[i].szLocaleName, COUNTOF(MUI_LanguageDLLs[i].szLocaleName), wchLngLocalName); // put back resolved name
//}
// get LANGID
GetLocaleInfoEx(MUI_LanguageDLLs[lng].szLocaleName, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&(MUI_LanguageDLLs[lng].LangId), sizeof(LANGID));
DWORD value = MUI_BASE_LNG_ID;
if (GetLocaleInfoEx(MUI_LanguageDLLs[lng].szLocaleName, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, (LPWSTR)&value, sizeof(value) / sizeof(WCHAR)) > 0) {
MUI_LanguageDLLs[lng].LangId = (LANGID)value;
}
// check for DLL
StringCchPrintf(wchRelPath, COUNTOF(wchRelPath), L"lng/%s/np3lng.dll.mui", MUI_LanguageDLLs[lng].szLocaleName);
@ -199,7 +260,6 @@ static bool _LngStrToMultiLngStr(WCHAR* pLngStr, WCHAR* pLngMultiStr, size_t ln
}
//=============================================================================
//
// GetUserPreferredLanguage
@ -214,7 +274,7 @@ bool GetUserPreferredLanguage(LPWSTR pszPrefLocaleName, int cchBuffer, LANGID* p
res = ResolveLocaleName(pszPrefLocaleName, wchLngLocalName, COUNTOF(wchLngLocalName));
if (res > 0) {
// get LANGID
DWORD value;
DWORD value = MUI_BASE_LNG_ID;
res = GetLocaleInfoEx(wchLngLocalName, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, (LPWSTR)&value, sizeof(value) / sizeof(WCHAR));
if (res > 0) {
lngID = (LANGID)value;
@ -234,16 +294,16 @@ bool GetUserPreferredLanguage(LPWSTR pszPrefLocaleName, int cchBuffer, LANGID* p
if (hr && (numLngs > 0)) {
// get the first
StringCchCopy(wchLngLocalName, COUNTOF(wchLngLocalName), pwszLngsBuffer);
// TODO: deprecated
lngID = LANGIDFROMLCID(LocaleNameToLCID(wchLngLocalName, 0));
res = 1;
}
FreeMem(pwszLngsBuffer);
}
}
if (res == 0) { // last try
if (res == 0) { // last try (deprecated)
lngID = GetUserDefaultUILanguage();
LCID const lcid = MAKELCID(lngID, SORT_DEFAULT);
res = LCIDToLocaleName(lcid, wchLngLocalName, COUNTOF(wchLngLocalName), 0);
res = LangIDToLocaleName(lngID, wchLngLocalName, COUNTOF(wchLngLocalName));
}
}
if (res != 0) {
@ -255,87 +315,34 @@ bool GetUserPreferredLanguage(LPWSTR pszPrefLocaleName, int cchBuffer, LANGID* p
}
//=============================================================================
//
// SetPreferredLanguage
//
static void SetMuiLocaleAll(LPCWSTR pszLocaleStr)
{
if (pszLocaleStr) {
const WCHAR* const pszLocaleCur = _wsetlocale(LC_ALL, pszLocaleStr);
if (pszLocaleCur && (StringCchCompareXI(pszLocaleStr, pszLocaleCur) != 0)) {
//const _locale_t pCurLocale = _get_current_locale();
_wsetlocale(LC_ALL, L""); // system standard
#ifdef _DEBUG
WCHAR msg[128];
StringCchPrintf(msg, COUNTOF(msg), L"Can't set desired locale '%s', using '%s' instead!",
pszLocaleStr, pszLocaleCur ? pszLocaleCur : L"<default>");
MsgBoxLastError(msg, ERROR_MUI_INVALID_LOCALE_NAME);
#endif
}
}
}
void SetPreferredLanguage(LANGID iPreferredLanguageID)
{
int const langIdx = GetMUILanguageIndexByLangID(iPreferredLanguageID);
if (langIdx < 0) {
Globals.iPrefLANGID = MUI_BASE_LNG_ID; // internal
int const idx = GetMUILanguageIndexByLangID(MUI_BASE_LNG_ID);
if (idx >= 0) {
SetMuiLocaleAll(MUI_LanguageDLLs[idx].szLocaleName);
}
return;
}
if (iPreferredLanguageID != Globals.iPrefLANGID) {
Globals.iPrefLANGID = iPreferredLanguageID; // == MUI_LanguageDLLs[langIdx].LangId
const WCHAR* const szLocaleName = MUI_LanguageDLLs[langIdx].szLocaleName;
SetMuiLocaleAll(szLocaleName);
if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, szLocaleName) != 0) {
StringCchCopyW(Settings2.PreferredLanguageLocaleName, COUNTOF(Settings2.PreferredLanguageLocaleName), szLocaleName);
if (Globals.bCanSaveIniFile) {
if (StringCchCompareXIW(Settings2.PreferredLanguageLocaleName, Defaults2.PreferredLanguageLocaleName) != 0) {
IniFileSetString(Paths.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", Settings2.PreferredLanguageLocaleName);
} else {
IniFileDelete(Paths.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", false);
}
}
}
}
}
//=============================================================================
//
// LoadLanguageResources
//
//
LANGID LoadLanguageResources()
LANGID LoadLanguageResources(LPCWSTR localeName)
{
FreeLanguageResources(); // reset
int const iInternalLngIndex = max_i(0, GetMUILanguageIndexByLangID(MUI_BASE_LNG_ID));
// 1st check language resources
Globals.iAvailLngCount = _CheckAvailableLanguageDLLs();
// set the appropriate fallback list
int iPrefLngIndex = -1;
int iLngIndex = -1;
WCHAR tchAvailLngs[2 * (LOCALE_NAME_MAX_LENGTH + 1)] = { L'\0' };
for (int lng = 0; lng < MuiLanguages_CountOf(); ++lng) {
if (StringCchCompareXIW(MUI_LanguageDLLs[lng].szLocaleName, Settings2.PreferredLanguageLocaleName) == 0) {
if (StringCchCompareXIW(MUI_LanguageDLLs[lng].szLocaleName, localeName) == 0) {
if (MUI_LanguageDLLs[lng].bHasDLL && (lng > 0)) {
StringCchCatW(tchAvailLngs, COUNTOF(tchAvailLngs), MUI_LanguageDLLs[lng].szLocaleName);
StringCchCatW(tchAvailLngs, COUNTOF(tchAvailLngs), L";");
}
iPrefLngIndex = lng;
iLngIndex = lng;
break;
}
}
StringCchCatW(tchAvailLngs, COUNTOF(tchAvailLngs), MUI_LanguageDLLs[0].szLocaleName); // en-US fallback
StringCchCatW(tchAvailLngs, COUNTOF(tchAvailLngs), MUI_LanguageDLLs[iInternalLngIndex].szLocaleName); // en-US fallback
// NOTES:
// an application developer that makes the assumption the fallback list provided by the
@ -363,36 +370,41 @@ LANGID LoadLanguageResources()
// obtains access to the proper resource container
// for standard Win32 resource loading this is normally a PE module - use LoadLibraryEx
HINSTANCE _hLangResourceContainer = NULL;
Globals.bPrefLngNotAvail = (iPrefLngIndex < 0);
int iUsedLngIdx = (iPrefLngIndex >= 0) ? iPrefLngIndex : 0;
Globals.hLngResContainer = NULL; //(!)
if ((iPrefLngIndex >= 0) && MUI_LanguageDLLs[iPrefLngIndex].bHasDLL) {
_hLangResourceContainer = (iPrefLngIndex == 0) ? Globals.hInstance :
LoadMUILibrary(L"lng/np3lng.dll", MUI_LANGUAGE_NAME | MUI_LANGUAGE_EXACT, MUI_LanguageDLLs[iPrefLngIndex].LangId);
if (_hLangResourceContainer) {
MUI_LanguageDLLs[0].bIsActive = false;
MUI_LanguageDLLs[iPrefLngIndex].bIsActive = true;
iUsedLngIdx = iPrefLngIndex;
if (iLngIndex == iInternalLngIndex) {
Globals.hLngResContainer = Globals.hInstance;
MUI_LanguageDLLs[iInternalLngIndex].bIsActive = true;
} else if ((iLngIndex >= 0) && MUI_LanguageDLLs[iLngIndex].bHasDLL) {
Globals.hLngResContainer = LoadMUILibrary(L"lng/np3lng.dll",
MUI_LANGUAGE_NAME | MUI_LANGUAGE_EXACT,
MUI_LanguageDLLs[iLngIndex].LangId);
if (Globals.hLngResContainer) {
MUI_LanguageDLLs[iLngIndex].bIsActive = true;
MUI_LanguageDLLs[iInternalLngIndex].bIsActive = false;
} else {
//DbgMsgBoxLastError(L"LoadMUILibrary", 0);
iLngIndex = -1;
}
}
if (!_hLangResourceContainer) {
// fallback to ENGLISH_US
//MsgBoxLastError(L"LoadMUILibrary", 0);
Globals.bPrefLngNotAvail = (iPrefLngIndex != 0);
_hLangResourceContainer = Globals.hInstance;
MUI_LanguageDLLs[0].bIsActive = true;
iUsedLngIdx = 0;
if (!Globals.hLngResContainer || (iLngIndex < 0)) {
// fallback to MUI_BASE_LNG_ID
Globals.hLngResContainer = Globals.hInstance;
MUI_LanguageDLLs[iInternalLngIndex].bIsActive = true;
iLngIndex = iInternalLngIndex;
const WCHAR *const suprMsg = L"MsgPrefLanguageNotAvailable";
InfoBoxLng(MB_ICONWARNING, suprMsg, IDS_WARN_PREF_LNG_NOT_AVAIL, localeName);
int const noMsg = IniFileGetInt(Paths.IniFile, Constants.SectionSuppressedMessages, suprMsg, 0);
if (noMsg && Globals.bCanSaveIniFile) {
IniFileSetString(Paths.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", MUI_LanguageDLLs[iInternalLngIndex].szLocaleName);
}
}
// MUI Language for common controls
LANGID const langID = MUI_LanguageDLLs[iUsedLngIdx].LangId;
SetThreadUILanguage(langID);
InitMUILanguage(langID);
Globals.hLngResContainer = _hLangResourceContainer;
// === update language dependent items ===
for (cpi_enc_t enc = 0; enc < Encoding_CountOf(); ++enc) {
@ -414,7 +426,7 @@ LANGID LoadLanguageResources()
IniFileGetString(Paths.IniFile, StatusBar_Section, L"SectionPostfixes", tchDefaultStrg, tchStatusBar, COUNTOF(tchStatusBar));
ReadStrgsFromCSV(tchStatusBar, g_mxSBPostfix, STATUS_SECTOR_COUNT, MICRO_BUFFER, L"_POFX_");
return MUI_LanguageDLLs[iUsedLngIdx].LangId;
return MUI_LanguageDLLs[iLngIndex].LangId;
}
@ -425,14 +437,13 @@ LANGID LoadLanguageResources()
//
void FreeLanguageResources() {
CloseNonModalDialogs();
int const iInternalLngIndex = GetMUILanguageIndexByLangID(MUI_BASE_LNG_ID);
if (Globals.hLngResContainer != Globals.hInstance) {
HINSTANCE const _hLngResContainer = Globals.hLngResContainer;
FreeMUILibrary(Globals.hLngResContainer);
Globals.hLngResContainer = Globals.hInstance;
MUI_LanguageDLLs[0].bIsActive = true;
FreeMUILibrary(_hLngResContainer);
}
for (int i = 1; i < MuiLanguages_CountOf(); ++i) {
MUI_LanguageDLLs[i].bIsActive = false;
for (int i = 0; i < MuiLanguages_CountOf(); ++i) {
MUI_LanguageDLLs[i].bIsActive = (iInternalLngIndex == i);
}
}
@ -494,14 +505,14 @@ void DynamicLanguageMenuCmd(int cmd) {
return;
}
if (!MUI_LanguageDLLs[iLngIdx].bIsActive) {
DestroyMenu(Globals.hMainMenu);
// desired language
LANGID const desiredLngID = MUI_LanguageDLLs[iLngIdx].LangId;
SetPreferredLanguage(desiredLngID);
FreeLanguageResources();
LoadLanguageResources();
LPCWSTR desiredLocaleName = MUI_LanguageDLLs[iLngIdx].szLocaleName;
LoadLanguageResources(desiredLocaleName);
SetCurrentLanguage(desiredLngID);
Globals.hMainMenu = LoadMenu(Globals.hLngResContainer, MAKEINTRESOURCE(IDR_MUI_MAINMENU));
if (!Globals.hMainMenu) {

View File

@ -13,19 +13,63 @@
* *
* *
*******************************************************************************/
// TODO: Get rid of these deprecated LCID Stuff (see "winnt.h"):
//
// ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED **
//
// DEPRECATED: The LCID/LANGID/SORTID concept is deprecated, please use
// Locale Names instead, eg: en-US instead of an LCID like 0x0409.
// See the documentation for GetLocaleInfoEx.
//
// A locale ID is a 32 bit value which is the combination of a
// language ID, a sort ID, and a reserved area. The bits are
// allocated as follows:
//
// +-------------+---------+-------------------------+
// | Reserved | Sort ID | Language ID |
// +-------------+---------+-------------------------+
// 31 20 19 16 15 0 bit
//
// WARNING: This pattern isn't always followed (es-ES_tradnl vs es-ES for example)
//
// WARNING: Some locales do not have assigned LCIDs. Please use
// Locale Names, such as "tlh-Piqd".
//
// It is recommended that applications test for locale names rather than
// attempting to rely on LCID or LANGID behavior.
//
// DEPRECATED: Locale ID creation/extraction macros:
//
// MAKELCID - construct the locale id from a language id and a sort id.
// MAKESORTLCID - construct the locale id from a language id, sort id, and sort version.
// LANGIDFROMLCID - extract the language id from a locale id.
// SORTIDFROMLCID - extract the sort id from a locale id.
// SORTVERSIONFROMLCID - extract the sort version from a locale id.
//
// Note that the LANG, SUBLANG construction is not always consistent.
// The named locale APIs (eg GetLocaleInfoEx) are recommended.
//
// DEPRECATED: LCIDs do not exist for all locales.
//
// ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED ** DEPRECATED **
//
#pragma once
#ifndef _NP3_MUI_LANGUAGE_H_
#define _NP3_MUI_LANGUAGE_H_
#include "resource.h"
void SetCurrentLanguage(LANGID iLanguageID);
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
typedef struct _muilanguage {
UINT rid;
const WCHAR* szLocaleName;
const WCHAR* szMenuItem;
// !!! WARNING: LCID is DEPRECATED
// !!! WARNING: LCID/LANGID is DEPRECATED
LANGID LangId;
bool bHasDLL;
bool bIsActive;
@ -34,31 +78,22 @@ typedef struct _muilanguage {
extern MUILANGUAGE MUI_LanguageDLLs[];
int MuiLanguages_CountOf();
typedef struct _gwlang_ini {
const LANGID lngid;
const WCHAR* const filename;
}
grepWinLng_t;
extern grepWinLng_t grepWinLangResName[];
int grepWinLang_CountOf();
int GetMUILanguageIndexByLangID(LANGID iLanguageID);
bool GetUserPreferredLanguage(LPWSTR pszPrefLocaleName, int cchBuffer, LANGID* pLangID);
void SetPreferredLanguage(LANGID iPreferredLanguageID);
LANGID LoadLanguageResources();
LANGID LoadLanguageResources(LPCWSTR localeName);
void FreeLanguageResources();
bool InsertLanguageMenu(HMENU hMenuBar);
void DynamicLanguageMenuCmd(int cmd);
#endif // HAVE_DYN_LOAD_LIBS_MUI_LNGS
typedef struct _gwlang_ini {
const LANGID lngid;
const WCHAR *const filename;
} grepWinLng_t;
extern grepWinLng_t grepWinLangResName[];
int grepWinLang_CountOf();
int LoadLngStringW(UINT uID, LPWSTR lpBuffer, int nBufferMax);
int LoadLngStringA(UINT uID, LPSTR lpBuffer, int nBufferMax);
@ -70,6 +105,11 @@ int LoadLngStringW2MB(UINT uID, LPSTR lpBuffer, int nBufferMax);
#define GetLngStringA(id,pb,cb) LoadLngStringA((id),(pb),(cb))
#define GetLngStringW2MB(id,pb,cb) LoadLngStringW2MB((id),(pb),(cb))
// TODO: deprecated
inline int LangIDToLocaleName(const LANGID lngID, LPWSTR lpName_out, size_t cchName) {
LCID const lcid = MAKELCID(lngID, SORT_DEFAULT);
return LCIDToLocaleName(lcid, lpName_out, (int)cchName, 0);
}
#endif //_NP3_MUI_LANGUAGE_H_

View File

@ -630,6 +630,8 @@ static void _InitGlobals()
ZeroMemory(&(Globals.fvCurFile), sizeof(FILEVARS));
Globals.WindowsBuildNumber = GetWindowsBuildNumber(NULL, NULL);
Globals.hLngResContainer = NULL;
Globals.hDlgIcon256 = NULL;
Globals.hDlgIcon128 = NULL;
@ -644,7 +646,7 @@ static void _InitGlobals()
Globals.pMRUfind = NULL;
Globals.pMRUreplace = NULL;
Globals.iAvailLngCount = 1;
Globals.iPrefLANGID = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
Globals.iCurrentLANGID = WORD_MAX;
Globals.iWrapCol = 80;
Globals.CmdLnFlag_PosParam = false;
@ -875,11 +877,9 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
// MultiLingual
//
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
SetPreferredLanguage(LoadLanguageResources());
SetCurrentLanguage(LoadLanguageResources(Settings2.PreferredLanguageLocaleName));
#else
Globals.iPrefLANGID = MUI_BASE_LNG_ID;
SetThreadUILanguage(MUI_BASE_LNG_ID);
InitMUILanguage(MUI_BASE_LNG_ID);
SetCurrentLanguage(MUI_BASE_LNG_ID);
#endif
// ----------------------------------------------------
@ -997,17 +997,6 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
SetTimer(hwnd, IDT_TIMER_MRKALL, _MQ_TIMER_CYCLE, MQ_ExecuteNext);
#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS)
if (Globals.bPrefLngNotAvail) {
const WCHAR* const suprMsg = L"MsgPrefLanguageNotAvailable";
InfoBoxLng(MB_ICONWARNING, suprMsg, IDS_WARN_PREF_LNG_NOT_AVAIL, Settings2.PreferredLanguageLocaleName);
int const noMsg = IniFileGetInt(Paths.IniFile, Constants.SectionSuppressedMessages, suprMsg, 0);
if (noMsg && Globals.bCanSaveIniFile) {
IniFileSetString(Paths.IniFile, Constants.Settings2_Section, L"PreferredLanguageLocaleName", MUI_LanguageDLLs[0].szLocaleName);
}
}
#endif
MSG msg;
while (GetMessage(&msg,NULL,0,0)) {
if (IsWindow(Globals.hwndDlgFindReplace) && ((msg.hwnd == Globals.hwndDlgFindReplace) || IsChild(Globals.hwndDlgFindReplace, msg.hwnd))) {

View File

@ -346,8 +346,6 @@ typedef struct _globals_t
HINSTANCE hLngResContainer;
DWORD WindowsBuildNumber;
bool bCanSaveIniFile;
int iAvailLngCount;
bool bPrefLngNotAvail;
HWND hwndMain;
HANDLE hndlProcessHeap;
HWND hwndEdit;
@ -374,13 +372,15 @@ typedef struct _globals_t
HWND hwndDlgCustomizeSchemes;
int iDefaultCharSet;
cpi_enc_t DOSEncoding;
LANGID iPrefLANGID;
LPMRULIST pFileMRU;
LPMRULIST pMRUfind;
LPMRULIST pMRUreplace;
FILEVARS fvCurFile;
int iWrapCol;
int iAvailLngCount;
LANGID iCurrentLANGID;
bool CmdLnFlag_PosParam;
int CmdLnFlag_AlwaysOnTop;
int CmdLnFlag_WindowPos;

View File

@ -15,13 +15,9 @@
// 1. Comment-Out the following line
#define HAVE_DYN_LOAD_LIBS_MUI_LNGS 1
// -----------------------------------------------------
#ifdef HAVE_DYN_LOAD_LIBS_MUI_LNGS
// currently only en-US allowed for Base-Lng in MUI env
// 2. Uncomment one of the following lines according to
// the desired Language (use en-US if undefined)
#define MUI_BASE_LNG_EN_US 1
#else
// 2. Uncomment one of the following lines
// according to the desired Language
//#define MUI_BASE_LNG_EN_US 1
//#define MUI_BASE_LNG_AF_ZA 1
//#define MUI_BASE_LNG_BE_BY 1
//#define MUI_BASE_LNG_DE_DE 1
@ -48,8 +44,6 @@
//#define MUI_BASE_LNG_ZH_CN 1
//#define MUI_BASE_LNG_ZH_TW 1
#endif
// -----------------------------------------------------
// 3. In case of a new language:
// Extent Notepad3.rc file accordingly