此随笔中主要内容来自http://blog.csdn.net/china_hxx/article/details/10066655,原出处不详。

以下内容基于VC 6.0。要实现界面多语言化,必须要先配置项目使其支持Unicode编码,文章《VC下的Unicode编程》 对此有详细介绍。

首先创建一个基于MFC的工程,在选择语言时选择 中文[简体,中国]。

项目框架选择对话框、单文档和多文档都可以,这里就选个基于对话框的吧,然后立即修该项目属性使其支持Unicode。

MFC已经为我们加入了一些资源,包括2个对话框、1个String Table等。为了节省空间修改了对话框的大小。

现在项目中的资源情况如下:

然后再新建一个DLL项目,为了方便管理可以将其添加到当前工作空间中。

立即修改此DLL项目使其支持Unicode,然后设置项目依赖性(Project->Dependencies…) ,资源DLL要在exe项目之前编译:

为了将生成的资源DLL自动拷贝到exe项目执行目录下,还需要修改DLL项目的Post-build Step:

然后将主项目目录下的res文件夹、resource.h、TestMultiLang.rc文件拷贝到ResENG项目目录下,res文件夹和resource.h直接替换,将ResENG.rc删除后再将TestMultiLang.rc重命名为ResENG.rc。

切换到资源视图就会发现这两个项目的资源内容是一样的了,将ResENG项目的资源更改为英文如下:

为了让程序在启动的时候加载英文语言资源,需要在CTestMultiLangApp::InitInstance()函数中Dlg创建之前添加如下语句:

HINSTANCE hLanguageDll = AfxLoadLibrary(_T("ResENG")); if (hLanguageDll) AfxSetResourceHandle(hLanguageDll);

最后重新编译TestMultiLang项目,运行就会发现对话框已经是英文界面了 :)

动态实现语言切换

以上程序仅为示例,为了能使程序自动选择合适的语言,还需要做许多工作。比如要在程序中添加程序语言切换菜单或语言选择下拉列表框,并将用户喜好保存在ini配置文件中,然后在程序启动时自动读取此ini文件加载相应的资源DLL;如果用户未设置语言,则默认根据操作系统语言加载合适资源,如果不存在针对此语言的资源DLL,就使用最国际化的语言——英语。

在stdafx.h中做如下定义:

#define CHINESE    0
#define ENGLISH 1

在CTestMultiLangApp类中添加private变量 int m_Lang, 用来保存当前语言类型是CHINESE,还是ENGLISH。

在CTestMultiLangApp类中添加public方法GetLang用于返回当前语言类型。

int CTestMultiLangApp::GetLang(void)
{
return m_Lang;
}

根据配置加载相应资源的DLL包装成一个函数如下:

void CTestMultiLangApp::LoadLanguage(void)
{
CString strDLL;
HINSTANCE hLanguageDll, hLanguageNow; //保存本身的资源句柄
static HINSTANCE hOriginalHandle = ::AfxGetResourceHandle(); //读取ini配置文件
CString strFileName = _T("Language.ini");
if (PathFileExists(strFileName))
{
int lang = ;
CFile file;
file.Open(strFileName, CFile::modeRead | CFile::typeBinary);
file.Read(&lang, sizeof(lang));
file.Close();
m_Lang = lang;
} //根据用户喜好来设置
if (m_Lang == ENGLISH)//英文
hLanguageDll = ::AfxLoadLibrary(_T("ResENG"));
else if (m_Lang == CHINESE)//中文
hLanguageDll = hOriginalHandle;
else
{
//用户未指定,则根据系统选择合适语言,默认为英文
WORD wLangPID = PRIMARYLANGID(GetSystemDefaultLangID());
if (wLangPID == LANG_CHINESE)
hLanguageDll = hOriginalHandle;
else if (wLangPID == LANG_ENGLISH)
hLanguageDll = ::AfxLoadLibrary(_T("ResENG"));
else
hLanguageDll = ::AfxLoadLibrary(_T("ResENG"));
}
//保存已加载的资源DLL句柄
hLanguageNow = ::AfxGetResourceHandle();
//加载新的资源DLL
if(hLanguageDll)
::AfxSetResourceHandle(hLanguageDll);
//释放之前加载的资源DLL
if (hLanguageNow != hOriginalHandle)
FreeLibrary(hLanguageNow);
}

因为在切换界面语言的过程中需要频繁地销毁和创建对话框,所以我们也把创建对话框的代码包装成一个函数:

void CTestMultiLangApp::OpenWindow(void)
{
CTestMultiLangDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
}

现在在InitInstance()函数里简单得调用一下这两个函数就可以了:

BOOL CTestMultiLangApp::InitInstance()
{
AfxEnableControlContainer(); #ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif LoadLanguage(); if (!OpenWindow())
return FALSE; return FALSE;
}

然后要实现用户界面的语言选择消息响应函数。该函数要将用户的选择保存到ini文件里,销毁当前窗口,然后再重新加载资源并创建新的窗口:

void CTestMultiLangDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CTestMultiLangApp*pApp = (CTestMultiLangApp*)AfxGetApp(); int old_Lang = pApp->GetLang();
int new_Lang = ;
if(old_Lang == ENGLISH)
new_Lang = CHINESE;
else
new_Lang = ENGLISH; CFile file;
file.Open(_T("Language.ini"), CFile::modeWrite | CFile::modeCreate | CFile::typeBinary);
file.Write(&new_Lang, sizeof(new_Lang));
file.Close(); //销毁当前窗口
pApp->m_pMainWnd = NULL;
this->DestroyWindow(); //创建新的窗口
pApp->LoadLanguage();
pApp->OpenWindow();
}

上面这段代码中pApp->m_pMainWnd = NULL这一句是关键,它切断了销毁当前程序消息向上的路由,因此进程不会被销毁,才有了机会重新创建新的窗口。如果项目是基于单文档/多文档的程序的话,还要加一句pApp->m_pDocManager = NULL才可以。
    重新编译项目,现在语言就可以动态切换了。

继续添加其他语言

如果项目不仅要支持中英文这两种语言,比如还需要支持德语,这里介绍两种方法来实现。

第一种方法显而易见————新建一个资源DLL项目。理论上这是可行的,但是有个棘手的问题:如果需要支持的语言很多,那么对程序资源的任何更改都需要同步更新到其他所有资源项目!
    第二种方法是借用工具,由一个资源DLL制作出其他各语言版本的资源DLL。这个工具软件会把资源DLL中的字符串、对话框、菜单项等资源提取出来并保存到一个po文件里,之后使用poedit就可以进行翻译了。翻译完成后再根据此po文件和原资源DLL生成新的资源DLL。
    工具软件截图如下:

MFC多国语言——资源DLL的更多相关文章

  1. MFC多国语言——资源副本

    此随笔主要参考了http://www.cnblogs.com/xianyunhe/archive/2011/09/02/2163842.html 为软件提供多国语言的支持的具体实现方法有很多,但基本原 ...

  2. MFC多国语言——配置文件

    前段时间,因工作需要,本地化了一个英文版本的产品. 在网上查阅了若干资料,在此进行一个简单的整理. 在MFC程序中,实现多国语言的方式很多,我们选择的是使用配置文件的方法. 在通过配置文件方式实现多国 ...

  3. 高质量,高效率的多国语言软件开发(Web/PC/Mobile),使用接口约束/调用不同语言资源

    偶然间翻出了几年前写的一个小程序,把当时的资料整理整理分享一下. 当时为了给自己的软件实现多国语言功能,而开发的辅助工具:SE String Resource. 这是当时基于自己另一款 IDE 软件抽 ...

  4. WPF应用程序支持多国语言解决方案

    原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...

  5. Delphi如何实现多国语言

    Delphi里的多语言处理方法都一样, 都是通过资源DLL的形式进行加载处理. Delphi在加载form数据的时候会判断当前的系统语言,然后根据语言加载不同的资源dll, 来实现多国语言的功能. 下 ...

  6. 解析大型.NET ERP系统 多国语言实现

    实现多国语言有许多种实现方案,无外乎是一种字符串替换技术,将界面控件的文本标签替换成相应语言的文字..NET Windows Forms实现多国语言的方法有以下几种: 1 .NET的方案,使用资源文件 ...

  7. WinCE6.0多国语言软键盘

    N久以前写过一篇<WinCE下自定义的大软键盘>,这个自定义软键盘就是为RM905a+项目来做的.RM905a+的系统分辨率是640*480,WinCE原生键盘小的太小,大的又太大.所以就 ...

  8. 引擎设计跟踪(九.8) Gizmo helper实现与多国语言

    最近把gizmo helper的绘制做好了. 1.为了复用代码,写了utility来创建sphere, cube, cylinder, plane, ring(line), circle(solid) ...

  9. 【软件多国语言】一个demo

    之前上学的时候做过一个东西,需要中英文软件界面,并且需要随时可以切换,当时是师妹来做的,用的最直接也是最笨的办法, what? if(中文) { button1.Text = "花姑娘&qu ...

随机推荐

  1. MPlayer源代码分析

    http://blog.csdn.net/leixiaohua1020/article/details/11885509 一.Mplayer支持的格式 MPlayer是一个LINUX下的视频播放器,它 ...

  2. python的__init__和__new__

    本文所有实例代码在python3.7下 一.__new__和__init__区别 1.__new__先于__init__执行;__new__是相当于其他OOP语言的构造方法,负责创建实例:之后,__i ...

  3. win7多重网络之默认网关问题

    如果有谁做硬件的在用MAC,跟我讲一声好用不好用...有常用软件清单最好.windows已经用的无力吐槽了. 机子上有两块网卡,一块有线一块无线,有线的连接内部网络,无线连接外部网络, 问题描述: 内 ...

  4. openerp js调用Python类方法

    转自:http://blog.csdn.net/kuaileboy1989/article/details/42875497 js调用.py文件中定义的类 形式如下: //创建product.prod ...

  5. 《The Story of My Life》Introductiom - A Journey Of Discovery

    "I do not object to harsh criticism," said Helen Keller, "so long as I am treated lik ...

  6. 使用 WinEdt 来写中文文章or 建模论文

    找了几乎两个小时…… 后来发现… WinEdt 是可以用来写中文文章的…而并非只能英文文章或演示文稿… \documentclass{article} \usepackage{CJK} \begin{ ...

  7. Js日常笔记之this

    在javascript中自己创建构造函数时可以利用this来指向新创建的对象上.这样就可以避免函数中的this指向全局了,如下 var x = 2; function test(){ this.x = ...

  8. LNMP架构二

    Nginx默认虚拟主机 1.首先修改nginx.conf文件,删除server及下面的,在http最后添加include vhost/*.conf; (指定虚拟主机目录,并读取以.conf结尾的文件) ...

  9. Jumpserver web界面跳板机

    Jumpserver.org 普通用户 仪表盘 查看主机 上传下载 访问官网 欢迎使用Jumpserver开源跳板机系统 帮助 Log out 查看资产 仪表盘 资产管理 查看资产 主机详细信息列表 ...

  10. 0xffff0000颜色表示

    0xffff0000表红色,意思是: A:ff=255 R:ff=255 G:00=0 B:00=0 可如下将(255,0,0,255)转成0xffff0000并输出: inline DWORD RG ...