软件资源国际化VC教程.docx
《软件资源国际化VC教程.docx》由会员分享,可在线阅读,更多相关《软件资源国际化VC教程.docx(11页珍藏版)》请在冰豆网上搜索。
软件资源国际化VC教程
软件国际化
VC++教程
1软件国际化概述
随着计算机应用的普及,应用软件跨国使用越来越频繁,如何实现应用软件的国际化,成为许多程序员关心的问题。
这种国际化问题相对使用某一种语言的用户来说,就是本地化问题。
本地化的含义比仅仅翻译菜单栏和对话框的文本内容要广泛得多,如特定文化背景的位图和图标对不同的人来说,可能会有不同的含义。
在Windows系统中,应用程序开发者可以通过利用VC动态链接库,只用一套源代码就能简洁地支持多种文字。
本文介绍用VC的资源动态链接库解决国际化问题的具体方法和步骤。
实现技术:
利用VC编程,可以将所有的可见资源封装在一个资源动态链接库中,以简化本地化工作。
一般情况下,资源包含在应用程序中,但也可以将资源与应用程序(即源代码)分离的方式以确定根据语言需求加载不同语言版本的资源动态链接库DLL。
当调用MFC函数比如CString:
:
LoadString或其它LoadIcon时,MFC应用程序框架首先跟踪搜索EXE文件的资源,然后才是DLL和MFC的资源,因此在使用纯资源DLL时候,必须先人为改变资源的搜索顺序,调用AfxSetResourceHandle函数完成资源的引用。
HINSTANCEm_hLangDLL=:
:
LoadLibrary("AppLanguage.dll");
AfxSetResourceHandle(m_hLangDLL);
下面主要从两个典型的Demo实例简要说明软件国际化(以中英文为例)的实现:
1.Demo1
项目名:
MultiLangDemo1,根据调用GetSystemDefaultLangID函数判断系统默认语种,以载入相应语言的资源动态链接库实现界面与系统的自动适应。
2.Demo2
项目名:
MultiLangDemo2,根据界面菜单手动选择语种实现动态更改语言资源,包括图标、菜单、状态栏,以及显示不同区域的数据格式。
2实现步骤
DEMO1
一、创建主工程:
1.运行VC6.0->File->New->Project;选择MFCAppWizard(exe),在右边ProjectName下输入项目名MultiLangDemo1,完成(这里以SingleDocument为例,其他类似)。
2.从项目中移出所有的资源文件,将面板中的MultiLangDemo1.rc,Resource.h,以及ResourceFiles下的所有文件移出(不是从实际文件目录中删除)。
注:
项目中移出资源文件后,主工程必须要加载外部的语言资源DLL,如果没有找到或加载失败的话,程序将无法运行,所以这里也可以选择不移出,保留程序默认的资源(Demo1中已移出,Demo2中没有移出)。
二、创建中、英文语言版(或其他语言)的资源DLL
注:
为统一起见,语言资源DLL名以“主工程名+Res”的格式,不同语言资源以文件夹区分,如本例中中文资源DLL工程(MultiLangDemo1Res)可以创建在主工程MultiLangDemo1下的CHS文件夹中,英文资源DLL工程(MultiLangDemo1Res)可创建在主工程MultiLangDemo1下的ENG文件夹中。
1.运行VC6.0->File->New->Project;选择MFCAppWizard(dll),在右边ProjectName下输入项目名MultiLangDemo1Res,下一步选择RegularDllUsingshareMFCDLL,单击Finish完成创建。
2.删除该工程下的资源文件:
将面板中的MultiLangDemo1Res.rc,Resource.h,以及ResourceFiles下的所有文件移出,然后也将实际目录中的文件删除掉。
3.复制相关资源文件:
将MultiLangDemo1目录下的MultiLangDemo1.rc,Resource.h文件复制到MultiLangDemo1Res工程文件目录下,将MultiLangDemo1/res下的所有文件复制到MultiLangDemo1/res目录下(当然也可以根据需要,选择复制的文件)。
4.将第3步复制的所有文件添加到项目中去。
5.如果是创建英文资源dll,应将相关资源改为英文,将支持的语言改为“英语(美国).",在Project菜单Setting对话框中Resource标签的缺省文字改为"英语(美国).”,同时删除在Resource标签下预处理定义中的"_AFXDLL"。
这样用户的链接库包含通用的MFC资源;
如果是创建中文资源dll,应将相关资源改为中文,将支持的语言改为“中文(中国)",在Project菜单Setting对话框中Link标签ProjectOptions的最后添加”/NOENTRY”。
6.最后编译生成中英文版的动态链接库,并将DLL放置于主工程可执行文件的同级目录,形式为CHS/MultiLangDemo1Res.dll和ENG/MultiLangDemo1Res.dll,OK!
三、修改主工程:
1.在CMultiLangDemo1App类中添加如下成员变量:
private:
HINSTANCEm_hLangDLL;
构造函数中初始化:
CMultiLangDemo1App:
:
CMultiLangDemo1App()
{
m_hLangDLL=NULL;
}
在InitInstance()函数修改资源加载顺序:
BOOLCMultiLangDemo1App:
:
InitInstance()
{
AfxEnableControlContainer();
CStringstrTitle=_T("");
WORDwLangPID=PRIMARYLANGID(:
:
GetSystemDefaultLangID());
switch(wLangPID)
{
//这里是中文环境选择了英文的dll库,只是为了突出效果
caseLANG_CHINESE:
m_hLangDLL=:
:
LoadLibrary("ENG/MultiLangDemo1Res.dll");
strTitle=_T("Untitled-MultiLangDemo1");
break;
caseLANG_ENGLISH:
m_hLangDLL=:
:
LoadLibrary("CHS/MultiLangDemo1Res.dll");
strTitle=_T("无标题-MultiLangDemo1");
break;
}
if(!
m_hLangDLL)
{
AfxMessageBox(_T("无法装载资源链接库!
"));
returnFALSE;
}
AfxSetResourceHandle(m_hLangDLL);
…
//更改标题栏,dll资源中没有该项,只有手动更改
m_pMainWnd->SetWindowText(strTitle);
}
别忘了ExitInstance()函数释放掉加载的dll资源
intCMultilanguageApp:
:
ExitInstance()
{
if(m_hLangDLL)
AfxFreeLibrary(m_hLangDLL);
returnCWinApp:
:
ExitInstance();
}
最后编译运行!
如下图为中英文版本的实现界面:
DEMO2
Demo2项目创建的前两步(即主工程与中、英文语言版资源DLL的创建)与Demo1一样(只是主工程的资源文件未移出),项目名为MultiLangDemo2,在第三步修改主工程方面有些差异:
修改主工程:
1.首先在中文dll和英文dll中分别增加菜单项:
语言(Language),下拉菜单中文(Chinese)和英文(English),下拉菜单ID分别为:
ID_LANGUAGE_CHINESE、ID_LANGUAGE_ENGLISH(确保同一ID,Value值一样)。
如下图所示:
并分别添加各自的菜单响应函数OnLanguageEnglish和OnLanguageChinese,
voidCMainFrame:
:
OnLanguageChinese()
{
//TODO:
Addyourcommandhandlercodehere
SetLanguage(Chinese);
}
voidCMainFrame:
:
OnLanguageEnglish()
{
//TODO:
Addyourcommandhandlercodehere
SetLanguage(English);
}
2.在类CMainFrame头文件中定义如下:
private:
CMenu*m_pMenuNew;
enumLANGUAGES{Chinese,English};
HINSTANCEm_hInstChinese,m_hInstEnglish;
LANGUAGESm_nLanguage;
public:
voidGetDate(CString&strDate);
private:
voidSetLanguage(LANGUAGESnLanguage);
实现文件中,SetLanguage函数完成资源库的加载:
voidCMainFrame:
:
SetLanguage(LANGUAGESnLanguage)
{
CStringstrBuffer=_T("");
HINSTANCEhInst=NULL;
LCIDlcid=NULL;
m_nLanguage=nLanguage;
switch(nLanguage)
{
caseChinese:
if(!
m_hInstChinese)
//加载CHS文件夹下的语言资源库
m_hInstChinese=LoadLibrary(_T("CHS/MultiLangDemo2Res.dll"));
//根据语种设置窗口标题
((CMultiLangDemo2Doc*)GetActiveDocument())->SetTitle("无标题");
hInst=m_hInstChinese;
break;
caseEnglish:
if(!
m_hInstEnglish)
m_hInstEnglish=LoadLibrary(_T("ENG/MultiLangDemo2Res.dll"));
((CMultiLangDemo2Doc*)GetActiveDocument())->SetTitle("Untitled");
hInst=m_hInstEnglish;
break;
}
if(hInst)
AfxSetResourceHandle(hInst);
else
AfxMessageBox("加载语言库失败");
//设置菜单
CMenu*pMenuCurrent=GetMenu();
m_pMenuNew=newCMenu;
if(pMenuCurrent->m_hMenu!
=m