实现MFC多语言版本

    百度了一番,MFC实现多国语言有不少方法:

  • VS提供对话框的“插入副本”方法;

  • 将要显示的界面文字做一个类似ini文件,加载界面的时候各控件用SetWindowText来显示不同的语言内容;

  • 制作Dll资源文件,不同语言调用不同的Dll;

    等等不同招数,网上各路神仙各有方法来实现之。


    综合下来本人觉得Dll资源文件比较喜欢,尝试写了一个例程。

    开发环境:Win7 64位 专业版、Visual Studio 2012 专业版。

    OK,开工。


    VS中新建一个MFC项目:

    【文件】――【新建】――【项目】,选择“MFC 应用程序”,项目名称:MFCApp,位置:MultiLanguage。

    选择“基于对话框”,取消“使用 Unicode 库”。

    wKiom1S2JdXymxMJAAJa7Yikw2g828.jpg

    【完成】,结束应用程序向导的配置。


    自由发挥一下,做一个程序界面:

    wKiom1S2KZLBLwgGAABFlFzsiB0932.jpg

    控件编辑:

ID
控件类型 Caption
IDC_EDIT_SHOW Edit Control
IDC_BUTTON_SPEAK Button 快说!


     再弄一个菜单:

    wKiom1S2K4bisMk1AABwJeqv9jg797.jpg

    菜单ID:

ID Caption
ID_CN 中文
ID_EN 英文
ID_JP 日语
ID_GM 德文


    Dll资源制作的准备工作:

    将MFCApp中的“资源文件”下的文件“移除”(“移除”后文件还在,并没有被“删除”);

    将“头文件”下的“Resource.h”移除。

    wKioL1S2MP_xEBwCAAC7IUBhQ0k175.jpg


    创建英文版的Dll。

    VS中,【文件】――【添加】――【新建项目】

    选择“MFC DLL”,新项目名称“English”,放在“MultiLanguage”文件夹下。

    wKiom1S2MtLAS_q9AADwS2ccodk417.jpg

    MFC DLL向导不做修改,采用默认的共享MFC DLL规则设置,【完成】。

    wKioL1S2NNmDTNnRAADHTuJc3Lc445.jpg


    删除DLL中不需要的文件:

    “资源文件”下的文件,“头文件”下的Resource.h。

    wKioL1S2NZmRDLbNAADbgLdvbwc145.jpg


    导入相关文件:

    将\MultiLanguage\MFCApp\MFCApp下的“MFCApp.rc”、“resource.h”复制到英文DLL项目的文件夹\MultiLanguage\English下。

    然后将MFCApp的\MultiLanguage\MFCApp\MFCApp\res文件夹中的文件全部复制到英文DLL项目对应的文件夹下。

    再将上述文件添加到 English 项目中。

    右击English项目,【添加】――【现有项】

    wKiom1S2OAug6NL7AAIsO59Q7vE418.jpg

    完成后如下图所示:

    wKiom1S2OKSD4l06AADDQMNZuOc804.jpg


    修改 English 项目中相关资源的语言属性。

    wKiom1S2ObSRXl7YAAGNgT8x6C0197.jpg


    把English项目中的相关界面翻译为英文版,也包括菜单哦。

    wKioL1S2PBzgO6oPAABBy10atTo937.jpg


    修改English项目属性。【配置属性】――【链接器】――【高级】,“无入口点”改为“是(/NOENTRY)”。

    wKiom1S2PLqhA0QgAAMXnCNRAKc785.jpg


    然后就可以按下 F7 生成 DLL 文件了。

    生成成功,不过有一堆warning,本人水平有限,索性无视了,能干活就行。\(�R��Q)/~

    wKiom1S2PkXCsV5DAAILCtmZ1Dg049.jpg


    按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();
}


    至此,大体框架已经搭建完成j_0051.gif,其余部分可查看源代码。走起,看看效果吧!

    wKioL1S3gB2TRnndAACenIFxao8275.jpg        wKiom1S3f1HTXxtkAACC_5IWPFo187.jpg


    另外,文本框中的显示内容采用了从配置文件读取的方式。如果哪位觉得需要将程序打造得能适应更多的语言,可以尝试根据配置文件动态生成程序界面和菜单。

    本例中本人做了一个配置文件:Config.ini,内容如下:

[Language]
Current=2

[Text]
Chinese=你好,这是中文版
English=Hello World
Japanese=私は言うのは日本�Zです。(我说的是日语哦)
German=Ich sagte, IST Deutsch.(我说的是德语哦)


    其实本例的语言Dll文件本人只做了中文和英文的,至于日文和德文的就偷懒了一下,复制了中文的Dll文件,再用eXeScope工具进行了修改:

    wKioL1S3gUvAS8QyAAJrySgtNUY108.jpg


本文参考了网上不少前辈的大作,再次一并感谢!

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

你可能感兴趣的:(mfc,dll,c/c++,多国语言版版本)