From 4d99c9b9f9b99e8d0eb840d9c0bbe66e4be3f378 Mon Sep 17 00:00:00 2001 From: Selva Nair Date: Mon, 28 Nov 2022 18:34:35 -0500 Subject: [PATCH] Respect UI language flow direction in message boxes - Add a function to check flow direction of currently selected UI language - Add MB_RIGHT|MB_RTLREADING to message boxes when language is RTL Note: though we use MessageBoxEx() for popups, and pass langId to it, buttons like OK/Cancel are not automatically localized. It seems these get localized based on the current locale, not the langID passed in. Signed-off-by: Selva Nair --- localization.c | 19 +++++++++++++++++-- localization.h | 6 ++++++ main.c | 2 +- openvpn.c | 17 +++++++++-------- options.c | 2 +- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/localization.c b/localization.c index 8644e24..3f94464 100644 --- a/localization.c +++ b/localization.c @@ -69,6 +69,22 @@ FindResourceLang(PTSTR resType, PTSTR resId, LANGID langId) return FindResource(o.hInstance, resId, resType); } +/* + * Return value: 0 for LTR, 1 for RTL, 2 or 3 for vertical + */ +int +LangFlowDirection(void) +{ + int res = 0; /* LTR by default */ + wchar_t lcname[LOCALE_NAME_MAX_LENGTH]; + wchar_t data[2]; + if (LCIDToLocaleName(MAKELCID(GetGUILanguage(), SORT_DEFAULT), lcname, _countof(lcname), 0) != 0 + && GetLocaleInfoEx(lcname, LOCALE_IREADINGLAYOUT, data, 2) != 0) + { + res = _wtoi(data); + } + return res; +} LANGID GetGUILanguage(void) @@ -257,10 +273,9 @@ static int __ShowLocalizedMsgEx(const UINT type, HANDLE parent, LPCTSTR caption, const UINT stringId, va_list args) { return MessageBoxEx(parent, __LoadLocalizedString(stringId, args), caption, - type | MB_SETFOREGROUND, GetGUILanguage()); + type | MB_SETFOREGROUND | MBOX_RTL_FLAGS, GetGUILanguage()); } - int ShowLocalizedMsgEx(const UINT type, HANDLE parent, LPCTSTR caption, const UINT stringId, ...) { diff --git a/localization.h b/localization.h index 18eec80..0e44ac1 100644 --- a/localization.h +++ b/localization.h @@ -37,5 +37,11 @@ HWND CreateLocalizedDialogParam(const UINT, DLGPROC, const LPARAM); HWND CreateLocalizedDialog(const UINT, DLGPROC); INT_PTR CALLBACK GeneralSettingsDlgProc(HWND, UINT, WPARAM, LPARAM); LANGID GetGUILanguage(void); +/* + * Detect whether the selected UI language is LTR or RTL. + * Returns 0 for LTR, 1 for RTL, 2 or 3 for vertical + */ +int LangFlowDirection(void); +#define MBOX_RTL_FLAGS ((LangFlowDirection() == 1) ? MB_RIGHT|MB_RTLREADING : 0) #endif diff --git a/main.c b/main.c index 11b83cc..8848043 100644 --- a/main.c +++ b/main.c @@ -938,7 +938,7 @@ ErrorExit(int exit_code, const wchar_t *msg) { if (msg) MessageBoxExW(NULL, msg, TEXT(PACKAGE_NAME), - MB_OK | MB_SETFOREGROUND|MB_ICONERROR, GetGUILanguage()); + MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); if (o.hWnd) { StopAllOpenVPN(); diff --git a/openvpn.c b/openvpn.c index b3c2d71..fd663d7 100644 --- a/openvpn.c +++ b/openvpn.c @@ -1283,8 +1283,8 @@ OnTimeout(connection_t *c, UNUSED char *msg) c->state = connecting; if (!OpenManagement(c)) { - MessageBoxEx(NULL, L"Failed to open management", _T(PACKAGE_NAME), - MB_OK|MB_SETFOREGROUND|MB_ICONERROR, GetGUILanguage()); + MessageBoxExW(NULL, L"Failed to open management", _T(PACKAGE_NAME), + MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); StopOpenVPN(c); } return; @@ -1316,8 +1316,8 @@ OnStop(connection_t *c, UNUSED char *msg) SetForegroundWindow(c->hwndStatus); ShowWindow(c->hwndStatus, SW_SHOW); } - MessageBox(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONN_TERMINATED, c->config_file), - _T(PACKAGE_NAME), MB_OK); + MessageBoxExW(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONN_TERMINATED, c->config_file), + _T(PACKAGE_NAME), MB_OK | MBOX_RTL_FLAGS, GetGUILanguage()); SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); break; @@ -1340,7 +1340,8 @@ OnStop(connection_t *c, UNUSED char *msg) SetForegroundWindow(c->hwndStatus); ShowWindow(c->hwndStatus, SW_SHOW); } - MessageBox(c->hwndStatus, LoadLocalizedString(msg_id, c->config_name), _T(PACKAGE_NAME), MB_OK); + MessageBoxExW(c->hwndStatus, LoadLocalizedString(msg_id, c->config_name), + _T(PACKAGE_NAME), MB_OK | MBOX_RTL_FLAGS, GetGUILanguage()); SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); break; @@ -1764,7 +1765,7 @@ OnNeedOk (connection_t *c, char *msg) } const char *fmt; - if (MessageBoxW (NULL, wstr, L""PACKAGE_NAME, MB_OKCANCEL) == IDOK) + if (MessageBoxExW(NULL, wstr, L""PACKAGE_NAME, MB_OKCANCEL | MBOX_RTL_FLAGS, GetGUILanguage()) == IDOK) { fmt = "needok \'%s\' ok"; } @@ -2124,8 +2125,8 @@ ThreadOpenVPNStatus(void *p) if (!OpenManagement(c)) { - MessageBoxEx(NULL, L"Failed to open management", _T(PACKAGE_NAME), - MB_OK|MB_SETFOREGROUND|MB_ICONERROR, GetGUILanguage()); + MessageBoxExW(NULL, L"Failed to open management", _T(PACKAGE_NAME), + MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); StopOpenVPN(c); } diff --git a/options.c b/options.c index a1225d6..32e86b4 100644 --- a/options.c +++ b/options.c @@ -96,7 +96,7 @@ add_option(options_t *options, int i, TCHAR **p) LoadLocalizedStringBuf(caption, _countof(caption), IDS_NFO_USAGECAPTION); LoadLocalizedStringBuf(msg, _countof(msg), IDS_NFO_USAGE); - MessageBoxEx(NULL, msg, caption, MB_OK | MB_SETFOREGROUND, GetGUILanguage()); + MessageBoxExW(NULL, msg, caption, MB_OK | MB_SETFOREGROUND | MBOX_RTL_FLAGS, GetGUILanguage()); exit(0); } else if (streq(p[0], _T("connect")) && p[1])