实现MFC多语言版本

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

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

  • 将要显示的界面文字作一个相似ini文件,加载界面的时候各控件用SetWindowText来显示不一样的语言内容;
    框架

  • 制做Dll资源文件,不一样语言调用不一样的Dll;
    ide

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


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

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

    OK,开工。
.net


    VS中新建一个MFC项目:
翻译

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

    选择“基于对话框”,取消“使用 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,本人水平有限,索性无视了,能干活就行。\(≧▽≦)/~

    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=私は言うのは日本語です。(我说的是日语哦)
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

相关文章
相关标签/搜索