From 1ea8d5b8f75269792b6e5ea87daa7c7713569feb Mon Sep 17 00:00:00 2001 From: Heiko Hund Date: Sun, 18 Jan 2009 20:37:32 +0000 Subject: [PATCH] added functions for localized dialog, string and icon resources --- localization.c | 369 +++++++++++++++++++++++++++++++------------------ localization.h | 57 ++++---- 2 files changed, 265 insertions(+), 161 deletions(-) diff --git a/localization.c b/localization.c index 6a77000..88e15a0 100755 --- a/localization.c +++ b/localization.c @@ -1,137 +1,232 @@ -/* - * OpenVPN-GUI -- A Windows GUI for OpenVPN. - * - * Copyright (C) 2009 Heiko Hund - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -static const LANGID defaultLangId = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL); - -static HRSRC -FindResourceLang(HINSTANCE instance, PTSTR resType, PTSTR resId, LANGID langId) -{ - HRSRC res; - - /* try to find the resource in requested language */ - res = FindResourceEx(instance, resType, resId, langId); - if (res) - return res; - - /* try to find the resource in the default language */ - res = FindResourceEx(instance, resType, resId, defaultLangId); - if (res) - return res; - - /* try to find the resource in any language */ - return FindResource(instance, resId, resType); -} - - -int -LoadStringLang(HINSTANCE instance, UINT stringId, LANGID langId, PTSTR buffer, int bufferSize) -{ - PWCH entry; - PTSTR resBlockId = MAKEINTRESOURCE(stringId / 16 + 1); - int resIndex = stringId & 15; - - /* find resource block for string */ - HRSRC res = FindResourceLang(instance, RT_STRING, resBlockId, langId); - if (res == NULL) - return 0; - - /* get pointer to first entry in resource block */ - entry = (PWCH) LoadResource(instance, res); - if (entry == NULL) - return 0; - - /* search for string in block */ - for (int i = 0; i < 16; i++) - { - /* string found, copy it */ - if (i == resIndex && *entry) - { - int maxLen = (*entry < bufferSize ? *entry : bufferSize); -#ifdef _UNICODE - wcsncpy(buffer, entry + 1, maxLen); -#else - WideCharToMultiByte(CP_ACP, 0, entry + 1, *entry, buffer, maxLen, "?", NULL); -#endif - buffer[bufferSize - 1] = 0; - return _tcslen(buffer); - } - - /* string does not exist */ - if (i == resIndex) - break; - - /* skip over this entry */ - entry += ((*entry) + 1); - } - - return 0; -} - - -HICON -LoadIconLang(HINSTANCE instance, PTSTR iconId, LANGID langId) -{ - /* find group icon resource */ - HRSRC res = FindResourceLang(instance, RT_GROUP_ICON, iconId, langId); - if (res == NULL) - return NULL; - - HGLOBAL resInfo = LoadResource(instance, res); - if (resInfo == NULL) - return NULL; - - int id = LookupIconIdFromDirectory(resInfo, TRUE); - if (id == 0) - return NULL; - - /* find the actual icon */ - res = FindResourceLang(instance, RT_ICON, MAKEINTRESOURCE(id), langId); - if (res == NULL) - return NULL; - - resInfo = LoadResource(instance, res); - if (resInfo == NULL) - return NULL; - - DWORD resSize = SizeofResource(instance, res); - if (resSize == 0) - return NULL; - - return CreateIconFromResource(resInfo, resSize, TRUE, 0x30000); -} - -INT_PTR -DialogBoxLang(HINSTANCE instance, PTSTR dialogId, LANGID langId, HWND parentWnd, DLGPROC dialogFunc) -{ - /* find dialog resource */ - HRSRC res = FindResourceLang(instance, RT_DIALOG, dialogId, langId); - if (res == NULL) - return -1; - - HGLOBAL resInfo = LoadResource(instance, res); - if (resInfo == NULL) - return -1; - - return DialogBoxIndirect(instance, resInfo, parentWnd, dialogFunc); -} +/* + * OpenVPN-GUI -- A Windows GUI for OpenVPN. + * + * Copyright (C) 2009 Heiko Hund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* for GetUserDefaultUILanguage() */ +#include +#define WINVER Windows2000 + +#include +#include +#include +#include +#include "registry.h" + +static const LANGID defaultLangId = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL); + +static HRSRC +FindResourceLang(HINSTANCE instance, PTSTR resType, PTSTR resId, LANGID langId) +{ + HRSRC res; + + /* try to find the resource in requested language */ + res = FindResourceEx(instance, resType, resId, langId); + if (res) + return res; + + /* try to find the resource in the default language */ + res = FindResourceEx(instance, resType, resId, defaultLangId); + if (res) + return res; + + /* try to find the resource in any language */ + return FindResource(instance, resId, resType); +} + + +static LANGID +GetGUILanguage(void) +{ + return GetUserDefaultUILanguage(); +} + + +static int +LoadStringLang(HINSTANCE instance, UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_list args) +{ + PWCH entry; + PTSTR resBlockId = MAKEINTRESOURCE(stringId / 16 + 1); + int resIndex = stringId & 15; + + /* find resource block for string */ + HRSRC res = FindResourceLang(instance, RT_STRING, resBlockId, langId); + if (res == NULL) + return 0; + + /* get pointer to first entry in resource block */ + entry = (PWCH) LoadResource(instance, res); + if (entry == NULL) + return 0; + + /* search for string in block */ + for (int i = 0; i < 16; i++) + { + /* skip over this entry */ + if (i != resIndex) + { + entry += ((*entry) + 1); + continue; + } + + /* string does not exist */ + if (i == resIndex && *entry == 0) + break; + + /* string found, copy it */ + PTSTR formatStr = (PTSTR) malloc((*entry + 1) * sizeof(TCHAR)); + if (formatStr == NULL) + break; + formatStr[*entry] = 0; + +#ifdef _UNICODE + wcsncpy(formatStr, entry + 1, *entry); +#else + WideCharToMultiByte(CP_ACP, 0, entry + 1, *entry, formatStr, *entry, "?", NULL); +#endif + + _vsntprintf(buffer, bufferSize, formatStr, args); + buffer[bufferSize - 1] = 0; + free(formatStr); + return _tcslen(buffer); + } + + return 0; +} + + +static PTSTR +__LoadLocalizedString(const UINT stringId, va_list args) +{ + static TCHAR msg[512]; + msg[0] = 0; + LoadStringLang(GetModuleHandle(NULL), stringId, GetGUILanguage(), msg, sizeof(msg)/sizeof(*msg), args); + return msg; +} + + +PTSTR +LoadLocalizedString(const UINT stringId, ...) +{ + va_list args; + va_start(args, stringId); + PTSTR str = __LoadLocalizedString(stringId, args); + va_end(args); + return str; +} + + +int +LoadLocalizedStringBuf(PTSTR buffer, int bufferSize, const UINT stringId, ...) +{ + va_list args; + va_start(args, stringId); + int len = LoadStringLang(GetModuleHandle(NULL), stringId, GetGUILanguage(), buffer, bufferSize, args); + va_end(args); + return len; +} + + +void +ShowLocalizedMsg(const PTSTR caption, const UINT stringId, ...) +{ + va_list args; + va_start(args, stringId); + MessageBox(NULL, __LoadLocalizedString(stringId, args), caption, MB_OK | MB_SETFOREGROUND); + va_end(args); +} + + +HICON +LoadLocalizedIcon(const UINT iconId) +{ + HINSTANCE instance = GetModuleHandle(NULL); + LANGID langId = GetGUILanguage(); + + /* find group icon resource */ + HRSRC res = FindResourceLang(instance, RT_GROUP_ICON, MAKEINTRESOURCE(iconId), langId); + if (res == NULL) + return NULL; + + HGLOBAL resInfo = LoadResource(instance, res); + if (resInfo == NULL) + return NULL; + + int id = LookupIconIdFromDirectory(resInfo, TRUE); + if (id == 0) + return NULL; + + /* find the actual icon */ + res = FindResourceLang(instance, RT_ICON, MAKEINTRESOURCE(id), langId); + if (res == NULL) + return NULL; + + resInfo = LoadResource(instance, res); + if (resInfo == NULL) + return NULL; + + DWORD resSize = SizeofResource(instance, res); + if (resSize == 0) + return NULL; + + return CreateIconFromResource(resInfo, resSize, TRUE, 0x30000); +} + + +INT_PTR +LocalizedDialogBoxParam(const UINT dialogId, DLGPROC dialogFunc, const LPARAM param) +{ + HINSTANCE instance = GetModuleHandle(NULL); + + /* find dialog resource */ + HRSRC res = FindResourceLang(instance, RT_DIALOG, MAKEINTRESOURCE(dialogId), GetGUILanguage()); + if (res == NULL) + return -1; + + HGLOBAL resInfo = LoadResource(instance, res); + if (resInfo == NULL) + return -1; + + return DialogBoxIndirectParam(instance, resInfo, NULL, dialogFunc, param); +} + + +INT_PTR +LocalizedDialogBox(const UINT dialogId, DLGPROC dialogFunc) +{ + return LocalizedDialogBoxParam(dialogId, dialogFunc, 0); +} + + +HWND +CreateLocalizedDialog(const UINT dialogId, DLGPROC dialogFunc) +{ + HINSTANCE instance = GetModuleHandle(NULL); + + /* find dialog resource */ + HRSRC res = FindResourceLang(instance, RT_DIALOG, MAKEINTRESOURCE(dialogId), GetGUILanguage()); + if (res == NULL) + return NULL; + + HGLOBAL resInfo = LoadResource(instance, res); + if (resInfo == NULL) + return NULL; + + return CreateDialogIndirect(instance, resInfo, NULL, dialogFunc); +} diff --git a/localization.h b/localization.h index dfef6a2..0161e6e 100755 --- a/localization.h +++ b/localization.h @@ -1,24 +1,33 @@ -/* - * OpenVPN-GUI -- A Windows GUI for OpenVPN. - * - * Copyright (C) 2009 Heiko Hund - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -int LoadStringLang(HINSTANCE, UINT, LANGID, PTSTR, int); -HICON LoadIconLang(HINSTANCE, PTSTR, LANGID); -INT_PTR DialogBoxLang(HINSTANCE, LPCTSTR, LANGID, HWND, DLGPROC); +/* + * OpenVPN-GUI -- A Windows GUI for OpenVPN. + * + * Copyright (C) 2009 Heiko Hund + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LOCALIZATION_H +#define LOCALIZATION_H + +PTSTR LoadLocalizedString(const UINT, ...); +int LoadLocalizedStringBuf(PTSTR, const int, const UINT, ...); +void ShowLocalizedMsg(const PTSTR, const UINT, ...); +HICON LoadLocalizedIcon(const UINT); +INT_PTR LocalizedDialogBoxParam(const UINT, DLGPROC, const LPARAM); +INT_PTR LocalizedDialogBox(const UINT, DLGPROC); +HWND CreateLocalizedDialog(const UINT, DLGPROC); + +#endif