📄 multilanguage.cpp
字号:
/*
* Openmysee
*
* 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; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
// MultiLanguage.cpp : Defines the entry point for the DLL application.
//
#include <assert.h>
#include "MultiLanguage.h"
StringMapLoader g_loader;
HMODULE g_module;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID /*lpReserved*/
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_module = (HMODULE)hModule;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
StringMapLoader::StringMapLoader(void)
{
m_mapLangId2Str[DEFAULT_LANG_ID] = "en_US";
m_mapLangId2Str[TAIWAN_LANG_ID] = "zh_TW";
m_mapLangId2Str[HONGKONG_LANG_ID] = "zh_TW";
m_mapLangId2Str[MAINLAND_LANG_ID] = "zh_CN";
m_idCurLang = 0xffff;
// load preferred language
LANGID id = DetectLanguage();
if(!SwitchLanguage(id)) {
// load default language
if(!SwitchLanguage(DEFAULT_LANG_ID)) {
return;
}
}
m_idCurLang = id;
}
StringMapLoader::~StringMapLoader(void)
{
}
bool StringMapLoader::SwitchLanguage(
const LANGID langID // in, 语言ID
)
{
// get file name of target language
char buf[1024];
if(::GetModuleFileNameA(g_module, buf, 1024) == 0)
return false;
char* temp = strrchr(buf, '\\');
if(temp == NULL)
return false;
temp[1] = '\0';
string filename = buf;
filename.append(g_loader.m_mapLangId2Str[langID]);
filename.append(".ini");
// load preferred language
if(!g_loader.LoadLanguageFile(filename))
return false;
g_loader.m_idCurLang = langID;
return true;
}
bool StringMapLoader::GetCurLanguage(
LANGID& langID // out, 当前语言的ID
)
{
langID = g_loader.m_idCurLang;
return (g_loader.m_idCurLang != 0xffff);
}
UINT StringMapLoader::GetStrByStr(
const LPCTSTR keyStr, // in, 索引字符串
LPTSTR buf, // out, 存储字符串的缓冲区
const UINT bufSize // in, 缓冲区的大小
)
{
if(!buf || !keyStr)
return 0;
buf[0] = 0;
tstring key = keyStr;
tstring valStr = g_loader.m_mapKeyStr2ValStr[key];
if(valStr.empty() || bufSize <= valStr.size())
return 0;
_tcscpy(buf, valStr.data());
return static_cast<UINT>(valStr.size());
}
bool StringMapLoader::LoadLanguageFile(const string &filename)
{
if(filename.size() <= 0)
return false;
// open language file
tifstream ifs;
ifs.open(filename.c_str());
if(!ifs || !ifs.is_open())
{
ifs.close();
return false;
}
// read language strings
tstring line;
tstring name;
tstring value;
size_t posEqual;
while(getline(ifs, line, TEXT('\n')))
{
if(!line.length())
continue;
if(line[0] == TEXT('#'))
continue; // 注释行
if(line[0] == TEXT(';'))
continue; // 注释行
posEqual=line.find(TEXT('='));
if(posEqual == -1)
continue;
name = line.substr(0,posEqual);
value = line.substr(posEqual+1);
size_t index = value.find(TEXT('\r'));
if(index != -1)
value = value.substr(0, index);
index = value.find(TEXT('\n'));
if(index != -1)
value = value.substr(0, index);
// add to map
m_mapKeyStr2ValStr[name] = value;
}
ifs.close();
return true;
}
// The following functions contain code to
// detect the language in which the initial
// user interface should be displayed
BOOL CALLBACK EnumLangProc(HANDLE /*hModule*/, LPCTSTR /*lpszType*/, LPCTSTR /*lpszName*/,
WORD wIDLanguage, LONG_PTR lParam)
{
PLANGINFO LangInfo;
LangInfo = (PLANGINFO) lParam;
LangInfo->Count++;
LangInfo->LangID = wIDLanguage;
return TRUE; // continue enumeration
}
// Detects the language of ntdll.dll with some specific processing for
// the Hongkong SAR version
LANGID StringMapLoader::GetNTDLLNativeLangID()
{
LANGINFO LangInfo;
LPCTSTR Type = (LPCTSTR) ((LPVOID)((WORD)16));
LPCTSTR Name = (LPCTSTR) 1;
ZeroMemory(&LangInfo,sizeof(LangInfo));
// Get the HModule for ntdll.
HMODULE hMod = GetModuleHandle(TEXT("ntdll.dll"));
if (hMod==NULL)
return 0;
BOOL result = EnumResourceLanguages(hMod, Type, Name, (ENUMRESLANGPROC)EnumLangProc, (LONG_PTR) &LangInfo);
if (!result || (LangInfo.Count > 2) || (LangInfo.Count < 1) )
return 0;
return LangInfo.LangID;
}
// Checks if NT4 system is Hongkong SAR version
BOOL StringMapLoader::IsHongKongVersion()
{
HMODULE hMod;
BOOL bRet=FALSE;
typedef BOOL (WINAPI *IMMRELEASECONTEXT)(HWND,HIMC);
IMMRELEASECONTEXT pImmReleaseContext;
hMod = LoadLibrary(TEXT("imm32.dll"));
if (hMod)
{
pImmReleaseContext = (IMMRELEASECONTEXT)GetProcAddress(hMod,"ImmReleaseContext");
if (pImmReleaseContext)
bRet = pImmReleaseContext(NULL,NULL);
FreeLibrary(hMod);
}
return bRet;
}
// This function detects a correct initial UI language for all
// platforms (Win9x, ME, NT4, Windows 2000, Windows XP)
LANGID StringMapLoader::DetectLanguage()
{
OSVERSIONINFO VersionInfo;
LANGID uiLangID = 0;
HKEY hKey;
DWORD Type, BuffLen = MAX_KEY_BUFFER;
TCHAR LangKeyValue[MAX_KEY_BUFFER];
VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( !GetVersionEx(&VersionInfo) )
return 0;
switch( VersionInfo.dwPlatformId )
{
// On Windows NT, Windows 2000 or higher
case VER_PLATFORM_WIN32_NT:
if( VersionInfo.dwMajorVersion >= 5) // Windows 2000 or higher
{
typedef LANGID (WINAPI *Proc_GetUserDefaultUILanguage)();
HMODULE hmodule = LoadLibrary(_T("Kernel32"));
Proc_GetUserDefaultUILanguage procGetUserDefaultUILanguage =
(Proc_GetUserDefaultUILanguage) GetProcAddress(hmodule, "GetUserDefaultUILanguage");
assert(procGetUserDefaultUILanguage);
if(procGetUserDefaultUILanguage)
uiLangID = procGetUserDefaultUILanguage();
else
uiLangID = 0;
}
else
{ // for NT4 check the language of ntdll.dll
uiLangID = GetNTDLLNativeLangID();
if (uiLangID == DEFAULT_LANG_ID)
{ // special processing for Honkong SAR version of NT4
if (IsHongKongVersion())
uiLangID = HONGKONG_LANG_ID;
}
}
break;
// On Windows 95, Windows 98 or Windows ME
case VER_PLATFORM_WIN32_WINDOWS:
// Open the registry key for the UI language
if( RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Default\\Control Panel\\Desktop\\ResourceLocale"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS )
{
// Get the type of the default key
if( RegQueryValueEx(hKey, NULL, NULL, &Type, NULL, NULL) == ERROR_SUCCESS && Type == REG_SZ )
{
// Read the key value
if( RegQueryValueEx(hKey, NULL, NULL, &Type, (LPBYTE)LangKeyValue, &BuffLen) == ERROR_SUCCESS )
uiLangID = static_cast<LANGID>(_ttoi(LangKeyValue));
}
RegCloseKey(hKey);
}
break;
}
if (uiLangID == 0)
uiLangID = GetUserDefaultLangID();
// Return the found language ID.
return uiLangID;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -