From 652dfd43d603c33bc0be3bc0c849708d7e064a59 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 12 Aug 2018 01:20:20 +0200 Subject: Windows Installer: implement language selection mechanism at the start of the installer to make easier for international users. --- src/Setup/Resource.h | 23 +++++++-- src/Setup/Setup.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/Setup/Setup.rc | 41 ++++++++++++++- src/Setup/Wizard.c | 11 ++++ 4 files changed, 209 insertions(+), 5 deletions(-) (limited to 'src/Setup') diff --git a/src/Setup/Resource.h b/src/Setup/Resource.h index 8feaf3dc..8882d67b 100644 --- a/src/Setup/Resource.h +++ b/src/Setup/Resource.h @@ -3,6 +3,20 @@ // Used by Setup.rc // #define IDR_COMREG 10 +#define IDR_LANG_AR 20 +#define IDR_LANG_CS 21 +#define IDR_LANG_DE 22 +#define IDR_LANG_ES 23 +#define IDR_LANG_FR 24 +#define IDR_LANG_IT 25 +#define IDR_LANG_JA 26 +#define IDR_LANG_NL 27 +#define IDR_LANG_PL 28 +#define IDR_LANG_RO 29 +#define IDR_LANG_RU 30 +#define IDR_LANG_VI 31 +#define IDR_LANG_ZHCN 32 +#define IDR_LANG_ZHHK 33 #define IDD_INSTALL 101 #define IDD_INSTALL_OPTIONS_PAGE_DLG 102 #define IDD_UNINSTALL 103 @@ -17,6 +31,7 @@ #define IDD_WIZARD_MODE_PAGE_DLG 112 #define IDD_PROGRESS_PAGE_DLG 113 #define IDD_DONATIONS_PAGE_DLG 114 +#define IDD_INSTALL_LANGUAGE 115 #define IDC_DESTINATION 1000 #define IDC_BOX_TITLE 1001 #define IDC_BROWSE 1002 @@ -50,15 +65,17 @@ #define IDC_BITMAP_SETUP_WIZARD 1030 #define IDC_MAIN_CONTENT_CANVAS 1031 #define IDC_DONATE 1032 +#define IDC_LANGUAGES_LIST 1033 +#define IDC_SELECT_LANGUAGE_LABEL 1034 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 115 +#define _APS_NEXT_RESOURCE_VALUE 116 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1033 +#define _APS_NEXT_CONTROL_VALUE 1035 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c index 485d333c..986bc122 100644 --- a/src/Setup/Setup.c +++ b/src/Setup/Setup.c @@ -1,4 +1,4 @@ -/* +/* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is @@ -78,6 +78,8 @@ BOOL bRegisterFileExt = TRUE; BOOL bAddToStartMenu = TRUE; BOOL bDesktopIcon = TRUE; +BOOL bUserSetLanguage = FALSE; + BOOL bDesktopIconStatusDetermined = FALSE; HMODULE volatile SystemRestoreDll = 0; @@ -2374,6 +2376,137 @@ BOOL CALLBACK UninstallDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP } #endif +typedef struct +{ + LPCWSTR name; + int resourceid; + WORD langid; + LPCSTR internalId; + LPCWSTR langtag; +} tLanguageEntry; + +static tLanguageEntry g_languagesEntries[] = { + {L"العربية", IDR_LANG_AR, LANG_ARABIC, "ar", NULL}, + {L"Čeština", IDR_LANG_CS, LANG_CZECH, "cs", NULL}, + {L"Deutsch", IDR_LANG_DE, LANG_GERMAN, "de", NULL}, + {L"English", IDR_LANGUAGE, LANG_ENGLISH, "en", NULL}, + {L"Español", IDR_LANG_ES, LANG_SPANISH, "es", NULL}, + {L"Français", IDR_LANG_FR, LANG_FRENCH, "fr", NULL}, + {L"Italiano", IDR_LANG_IT, LANG_ITALIAN, "it", NULL}, + {L"日本語", IDR_LANG_JA, LANG_JAPANESE, "ja", NULL}, + {L"Nederlands", IDR_LANG_NL, LANG_DUTCH, "nl", NULL}, + {L"Polski", IDR_LANG_PL, LANG_POLISH, "pl", NULL}, + {L"Română", IDR_LANG_RO, LANG_ROMANIAN, "ro", NULL}, + {L"Русский", IDR_LANG_RU, LANG_RUSSIAN, "ru", NULL}, + {L"Tiếng Việt", IDR_LANG_VI, LANG_VIETNAMESE, "vi", NULL}, + {L"简体中文", IDR_LANG_ZHCN, LANG_CHINESE, "zh-cn", L"zh-CN"}, + {L"繁體中文", IDR_LANG_ZHHK, LANG_CHINESE, "zh-hk", L"zh-HK"}, +}; + +typedef int (WINAPI *LCIDToLocaleNameFn)( + LCID Locale, + LPWSTR lpName, + int cchName, + DWORD dwFlags); + +static void UpdateSelectLanguageDialog (HWND hwndDlg) +{ + HWND hLangList = GetDlgItem (hwndDlg, IDC_LANGUAGES_LIST); + LPARAM nIndex = SendMessage (hLangList, CB_GETCURSEL, 0, 0); + int resourceid = (int) SendMessage (hLangList, CB_GETITEMDATA, nIndex, 0); + + LoadLanguageFromResource (resourceid, TRUE, TRUE); + + LocalizeDialog (hwndDlg, "IDD_INSTL_DLG"); +} + +BOOL CALLBACK SelectLanguageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + + switch (uMsg) + { + case WM_INITDIALOG: + { + char* preferredLanguage = GetPreferredLangId (); + if (strlen (preferredLanguage)) + { + // language already selected by user in current install + // use it for the setup + for (size_t i = 0; i < ARRAYSIZE (g_languagesEntries); i++) + { + if (0 == strcmp (preferredLanguage, g_languagesEntries[i].internalId)) + { + LoadLanguageFromResource (g_languagesEntries[i].resourceid, FALSE, TRUE); + break; + } + } + EndDialog (hwndDlg, IDCANCEL); + return FALSE; + } + else + { + // Get the default UI language + LCIDToLocaleNameFn LCIDToLocaleNamePtr = (LCIDToLocaleNameFn) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "LCIDToLocaleName"); + WCHAR langtag[256]; + LANGID defaultLanguage = GetUserDefaultUILanguage (); + WORD langid = (WORD) (defaultLanguage & 0x03FF); // primary language ID + + InitDialog (hwndDlg); + + LCIDToLocaleNamePtr (MAKELCID (defaultLanguage, 0), langtag, ARRAYSIZE (langtag), 0); // language tag (e.g. "en-US") + int resourceid = IDR_LANGUAGE; + for (size_t i = 0; i < ARRAYSIZE (g_languagesEntries); i++) + { + if (g_languagesEntries[i].langid == langid) + { + if (!g_languagesEntries[i].langtag || (0 == _wcsicmp (g_languagesEntries[i].langtag, langtag))) + { + resourceid = g_languagesEntries[i].resourceid; + break; + } + } + } + + for (size_t i = 0; i < ARRAYSIZE (g_languagesEntries); i++) + { + AddComboPair (GetDlgItem (hwndDlg, IDC_LANGUAGES_LIST), g_languagesEntries[i].name, g_languagesEntries[i].resourceid); + } + + SelectAlgo (GetDlgItem (hwndDlg, IDC_LANGUAGES_LIST), &resourceid); + + UpdateSelectLanguageDialog (hwndDlg); + } + + } + return TRUE; + + case WM_COMMAND: + if (CBN_SELCHANGE == HIWORD (wParam)) + { + UpdateSelectLanguageDialog (hwndDlg); + return 1; + } + + if (lw == IDOK) + { + bUserSetLanguage = TRUE; + EndDialog (hwndDlg, IDOK); + return 1; + } + + if (lw == IDCANCEL) + { + SetPreferredLangId (""); + EndDialog (hwndDlg, IDCANCEL); + return 1; + } + return 0; + } + + return 0; +} + int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpszCommandLine, int nCmdShow) { @@ -2525,6 +2658,10 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpsz if (!bUninstall) { + if (!bDevm && !LocalizationActive && (nCurrentOS >= WIN_VISTA)) + { + DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_INSTALL_LANGUAGE), NULL, (DLGPROC) SelectLanguageDialogProc, (LPARAM) 0 ); + } /* Create the main dialog for install */ DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_INSTL_DLG), NULL, (DLGPROC) MainDialogProc, diff --git a/src/Setup/Setup.rc b/src/Setup/Setup.rc index 587fc84c..096a6d96 100644 --- a/src/Setup/Setup.rc +++ b/src/Setup/Setup.rc @@ -74,6 +74,26 @@ IDR_SETUP_RSRC_HEADER HEADER "resource.h" IDR_COMREG REGISTRY "ComSetup.rgs" +///////////////////////////////////////////////////////////////////////////// +// +// LANGUAGES +// + +IDR_LANG_AR LANGUAGES "..\\..\\Translations\\Language.ar.xml" +IDR_LANG_CS LANGUAGES "..\\..\\Translations\\Language.cs.xml" +IDR_LANG_DE LANGUAGES "..\\..\\Translations\\Language.de.xml" +IDR_LANG_ES LANGUAGES "..\\..\\Translations\\Language.es.xml" +IDR_LANG_FR LANGUAGES "..\\..\\Translations\\Language.fr.xml" +IDR_LANG_IT LANGUAGES "..\\..\\Translations\\Language.it.xml" +IDR_LANG_JA LANGUAGES "..\\..\\Translations\\Language.ja.xml" +IDR_LANG_NL LANGUAGES "..\\..\\Translations\\Language.nl.xml" +IDR_LANG_PL LANGUAGES "..\\..\\Translations\\Language.pl.xml" +IDR_LANG_RO LANGUAGES "..\\..\\Translations\\Language.ro.xml" +IDR_LANG_RU LANGUAGES "..\\..\\Translations\\Language.ru.xml" +IDR_LANG_VI LANGUAGES "..\\..\\Translations\\Language.vi.xml" +IDR_LANG_ZHCN LANGUAGES "..\\..\\Translations\\Language.zh-cn.xml" +IDR_LANG_ZHHK LANGUAGES "..\\..\\Translations\\Language.zh-hk.xml" + ///////////////////////////////////////////////////////////////////////////// // // Dialog @@ -185,6 +205,17 @@ BEGIN PUSHBUTTON "Donate now...",IDC_DONATE,124,94,96,14 END +IDD_INSTALL_LANGUAGE DIALOGEX 0, 0, 213, 87 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "VeraCrypt Setup Wizard" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,102,66,50,14 + PUSHBUTTON "Cancel",IDCANCEL,156,66,50,14 + ICON 501,IDC_STATIC,10,10,32,32 + LTEXT "Select the language to use during the installation:",IDC_SELECT_LANGUAGE_LABEL,42,13,157,26 + COMBOBOX IDC_LANGUAGES_LIST,42,44,164,155,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END ///////////////////////////////////////////////////////////////////////////// // @@ -228,7 +259,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO +GUIDELINES DESIGNINFO BEGIN IDD_UNINSTALL, DIALOG BEGIN @@ -299,6 +330,14 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 147 END + + IDD_INSTALL_LANGUAGE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 206 + TOPMARGIN, 7 + BOTTOMMARGIN, 80 + END END #endif // APSTUDIO_INVOKED diff --git a/src/Setup/Wizard.c b/src/Setup/Wizard.c index 0303f2e6..94e3aae5 100644 --- a/src/Setup/Wizard.c +++ b/src/Setup/Wizard.c @@ -24,6 +24,7 @@ #include "Common/Resource.h" #include "Resource.h" #include "Setup.h" +#include "Registry.h" #include #include @@ -60,6 +61,8 @@ BOOL bInProgress = FALSE; BOOL bPromptTutorial = FALSE; BOOL bPromptReleaseNotes = FALSE; +extern BOOL bUserSetLanguage; + int nPbar = 0; /* Control ID of progress bar */ static HFONT hDonTextFont; @@ -1069,6 +1072,14 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa /* Installation completed successfully */ + /* if user selected a language, use for GUI in the next run */ + if (bUserSetLanguage) + { + WCHAR langId[6]; + MultiByteToWideChar (CP_ACP, 0, GetPreferredLangId(), -1, langId, ARRAYSIZE (langId)); + WriteRegistryString (L"Software\\VeraCrypt", L"SetupUILanguage", langId); + } + bInProgress = FALSE; nCurPageNo = DONATIONS_PAGE; -- cgit v1.2.3