方案一、创建资源文件多语言副本
图1-1 资源文件副本
如图1-1所示,资源文件的对话框和字符串表等资源,都创建对应语言的副本。在APP初始化时,调用接口函数SetThreadUILanguage(langid)来确定使用哪个资源副本。
优点:管理简单,所有资源都定义在同一个rc文件中。
缺点:维护不方便。每个副本修改后,其他副本都要对应修改,而且只能使用VC的资源编辑器对照着修改,不方便。
方案二、使用配置文件定义多语言文本
图2-1 多语言文件配置文件
如图2-1所示,用一个专门的配置文件(如multilang.ini)来定义不同语言的文本,定义文本加载函数读取相应语言的文本,然后显示到界面,如下代码所示:
// 从文件读取对应语言的字符串
CString LoadStringFromFile(UINT nID, LPCTSTR lpszLanguage)
{
// ...
}
// 设置控件文本
CString strText = LoadStringFromFile(CONTROL_ID, _T("Chinese"));
GetDlgItem(CONTROL_ID)->SetWindowText(strText );
优点:修改资源简单。
缺点:界面设计不方便,代码繁琐。
方案三、使用资源DLL
APP的资源文件为默认语言,比如“简体汉字”。需要其他语言时,比如英语,新建en_us DLL项目。APP使用lang.ini设置界面语言,如图3-1。未配置时,使用操作系统的语言。
图3-1
接着把APP项目的资源文件拷贝到资源DLL项目相应的位置。资源文件包括 res.rc、resource.h和res子目录。删除资源DLL的默认资源文件,然后导入刚才拷贝res.rc文件。使用差异比对工具(比如Beyond Compare)对比APP项目的res.rc和资源DLL的res.rc,然后将文本修改为相应的语言,如图3-2所示:
图3-2 资源对照修改
完成修改后编译资源DLL,把dll部署到APP安装目录,在APP初始化时调用以下代码即可:
HINSTANCE hResource = LoadLibrary((strAppPath + L"\\en_us.dll").c_str());
AfxSetResourceHandle(hResource);
当需要显示动态文本时,可以把文本放在“String Table”中,如图3-3:
图3-3 资源的字符串表
代码中加载字符串表资源的示例如下:
CString str;
str.LoadString(IDS_SURE_TO_EXIT);
AfxMessageBox(str, MB_YESNO) != IDYES);
优点:修改和扩展方面,可使用比对工具对照修改,很便捷。
缺点:需要多个资源DLL。
综上,选择方案三更合适。