在VC工程中添加多语言支持

随着贸易国际化,在软件开发过程中,常会碰到需在现有中文版软件加入多语言支持的情况。由于不同语言版本间的差别通常仅是软件操作界面的不同,为实现多语言支持,使用纯资源DLL是一个不错的解决之道。所谓纯资源DLL是指只包含资源的DLL,譬如:快捷键、对话框、字符串、菜单、工具条、位图、图标、版本信息等等。

具体做法是:利用VC可视化编辑环境为每种语言制作一套资源ID一一对应的资源集并编译生成DLL文件。应用程序初始化时按预设的语言设置选择合适的资源DLL调入,使用资源时依据资源ID进行访问,这样即可实现软件的多语言支持。当然了,应用程序退出前,注意将动态调入的DLL文件占用的资源释放。

现有一个心电图查看程序,工程名为DispECG,语言为中文,现需加入英文支持。下面根据这个具体实例来说明在VC中加入多语言支持的具体实施方法。

 

(一)建立纯资源DLL

a)打开DispECG工程,在当前工作区中添加一个工程。方法:使用菜单File\New…

在VC工程中添加多语言支持 

b)从弹出的对话框中选择“Projects”页面,选择“Win32 Dynamic-Link Library”,工程名设置为“DispECG_ENG”,DispECG工程的工作目录为D:\MyProject\DispECG,DispECG_ENG工程的工作目录为D:\MyProject\DispECG\DispECG_ENG。选择添加到当前工作区(注意Dependency of前的框不选),然后按OK。

在VC工程中添加多语言支持 

c)建立一个简单的DLL工程

在VC工程中添加多语言支持 

选择“A simple DLL project”,然后按“Finish”。此时新建的DispECG_ENG工程中会建立如下几个文件:DispECG_ENG.cpp,StdAfx.cpp,StdAfx.h以及ReadMe.txt。注意没有后缀为*.RC的资源文件。

在VC工程中添加多语言支持 

其中DispECG_ENG.cpp中文件内容如下:

        // DispECG_ENG.cpp : Defines the entry point for the DLL application.

        //

      #include "stdafx.h"

      BOOL APIENTRY DllMain( HANDLE hModule,DWORD  ul_reason_for_call,

                                                    LPVOID lpReserved)

        {

                return TRUE;

        }

 

(二)为DispECG_ENG加入资源并编辑

a)使用Windows资源管理器将DispECG工程下的resource.h和DispECG.rc拷贝到DispECG_ENG工程下,将DispECG工程下的res子目录拷贝到DispECG工程下;

b)使用Windows资源管理器将DispECG_ENG工程下的DispECG.rc改名为DispECG_ENG.rc,将DispECG_ENG\res下的DispECG.rc2改名为DispECG_ENG.rc2;

c)回到VC编辑环境。选择工作区中的文件视(FileView),选择“DispECG_ENG files”,单击右键,选择“Add Files to Project…”将DispECG_ENG工程下的resource.h和DispECG_ENG.rc加入到DispECG_ENG工程。

在VC工程中添加多语言支持 

资源文件DispECG_ENG.rc及资源ID定义文件resource.h加入工程后:

在VC工程中添加多语言支持 

d)修改编辑resource.h和DispECG_ENG.rc

         d.1)将文件头的注释“Used by DispECG_ENG.rc”修改为“Used by DispECG_ENG.rc”

         d.2)修改资源文件DispECG_ENG.rc,将

                  "#include ""res\\DispECG.rc2""  // non-Microsoft Visual C++ edited resources\r\n"

                  "#include ""l.chs\\afxres.rc""          // Standard components\r\n"

                  "#include "" l.chs\\afxprint.rc""        // printing/print preview resources\r\n"

                  修改为

                  "#include ""res\\DispECG_ENG.rc2""  // non-Microsoft Visual C++ edited resources\r\n"

                  "#include ""afxres.rc""          // Standard components\r\n"

                  "#include ""afxprint.rc""        // printing/print preview resources\r\n"

需要说明的是:MFC中含有一些预定义好的资源,不同的语言版本保存在不同的目录下,英文版保存在MFC\Include下,其它语言的版本则保存在Include的子目录中,譬如中文版对应的目录为l.chs,日文版对应l.jpn,韩文版对应l.kor,等等。

e)使用可视化编辑环境编辑对话框、菜单、字符串、版本等语言依赖性资源,将中文版翻译为英文版。当然,如果对资源文件的结构非常了解,可使用文本编辑器对资源文件直接编辑。方法是:使用“File\Open…”打开文件对化框,找到“DispECG_ENG.rc”,注意打开方式选择“Text”。

在VC工程中添加多语言支持 

完成文本的翻译是一项费时耗力的体力活儿,请耐心地仔细地一一做完。

f)修改工程设置,调整编译后DLL文件的存放位置。

由于按照默认的工程设置,DispECG_ENG.DLL的Release版自动生成在D:\My Project\DispECG\DispECG_ENG\Release下,Debug版自动生成在D:\My Project\DispECG\DispECG_ENG\Debug下。为了程序的处理方便,资源DLL最好和应用程序的可执行文件存放在同一目录。为做到这一点,请修改工程配置。

方法:操作菜单“Project\Project Settings…”

在VC工程中添加多语言支持

在“Project Settings”中选择“DispECG_ENG”工程,再选择“Link”页面,将输出文件名由“Release/DispECG_ENG.dll”修改为“../Release/DispECG_ENG.dll”,这样编译后生成的DLL文件将保存在D:\My Project\DispECG\Release下。

调试版也作类似的修改,使得编译后生成的DLL文件将保存在D:\My Project\DispECG\Debug下。

在VC工程中添加多语言支持  

g)编译DispECG_ENG工程,生成发行版和调试版的DispECG_ENG.DLL。

 

(三)在程序中添加多语言支持程序

a) 定义资源名称

在DispECG工程中的StdAfx.h中添加:

        #define CHINESE          0

        #define    ENGLISH              1

b)定义两个全局变量,一个表示当前的语言选择,另一个为资源句柄。

        UINT nLanguage = ENGLISH;

        HINSTANCE hResourceHandle = NULL;

c)添加资源DLL载入程序

在完成应用程序初始化的BOOL CDispECGApp::InitInstance()中添加依据语言选择资源DLL的程序代码。

        nLanguage = GetProfileInt("SETTINGS","LANGUAGE",ENGLISH);

        if (nLanguage != CHINESE)

        {

                CString strFile;

                strFile = "NewDispECG_ENG.dll";

                hResourceHandle = AfxLoadLibrary(strFile);

                ASSERT(hResourceHandle);

                if (hResourceHandle)

                {

                        AfxSetResourceHandle(hResourceHandle);

                }

                else

                {

                        CString strText;

                        strText.Format("%s not found!",strFile);

                        ::MessageBox(NULL,strText,"Error",MB_OK|MB_ICONERROR);

                        return FALSE;

                }

        }

d)添加资源DLL卸载程序

        CDispECGApp::~CDispECGApp()

        {

                if (hResourceHandle)

                AfxFreeLibrary(hResourceHandle);

        }

e) 添加语言选择菜单和命令实现代码。

同步更新各种版本的资源,编辑菜单加入语言选择菜单项。注意同一菜单项不同语言版本的命令ID保持一致。

使用类向导添加命令响应:

        void CDispECGApp::OnSwitchVersion()

        {

                WriteProfileInt("SETTINGS","LANGUAGE",1-nLanguage);

                AfxMessageBox(ID_SWITCH_VERSION);

                TRACE("%s\n%s\n%d\n

                %s\n",m_pszAppName,m_lpCmdLine,m_nCmdShow,m_pszExeName);

        }

 

(四)修改程序代码,根据资源ID调用资源

如果原先的程序未考虑到多语言支持,在显示提示信息时可能使用如下的语句:

        AfxMessageBox("文件无法打开!");

此时应该将诸如"文件无法打开!"此类的字符串添加到字符串资源中,其它语言版本同步更新。同样,注意字符串ID的彼此一致。一个好的习惯是,各版本的资源同步更新后,使用VC开发环境自带的WinDiff.exe对各个版本下的resource.h进行文件内容比较,以确保各语言的资源ID彼此完全一致。

修改完毕后,改用根据资源ID进行资源访问的函数。在实际编程中,最常用到的是对字符串资源的访问以及提示信息的显示,所以下面这些函数在需多语言支持的应用程序中会常被使用:

int AFXAPI AfxMessageBox( UINT nIDPrompt, UINT nType = MB_OK, UINT nIDHelp = (UINT) -1 );

BOOL LoadString( UINT nID );

void Format( UINT nFormatID, ... );

void FormatMessage( UINT nFormatID, ... );

...

至于其它资源,比如对话框、菜单等,通常由系统自动完成加载,无需程序员在软件中进行特别处理。

 

(五)编译调试

posted @ 2011-08-26 10:44  心随灵动  阅读(2030)  评论(0编辑  收藏  举报