基于MFC的Windows软件——常用的制作多国语版本有俩种方法:
一: 每个语言对应一套资源文件(.rc),根据系统语言读取不同的资源文件,使用于界面简单,要显示的文字较少的项目
二: 每个语言对应做一个dll,根据系统语言动态加载dll,适应于界面较复杂,要显示的文字较多的项目
开发环境: VS2013
方法一:
新建MutLangTest工程后,默认有一个MutLangTest.rc文件,一般把MutLangTest.rc作为英文对应的资源文件。
- 假设我要对应中国简体、日文俩种多国语,首先新建俩个.rc,LanguageID 作为后缀
MutLangTest0804.rc2 中国简体
MutLangTest0411.rc2 日文
- 在MutLangTest.rc的末尾include新建的俩个.rc文件
#include "res\MutLangTest0804.rc2"
#include "res\MutLangTest0411.rc2"
-
把MutLangTest.rc中定义的需要显示的内容拷贝到MutLangTest0804.rc2和MutLangTest0411.rc2,并做适当的修改注意俩个新建.rc文件的编码方式,否则会乱码
一般需要拷贝的内容大致为stringtable 和 对话框,如下所示
//MutLangTest.rc
STRINGTABLE
BEGIN
IDS_NAME "MutLangTest"
IDS_TITLE "MutLangTest Example"
END
IDD_MUTLANGTEST_DLG DIALOGEX 0, 0, 153, 51
WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "MutLangTest"
FONT 6, "MS Sans Serif", 0, 0, 0x1
BEGIN
CTEXT "Multi language",IDC_STATIC,31,4,74,9
PUSHBUTTON "Cancel",IDC_CANCEL,49,34,48,10
END
//MutLangTest0804.rc (MutLangTest0411.rc同)
//把需要翻译的改成相应语言
//把ID都加上相应语言的后缀
STRINGTABLE
BEGIN
IDS_NAME0804 "多国语测试工程"
IDS_TITLE0804 "多国语测试工程例子"
END
IDD_MUTLANGTEST_DLG0804 DIALOGEX 0, 0, 153, 51
WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "多国语测试工程"
FONT 6, "MS Sans Serif", 0, 0, 0x1
BEGIN
CTEXT "多国语",IDC_STATIC,31,4,74,9
PUSHBUTTON "取消",IDC_CANCEL,49,34,48,10
END
- 在Resource.h中定义各国语言stringtable和dlg的ID,注意每组的ID号按顺序依次增加
#define IDS_NAME 1
#define IDS_NAME0804 2
#define IDS_NAME0411 3
#define IDS_TITLE 10
#define IDS_TITLE0804 11
#define IDS_TITLE0411 12
#define IDD_MUTLANGTEST_DLG 20
#define IDD_MUTLANGTEST_DLG0804 21
#define IDD_MUTLANGTEST_DLG0411 22
- 实现动态加载不同的stringtable: 比如我要弹一个MSG,显示的内容为IDS_NAME的string
CString csMsg;
csMsg.LoadString(AfxGetResourceHandle(),LoadRC(IDS_NAME))
AfxMessageBox(csMsg);
- 实现动态加载dlg界面:dlg ID为
IDD_MUTLANGTEST_DLG
UpdateDlg dlg;
dlg.Create(LoadRC(IDD_MUTLANGTEST_DLG), ...);
// 根据不同的语言系统,得到各语言rc中对应的ID
int LoadRC(int nResourceID)
{
LANGID langID;
langID = GetLanguageID();
int nMutResourceID = nResourceID;
switch (langID)
{
// 中国简体
case 2052:
nMutResourceID += 1;
break;
// 日文
case 1041:
nMutResourceID += 2;
break;
}
return nMutResourceID;
}
方法二:
新建MutLangTest工程后,再新建MutLangTest0804和MutLangTest0411工程(dll),MutLangTest工程中的所有资源文件都拷贝到MutLangTest0804和MutLangTest0411,包括icon、.rc等;各icon、stringtable和dlg的ID不变,只需修改要翻译的内容
- 实现动态加载不同的多国语dll
BOOL InitInstance()
{
// g_hResource 全局变量
// LoadString(g_hResource,...)、LoadImage(g_hResource,...)等情况会用到
// 加载相应语言的dll,得到其句柄
HINSTANCE hResource = GetResourceDllHandle();
// 成功
if (hResource)
{
g_hResource = hResource;
}
else{
g_hResource = m_hInstance;
}
// 设定程序要加载的资源
AfxSetResourceHandle(g_hResource);
}
HINSTANCE GetResourceDllHandle()
{
LANGID llangID;
TCHAR szDllPath[MAX_PATH];
memset(szDllPath, 0, sizeof(szDllPath));
// 得到LanguageID
llangID = GetUserDefaultLangID();
// 根据LanguageID加载对应的dll
// 此处dll的路径随意写的
// eg: D:\??\MutLangTest0804\MutLangTest0804.dll
szDllPath = _T("D:\\**\\MutLangTest%04x\\MutLangTest%04x.dll");
wsprintf(szDllPath, _T("%s%04x\\%s%04x.dll"), _T("D:\\**\\MutLangTest"), llangID, _T("MutLangTest"), llangID);
if (IsExistFile(szDllPath))
return (LoadLibrary(szDllPath));
return (0L);
}