📄 language.cpp
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 预处理
#include "Language.h"
#include "Resource.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 语言文件节名和键名
#define LIN_Language TEXT("Language")
#define LIN_Description TEXT("Description")
#define LIN_FontName TEXT("FontName")
#define LIN_FontSize TEXT("FontSize")
#define LIN_Text TEXT("Text")
#define LIN_String TEXT("String")
#define EXT_Lng TEXT(".lng")
#define _NumberOf(v) (sizeof(v) / sizeof(v[0]))
#define _LengthOf(s) (_NumberOf(s) - 1)
#define _StrEnd(t) (t + lstrlen(t))
#ifdef _UNICODE
#define _StrStr(t1, t2) wcsstr(t1, t2)
#define _StrChr(t, c) wcschr(t, c)
#define _StrRChr(t, c) wcsrchr(t, c)
#else // _UNICODE
#define _StrStr(t1, t2) strstr(t1, t2)
#define _StrChr(t, c) strchr(t, c)
#define _StrRChr(t, c) strrchr(t, c)
#endif // _UNICODE
#define _WStrToAStrN(a, w, n) WideCharToMultiByte(CP_ACP, 0, w, -1, a, n, NULL, NULL)
#define _AStrToWStrN(w, a, n) MultiByteToWideChar(CP_ACP, 0, a, -1, w, n)
#ifdef _UNICODE
#define _WStrToStrN(t, w, n) lstrcpyn(t, w, n)
#else // _UNICODE
#define _WStrToStrN(t, w, n) _WStrToAStrN(t, w, n)
#endif // _UNICODE
#define _WStrToStr(t, w) _WStrToStrN(t, w, _NumberOf(t))
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(r) (((ULONG) (r) >> 16) == 0)
#endif
#ifndef CDSIZEOF_STRUCT
#define CDSIZEOF_STRUCT(s, m) (((INT) ((PBYTE) (&((s *) 0)->m) - ((PBYTE) ((s *) 0)))) + sizeof(((s *) 0)->m))
#endif
extern HINSTANCE g_hInst;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLanguage 类静态变量
UINT CLanguage::m_uLang = IDM_View_Default;
UINT CLanguage::m_uMax = IDM_View_Default;
HFONT CLanguage::m_hFont = NULL;
TCHAR CLanguage::m_tzText[1024] = {0};
TCHAR CLanguage::m_tzFileName[MAX_PATH] = {0};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 初始化语言
LANGID CLanguage::Initialize()
{
HANDLE hFind;
LANGID liLang;
LANGID liResult;
WIN32_FIND_DATA fdFind;
TCHAR tzPath[MAX_PATH];
#ifdef _MAKELANG
// 生成语言文件
hFind = NULL;
ZeroMemory(&fdFind, sizeof(WIN32_FIND_DATA));
liLang = GetUserDefaultLangID();
liResult = liLang;
//CIni::SetInt(INI_Language, liResult);
GetModuleFileName(NULL, tzPath, MAX_PATH);
#ifdef _CHS
lstrcpy(_StrRChr(tzPath, '\\') + 1, TEXT("简体中文") EXT_Lng);
WritePrivateProfileString(LIN_Language, LIN_Language, TEXT("2052"), tzPath);
WritePrivateProfileString(LIN_Language, LIN_Description, TEXT("简体中文,Yonsm 制造,欢迎使用。"), tzPath);
WritePrivateProfileString(LIN_Language, LIN_FontName, TEXT("宋体"), tzPath);
WritePrivateProfileString(LIN_Language, LIN_FontSize, TEXT("9"), tzPath);
#else // _CHS
lstrcpy(_StrRChr(tzPath, '\\') + 1, TEXT("English") EXT_Lng);
WritePrivateProfileString(LIN_Language, LIN_Language, TEXT("1033"), tzPath);
WritePrivateProfileString(LIN_Language, LIN_Description, TEXT("English. Powered by Yonsm. No rights reserved."), tzPath);
WritePrivateProfileString(LIN_Language, LIN_FontName, TEXT("Tahoma"), tzPath);
WritePrivateProfileString(LIN_Language, LIN_FontSize, TEXT("8"), tzPath);
#endif // _CHS
lstrcpy(m_tzFileName, tzPath);
#else // _MAKELANG
// 获取语言标识
liResult = 0;
// 下列配置文件名为临时代码,根据需要更改
GetModuleFileName(NULL, tzPath, MAX_PATH);
lstrcpy(tzPath + lstrlen(tzPath) - 4, TEXT(".ini"));
// 从配置文件中获取语言设置
liLang = GetPrivateProfileInt(TEXT("Main"), LIN_Language, GetUserDefaultLangID(), tzPath);
if (liLang)
{
// 查找语言文件
GetModuleFileName(NULL, tzPath, MAX_PATH);
lstrcpy(_StrRChr(tzPath, '\\') + 1, TEXT("*") EXT_Lng);
hFind = FindFirstFile(tzPath, &fdFind);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
// 如果是指定的语言
lstrcpy(_StrRChr(tzPath, '\\') + 1, fdFind.cFileName);
if (liLang == GetPrivateProfileInt(LIN_Language, LIN_Language, 0, tzPath))
{
// 设置语言文件名
liResult = liLang;
lstrcpy(m_tzFileName, tzPath);
Set(NULL, liResult);
break;
}
}
while (FindNextFile(hFind, &fdFind));
FindClose(hFind);
}
}
#endif // _MAKELANG
return liResult;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 列出语言
UINT CLanguage::List(HMENU hMenu)
{
HANDLE hFind;
LANGID liLang;
LANGID liTemp;
WIN32_FIND_DATA fdFind;
TCHAR tzPath[MAX_PATH];
// 下列配置文件名为临时代码,根据需要更改
GetModuleFileName(NULL, tzPath, MAX_PATH);
lstrcpy(tzPath + lstrlen(tzPath) - 4, TEXT(".ini"));
// 从配置文件中获取语言设置
liLang = GetPrivateProfileInt(TEXT("Main"), LIN_Language, 0, tzPath);
//liLang = CIni::GetInt(INI_Language);
// 查找语言文件
GetModuleFileName(NULL, tzPath, MAX_PATH);
lstrcpy(_StrRChr(tzPath, '\\') + 1, TEXT("*") EXT_Lng);
hFind = FindFirstFile(tzPath, &fdFind);
if (hFind != INVALID_HANDLE_VALUE)
{
do
{
// 获取语言标识,判断是否为有效
lstrcpy(_StrRChr(tzPath, '\\') + 1, fdFind.cFileName);
liTemp = GetPrivateProfileInt(LIN_Language, LIN_Language, 0, tzPath);
if (liTemp)
{
// 第一次添加,插入分隔符;大于 50 条,跳出
if (m_uMax == IDM_View_Default)
{
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
}
else if (m_uMax >= IDM_View_Default + 50)
{
break;
}
// 添加菜单项
m_uMax++;
fdFind.cFileName[lstrlen(fdFind.cFileName) - _LengthOf(EXT_Lng)] = 0;
AppendMenu(hMenu, MF_BYCOMMAND, m_uMax, fdFind.cFileName);
if (liTemp == liLang)
{
// 记录指定语言
m_uLang = m_uMax;
}
}
}
while (FindNextFile(hFind, &fdFind));
FindClose(hFind);
}
// 选择菜单项
CheckMenuRadioItem(hMenu, IDM_View_Default, m_uMax, m_uLang, MF_BYCOMMAND);
return m_uLang;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 设置语言
VOID CLanguage::Set(HMENU hMenu, UINT uLang)
{
HDC hDC;
LANGID liLang;
LOGFONT lfFont;
TCHAR tzName[MAX_PATH];
// 如果是初始化中设置语言
if (hMenu == NULL)
{
liLang = uLang;
}
else
{
if((uLang <= IDM_View_Default) || (uLang > m_uMax))
{
// 切换到默认语言
liLang = 0;
m_tzFileName[0] = 0;
m_uLang = IDM_View_Default;
}
else
{
// 切换到其它语言
m_uLang = uLang;
GetModuleFileName(NULL, m_tzFileName, MAX_PATH);
GetMenuString(hMenu, uLang, tzName, MAX_PATH, MF_BYCOMMAND);
wsprintf(_StrRChr(m_tzFileName, '\\'), TEXT("\\%s%s"), tzName, EXT_Lng);
liLang = GetPrivateProfileInt(LIN_Language, LIN_Language, 0, m_tzFileName);
}
// 选择菜单项
CheckMenuRadioItem(hMenu, IDM_View_Default, m_uMax, m_uLang, MF_BYCOMMAND);
}
// 下列配置文件名为临时代码,根据需要更改
TCHAR tzPath[MAX_PATH];
GetModuleFileName(NULL, tzPath, MAX_PATH);
lstrcpy(tzPath + lstrlen(tzPath) - 4, TEXT(".ini"));
// 保存语言标识到配置文件中
wsprintf(tzName, TEXT("%d"), liLang);
liLang = WritePrivateProfileString(TEXT("Main"), LIN_Language, tzName, tzPath);
//CIni::SetInt(INI_Language, liLang);
// 创建字体
Destroy();
ZeroMemory(&lfFont, sizeof(LOGFONT));
if (GetPrivateProfileString(LIN_Language, LIN_FontName, NULL, lfFont.lfFaceName, LF_FACESIZE, m_tzFileName))
{
lfFont.lfCharSet = DEFAULT_CHARSET;
lfFont.lfHeight = GetPrivateProfileInt(LIN_Language, LIN_FontSize, 0, m_tzFileName);
if (lfFont.lfHeight)
{
hDC = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);
lfFont.lfHeight = -MulDiv(lfFont.lfHeight, GetDeviceCaps(hDC, LOGPIXELSY), 72);
DeleteDC(hDC);
}
m_hFont = CreateFontIndirect(&lfFont);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 从菜单中获取语言文件名
PTSTR CLanguage::GetDescription(HMENU hMenu, UINT uLang)
{
TCHAR tzName[MAX_PATH];
GetModuleFileName(NULL, m_tzText, MAX_PATH);
GetMenuString(hMenu, uLang, tzName, MAX_PATH, MF_BYCOMMAND);
wsprintf(_StrRChr(m_tzText, '\\'), TEXT("\\%s%s"), tzName, EXT_Lng);
if (GetPrivateProfileString(LIN_Language, LIN_Description, NULL, m_tzText, _NumberOf(m_tzText), m_tzText) == 0)
{
TranslateString(IDM_View_FirstLang);
}
return m_tzText;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获取常规字符串
PTSTR CLanguage::TranslateText(PCTSTR ptzName, PCTSTR ptzDefault)
{
#ifdef _MAKELANG
WritePrivateProfileString(LIN_Text, ptzName, ptzDefault, m_tzFileName);
return (PTSTR) ptzDefault;
#else // _MAKELANG
if ((m_tzFileName[0] == 0) ||
(GetPrivateProfileString(LIN_Text, ptzName, NULL, m_tzText, _NumberOf(m_tzText), m_tzFileName) == 0))
{
return (PTSTR) ptzDefault;
}
return m_tzText;
#endif // _MAKELANG
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获取常规字符串,并替换特殊字符
PTSTR CLanguage::TranslateTextEx(PCTSTR ptzName, PCTSTR ptzDefault)
{
#ifdef _MAKELANG
// 判断是否有两个空字符
BOOL bDoubleNull = FALSE;
CopyMemory(m_tzText, ptzDefault, sizeof(m_tzText));
for (UINT i = 0; i < _LengthOf(m_tzText); i++)
{
if ((m_tzText[i] == 0) && (m_tzText[i + 1] == 0))
{
bDoubleNull = TRUE;
break;
}
}
for (PTSTR p = m_tzText; ; p++)
{
if (*p == '\n')
{
*p = '~';
}
else if (*p == 0)
{
if (bDoubleNull)
{
*p = '`';
if (*(p + 1) == 0)
{
break;
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -