百度了一番,MFC实现多国语言有不少方法:
VS提供对话框的“插入副本”方法;
将要显示的界面文字做一个类似ini文件,加载界面的时候各控件用SetWindowText来显示不同的语言内容;
制作Dll资源文件,不同语言调用不同的Dll;
等等不同招数,网上各路神仙各有方法来实现之。
综合下来本人觉得Dll资源文件比较喜欢,尝试写了一个例程。
开发环境:Win7 64位 专业版、Visual Studio 2012 专业版。
OK,开工。
VS中新建一个MFC项目:
【文件】――【新建】――【项目】,选择“MFC 应用程序”,项目名称:MFCApp,位置:MultiLanguage。
选择“基于对话框”,取消“使用 Unicode 库”。
【完成】,结束应用程序向导的配置。
自由发挥一下,做一个程序界面:
控件编辑:
ID |
控件类型 | Caption |
IDC_EDIT_SHOW | Edit Control | |
IDC_BUTTON_SPEAK | Button | 快说! |
再弄一个菜单:
菜单ID:
ID | Caption |
ID_CN | 中文 |
ID_EN | 英文 |
ID_JP | 日语 |
ID_GM | 德文 |
Dll资源制作的准备工作:
将MFCApp中的“资源文件”下的文件“移除”(“移除”后文件还在,并没有被“删除”);
将“头文件”下的“Resource.h”移除。
创建英文版的Dll。
VS中,【文件】――【添加】――【新建项目】
选择“MFC DLL”,新项目名称“English”,放在“MultiLanguage”文件夹下。
MFC DLL向导不做修改,采用默认的共享MFC DLL规则设置,【完成】。
删除DLL中不需要的文件:
“资源文件”下的文件,“头文件”下的Resource.h。
导入相关文件:
将\MultiLanguage\MFCApp\MFCApp下的“MFCApp.rc”、“resource.h”复制到英文DLL项目的文件夹\MultiLanguage\English下。
然后将MFCApp的\MultiLanguage\MFCApp\MFCApp\res文件夹中的文件全部复制到英文DLL项目对应的文件夹下。
再将上述文件添加到 English 项目中。
右击English项目,【添加】――【现有项】
完成后如下图所示:
修改 English 项目中相关资源的语言属性。
把English项目中的相关界面翻译为英文版,也包括菜单哦。
修改English项目属性。【配置属性】――【链接器】――【高级】,“无入口点”改为“是(/NOENTRY)”。
然后就可以按下 F7 生成 DLL 文件了。
生成成功,不过有一堆warning,本人水平有限,索性无视了,能干活就行。\(�R��Q)/~
按English项目的方法可创建中文、日语、德语版本。
再回到久违的MFCApp上。
MFCApp.h头文件中:
// 添加宏定义 #define LANG_CHINESE 0 #define LANG_ENGLISH 1 #define LANG_JAPNESE 2 #define LANG_GERMAN 3
类中添加成员变量:
class CMFCAppApp : public CWinApp { public: CMFCAppApp(); // 重写 public: virtual BOOL InitInstance(); // 新添加代码 private: int m_nLanguage; HINSTANCE m_hLangDLL; // 实现 DECLARE_MESSAGE_MAP() };
MFCApp.cpp文件中:
构造函数初始化
// CMFCAppApp 构造 CMFCAppApp::CMFCAppApp() { // 支持重新启动管理器 m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 // 新增代码 // 初始化变量 m_nLanguage=0; m_hLangDLL=NULL; }
在InitInstance()函数中增加导入语言DLL的代码
// CMFCAppApp 初始化 BOOL CMFCAppApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); AfxEnableControlContainer(); // 创建 shell 管理器,以防对话框包含 // 任何 shell 树视图控件或 shell 列表视图控件。 CShellManager *pShellManager = new CShellManager; // 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); // 标准初始化 // 如果未使用这些功能并希望减小 // 最终可执行文件的大小,则应移除下列 // 不需要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当修改该字符串, // 例如修改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 新增代码。语言选择 // 读取 INI 文件中的设置 CString strIniFile="Config.ini"; m_nLanguage=::GetPrivateProfileInt("Language","Current",0,strIniFile); // 加载对应的 DLL 文件 switch (m_nLanguage) { case LANG_CHINESE: m_hLangDLL=::LoadLibrary("Chinese.dll"); break; case LANG_ENGLISH: m_hLangDLL=::LoadLibrary("English.dll"); break; case LANG_JAPANESE: m_hLangDLL=::LoadLibrary("Japanese.dll"); break; case LANG_GERMAN: m_hLangDLL=::LoadLibrary("German.dll"); break; default: m_hLangDLL=::LoadLibrary("Chinese.dll"); break; } if (m_hLangDLL!=NULL) { AfxSetResourceHandle(m_hLangDLL); } else { AfxMessageBox("语言DLL文件加载失败!"); exit(1); // 非正常终止程序 } // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ CMFCAppDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: 在此放置处理何时用 // “确定”来关闭对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此放置处理何时用 // “取消”来关闭对话框的代码 } else if (nResponse == -1) { TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n"); TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n"); } // 删除上面创建的 shell 管理器。 if (pShellManager != NULL) { delete pShellManager; } // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; }
在类的最后,加入收尾工作:
// CMFCAppApp 收尾 int CMFCAppApp::ExitInstance() { // TODO: 在此添加专用代码和/或调用基类 // 新增代码。释放所加载的 DLL 资源 if(m_hLangDLL) { AfxFreeLibrary(m_hLangDLL); } return CWinApp::ExitInstance(); }
至此,大体框架已经搭建完成,其余部分可查看源代码。走起,看看效果吧!
另外,文本框中的显示内容采用了从配置文件读取的方式。如果哪位觉得需要将程序打造得能适应更多的语言,可以尝试根据配置文件动态生成程序界面和菜单。
本例中本人做了一个配置文件:Config.ini,内容如下:
[Language] Current=2 [Text] Chinese=你好,这是中文版 English=Hello World Japanese=私は言うのは日本�Zです。(我说的是日语哦) German=Ich sagte, IST Deutsch.(我说的是德语哦)
其实本例的语言Dll文件本人只做了中文和英文的,至于日文和德文的就偷懒了一下,复制了中文的Dll文件,再用eXeScope工具进行了修改:
本文参考了网上不少前辈的大作,再次一并感谢!
http://blog.csdn.net/bdc995/article/details/2139125
http://blog.csdn.net/xiliang_pan/article/details/7822230
http://blog.csdn.net/huihui0121/article/details/7654116
http://www.360doc.com/content/12/0922/17/29694_237587201.shtml