在MFC中以资源方式实现多语言支持很简单,
只需要将对话框资源副本和字符串资源(String Table)的副本选择为需要支持的语言(程序运行过程中需要用到的字符串使用CString的LoadString方法从String Table中加载,不要直接赋值),翻译之后使用以下几行代码即可实现多语言支持. BOOL bXPLaterOS=FALSE;//是否为xp以后版本的os
OSVERSIONINFO ovs;
ovs.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (::GetVersionEx(&ovs))
{
bXPLaterOS = (ovs.dwPlatformId == VER_PLATFORM_WIN32_NT
&& ovs.dwMajorVersion >= 6
&& ovs.dwMinorVersion >= 0);//vista or later
}
else
{
return FALSE;
}
int lang = GetSysLanguage();
if(lan<0)
{
return FALSE;
}
if(lang == 1)
{
if(bXPLaterOS)
SetThreadUILanguage(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US));
else
SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT));
}
else if(lang == 0)
{
if(bXPLaterOS)
SetThreadUILanguage(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED));
else
SetThreadLocale(MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_DEFAULT));
}
else
{
AfxMessageBox(_T("Not Supported Language."));
return FALSE;
}
这里请注意SetThreadUILanguage和SetThreadLocale的参数, SetThreadUILanguage的参数是使用宏 MAKELANGID生成,
而SetThreadLocale的参数是使用宏MAKELCID生成,当时本人两个参数都是使用宏MAKELCID,导致浪费了大半天时间.
实现多语言另外一种方式为使用资源DLL:
新建一个解决方案,并新建一个WIN32 DLL工程,创建完成后,在工程属性中将入口地址改为无(具体操作为:右键工程 ->属性 ->配置属性 ->链接器 ->高级,将无入口点改为"是"),在资源编译时添加编译条件(就像编译C/C++时定义的预处理宏一样,具体操作为:右键工程 ->属性 ->配置属性 ->资源 ->常规,在预处理定义处添加预处理宏):
1 编译中文(简体)资源时,添加宏定义:AFX_RESOURCE_DLL和AFX_TARG_CHS(这里假设在添加资源时没有设置编译条件)
2 编译英文(美国)资源时,添加宏定义:AFX_RESOURCE_DLL和AFX_TARG_ENU(这里假设在添加资源时没有设置编译条件)
3 exe工程中添加资源预处理宏AFX_RESOURCE_DLL
然后将工程的资源文件添加到工程(即rc文件),由于此处是将dll重新创建解决方案,所以默认情况下,生成的dll和exe不在同一个目录下,可以使用生成事件将生成的dll复制到exe目录(具体操作为:右键工程 ->属性 ->配置属性 ->生成事件 ->生成后事件,在命令行中填入命令copy $(OutDir)$(TargetName)$(TargetExt) exe目录)。
相关技巧使用:
一般在资源中会添加一些非语言性质的资源,如png、bmp、icon图片等,因为这些资源不论是英文还是中文环境,都是一样的,而在默认情况下,添加的这些资源都是以一种默认资源语言的形式添加到工程中的,因此需要修改这些资源的属性,选中待修改的资源(可以按住ctrl键同时选中多个或按住shift键连续选择多个),在属性中将将资源语言(Language)选择为“非特定语言”,在条件(Condition)中添加编译条件,该条件一般情况下指定为AFX_RESOURCE_DLL,因为在不同资源编译时,都会指定预处理宏AFX_RESOURCE_DLL,也可以指定为其他条件,如XXXX_RESOURCE,指定编译条件可以将一些特定的资源编译到exe或不同的dll中去(只需要在工程的资源预处理宏中定义好该条件即可),如系统有一个语言选择对话框,在用户未指定任何语言的情况下,启动程序时,需要显示该对话框让用户选择自己的语言,此时,需要将该对话框资源编译到exe文件中(因为未指定语言,所以无法确认将哪个dll资源Load到可执行程序),具体操作方法为:将对话框语言选择为“非特定语言”,条件添加XXXX_RESOURCE,在exe工程中添加资源预处理宏XXXX_RESOURC。
资源dll编译好后,只需要在exe工程的APP类的InitInstance函数中添加以下语句即可
HINSTANCE hLangRc=LoadLibrary(_T("xxxx.dll"));
if(hLangRc != NULL)
{
AfxSetResourceHandle(hLangRc);
}
else
do something