澳门新葡亰网址下载C++ Builder创建和调用dll中的资源

by admin on 2020年1月31日

cpp 中定义
int g_currentLanguage = LG_ENGLISH; //
定义一个全局变量,用来标示当前使用的语言
HINSTANCE hinsDll; // 定义一个全局实例句柄,用来存储 DLL 的实例句柄
.h 中声明
extern int g_currentLanguage;
extern HINSTANCE hinsDll;
enum{ // 定义语言的枚举值
LG_ENGLISH = 0,
LG_CHINESE = 1
};
切换使用的语言
void CMainFrame::OnMenuitemChinese() // 中文
{
g_currentLanguage = LG_CHINESE;
FreeLibrary(hinsDll);
hinsDll = LoadLibrary(“LG_CHINESE.DLL”);
if (hinsDll){
    AfxSetResourceHandle(hinsDll);
    HMENU hMenu = ::LoadMenu(hinsDll,   
MAKEINTRESOURCE(IDR_MAINFRAME));
    m_menu.Detach();
    m_menu.Attach(hMenu);
    SetMenu(&m_menu);
}else{ // Error
//    MessageBox(“Error”);
}
}

MS Windows操作系统是一个世界上广泛使用的操作系统,对于不同语种的国家MS
Windows有相应语种的版本。在不同语种的Windows平台上应该运行相应语种的应用程序。也就是说程序的用户界面(如菜单、对话框、状态条)中的提示文字应该使用和Windows操作系统所使用的语种一致。当然英语用户界面的程序可以运行在其它语言平台上,但比较复杂的程序或多或少都有问题,如对话框的尺寸不对,特殊的ASCII字符显示为文字,输入字符串可能会导致死机等。如果不一致却还想使用,则需要动态翻译软件。例如,在英文Windows平台上运行中文版的MS
Office就需要像中文之星或四通利方这样的中文动态翻译软件。

程序开发中经常会用到一些图标、图片、光标、声音等,我们称它们为资源(Resource)。当多个窗口用到同样的资源时,可以将这些公共的资源放到一个dll文件里调用,这样,由于定位资源比在磁盘中定位文件花费时间少,所以应用程序执行会更快。多种资源放在一个文件中,减少了图标、图片、光标、声音等文件数量,从而可以减小应用程序的大小。不用怕用户在使用过程中的不小心而损坏了资源文件致使程序无法正常运行。当然也可以不编为dll,而和应用程序放一起,用到时再LoadFromFile,但这样容易丢失,一旦丢失了将影响程序的运行。

在使用vc写简繁体通用程序时,对实现菜单、界面、Tooltips等的文字时无法实现通用。如果写简体和繁体各一套程序,那肯定不现实。查找所有资料和文章都只能实现菜单的多语言,且使用起来也不方便;并且无法实现界面、Tooltips等的多语言。因而,采用纯资源的DLL文件来实现多语言。
        纯资源DLL文件实现步骤如下:
       
(1)创建简繁体MDI或SDI程序后,把VC框架自动创建的.rc,.rc2,.ico,.bmp等文件从程序框架中删除;
        (2)使用Projects的Win32 Dynamic-Link
Library分别创建简繁体纯资源dll文件,把由MDI或SDI程序创建的.rc,.rc2,.ico,.bmp等文件加入到该工程文件中;
        (3)在Project菜单项选择Settings然后选择Project
Settings的Link标签;然后在Project
Options框内输入/NOENTRY。编译后就产生纯资源DLL文件;
       纯资源DLL文件加入没有任何资源的MDI或SDI程序,其步骤如下:
        (1)在主应用程序类的.h文件中定义protected 的 HINSTANCE
类型变量(如:mhInstMenu);     
       
(2)在主应用程序类的.cpp文件::InitInstance()函数过程中添加下面代码:
        mhInstMenu = ::LoadLibrary(“Menu.dll”);    //
Menu.dll为多语言纯资源的dll文件
      if (mhInstMenu == NULL)  
      {  
          return FALSE; // failed to load the localized resources  
      }  
      else {  
          AfxSetResourceHandle(m_hInstMenu); // get resources from
the DLL  
      }
      
(3)在主应用程序类的.cpp文件::ExitInstance()函数过程中添加下面代码:
        FreeLibrary(mhInstMenu);

  当前国内使用的MS
Windows在语种上划分主要有简体中文版和英文版两种。为了让开发的软件能在这两种平台上使用,提出了三种解决方案:第一种解决方案是仅编写中文界面的程序。在中文Windows上程序可以运行(这里的运行是指程序界面不出现乱码),在英文Windows上依靠中文之星或四通利方这样的中文动态翻译软件也可以运行。第二种解决方案是针对中文版和英文版各编一个程序,即在第一种方案的基础上增加了英文版,这样做有两点好处:一是英文Windows平台上运行英文版的软件比英文Windows平台上运行中文版的软件稳定,因为没有像中文之星或四通利方这样的中文动态翻译软件的参与。第三种解决方案是自动根据操作系统的语种选择相应的界面语种。也就是说,同一个软件在中文Windows上显示中文界面,在英文Windows上显示英文界面。这种方案相对于第二种方案的好处在于:程序不用做英文版和中文版两个版本,只要一个版本就可以了,对于用户来说是很方便的。在这三种方案中,前一种是后一种的基础,后一种实现了,前一种也就已经实现了。下面将从易到难介绍三种方案实现的步骤和要点。

下面介绍如何将资源装入dll文件并在应用程序中调用。

 

  解决方案一、自动生成中文界面框架

一、创建资源文件

  Visual
C++6.0版本中可以使用APPWIZARD自动生成具有基本中文界面的WIN32应用程序。使用APPWIZARD时,在自动生成的第一个步骤中,将资源类型选择为简体中文就可以了,可参见图1。其余选项都不涉及语种问题,根据应用程序的具体情况进行选择即可。然后在此基础上作进一步的软件开发工作。

首先将要用到的资源放在同一个文件夹下,新建一记事本,将后缀名改为.rc(此处暂以rc.rc的文件名为例)。注意事项:创建的资源文件名不要和工程名相同,因为bcb创建工程时会自动创建一个和工程名相同的资源文件,并且最好将资源文件保存到和工程文件同一个文件夹中。打开创建的rc.rc文件并按照如下格式写入资源信息:

  如果你在一边读文章一边上机实际操作,可能会发现一个问题:不论你怎样设定VisualC++5.0的安装程序的选项,资源类型仅会支持英语、德语、法语、西班牙语和意大利语这五种语言。于是你可能会怀疑你所用的Visual
C++5.0版本有问题。实际上并不是Visual
C++5.0版本有问题,而是需要从安装盘上手工拷贝一些文件。所需文件在Visual
Studio97软件包的第三张包含Visual
C++5.0的光盘上。在目录DEVSTUDIO/SHAREDIDE/BIN/IDE下有几个以APPWZ开头的动态链接库(扩展名为dll的文件)。在这些动态链接库中,一个动态链接库提供对一种语言的支持。其中的APPWZCHS.DLL就是支持简体中文的文件。将其拷贝到安装Visual
C++5.0的硬盘上相同名字的目录下即可。重新开始自动生成步骤,在自动生成的第一个步骤中,在资源类型选择中将出现简体中文支持。

资源标识符 关键字 资源文件名

  解决方案二、支持多种语言

格式说明:

  没有必要从头开发一个英文版。事实上,在现有中文版的基础上生成英文版并不复杂。工作量在于修改资源,程序的代码不用改变。

① 资源标识符:程序中调用资源时的特定标号,由自己定义。

  图2左边的ResourceView窗口中,同时存在着中英文两种资源,在中文资源的后面标注有“Chinese(P.R.C.)”以示区别。为了保证程序代码不变,相同界面元素的两种语言版本下的标识符必须相同。例如,产品介绍对话框的英文资源的标识符为IDD_ABOUTBOX,中文资源的标识符也应该是IDD_ABOUTBOX。可以用COPY操作对资源进行复制,然后修改语种再修改标识符。
(在资源中用InsertCopy COPY一份资源)

② 关键字:标识资源文件类型;例如:

  ResourceView提供的管理功能并不全面,还需要直接编辑资源文件RESOURCE.RC来完成全部任务。经过对RESOURCE.RC文件的研究,发现文件中使用编译控制开关来实现多语言支持。  ……

Wave : 资源文件是声音文件;

  //////////////////////////////////////////////////////////////////////////

RCDATA: JPEG文件;

  // Chinese (P.R.C.)
resources

AVI : AVI动画;

  #if !defined(AFX_RESOURCE_DLL)
|| defined(AFX_TARG_CHS)

ICON : 图标文件;

  #ifdef _WIN32

BITMAP: 位图文件;

  LANGUAGE LANG_CHINESE,
SUBLANG_CHINESE_SIMPLIFIED

CURSOR: 光标文件;

  #pragma code_page(936)

RMI : RMI音乐文件;

  #endif //_WIN32

MIDI : MIDI音乐文件

  //////////////////////////////////////////////////////////////////////////

EXEFILE:可执行文件

  // Dialog

JPEG: jpg图片

  ……

EXEFILE: exe可执行文件

  /////////////////////////////////////////////////////////////////////////

③ 资源文件名:加入的资源文件名(要带扩展名,可以带路径名构成全文件名);

  // Menu


举例:假如有三个图形:“open.bmp”、“save.bmp”、“ico.ico”,奖在rc.rc文件里写下如下信息:

  ……

OPEN   BITMAP   open.bmp

  //////////////////////////////////////////////////////////////////////////

SAVE   BITMAP   save.bmp

  // Icon

ICO    ICON      ico.ico

  ……

资源文件名可以不加引号,也可以加引号。保存rc.rc。

  //////////////////////////////////////////////////////////////////////////

二、创建dll工程

  // Bitmap

1、在C++ Builder中新建DLL Wizard,在弹出的对话框上选择Use
VCL,如下图:

  ……

 

  //////////////////////////////////////////////////////////////////////////

 

  // Toolbar

澳门新葡亰网址下载 1

  ……

 

  #ifdef APSTUDIO_INVOKED

点击“OK”后完成创建,并保存到上述资源文件所在文件夹。

  /////////////////////////////////////////////////////////////////////////////

2、点菜单上的“工程”/“添加到工程”(或Shift+F11),选择上述写好的rc.rc文件。

  // TEXTINCLUDE

3、在Unit1.cpp里添加以下两个函数:

  1 TEXTINCLUDE DISCARDABLE

//—————————————————————————–

  BEGIN

//加载bmp位图

  ”resource.h/0″

extern  “C” __declspec(dllexport)  HBITMAP  __stdcall 
GetBitmap(AnsiString   rcName);

  END

HBITMAP  __stdcall  GetBitmap(AnsiString  rcName)

  2 TEXTINCLUDE DISCARDABLE

{ return   ::LoadBitmap(HInstance, rcName.c_str()); }

  BEGIN

//加载ico图标

  ”#include “”afxres.h””/r/n”

extern “C” __declspec(dllexport) HICON  __stdcall
GetIcon(AnsiString);

  ”/0″

HICON __stdcall GetIcon(AnsiString  rcName)

  END

  { return   ::LoadIcon(HInstance, rcName.c_str());

  3 TEXTINCLUDE DISCARDABLE

  }

  BEGIN

//———————————————————————–

  ”#define _AFX_NO_SPLITTER_RESOURCES/r/n”

其中rcName为资源标识符。

  ”#define _AFX_NO_PROPERTY_RESOURCES/r/n”

4、保存工程,编译(Alt+F9),并生成Project1(Ctrl+F9)。现在便得到了Project1.dll。

  ”/r/n”

三、调用dll中的资源

  ”#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)/r/n”

重新新建一工程(Application),在Form1上加两个BitBtn,并将其Caption属性分别设为“打开”和“存储”,在Form1的OnShow函数下写下如下代码:

  ”#ifdef _WIN32/r/n”

//—————————————————————————

  ”LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED/r/n”

void __fastcall TForm1::FormShow(TObject *Sender)

  ”#pragma code_page(936)/r/n”

{

  ”#endif/r/n”

HBITMAP __stdcall (*GetBitmap)(AnsiString); //定义函数原型

  ”#include
“”res//sample.rc2″” // non-Microsoft Visual C++ edited
resources/r/n”

HICON __stdcall (*GetIcon)(AnsiString); //定义函数原型

  ”#include
“”l.chs//afxres.rc”” // Standard components/r/n”

HINSTANCE Hdl;

  ”#include
“”l.chs//afxprint.rc”” // printing/print preview resources/r/n”

Hdl = ::LoadLibrary(“Project1.dll”); //载入DLL

  ”#include
“”l.chs//afxolecl.rc”” // OLE container resources/r/n”

if(Hdl != NULL)

  ”#include
“”l.chs//afxolesv.rc”” // OLE server resources/r/n”

 {

  ”#endif/0″

GetBitmap=(HBITMAP __stdcall
(*)(AnsiString))::GetProcAddress(Hdl,”GetBitmap”);

  END

//取函数入口地址

  #endif // APSTUDIO_INVOKED

 if(GetBitmap!= NULL)

  ……

    {BitBtn1->Glyph->Handle=GetBitmap(“OPEN”);

  #endif // Chinese (P.R.C.) resources

     BitBtn2->Glyph->Handle=GetBitmap(“SAVE”);

  /////////////////////////////////////////////////////////////////////////////

     }

  // English (U.S.) resources

 GetIcon=(HICON  __stdcall
(*)(AnsiString))::GetProcAddress(Hdl,”GetIcon”);

  #if !defined(AFX_RESOURCE_DLL)
|| defined(AFX_TARG_ENU)

//获取函数入口地址

  #ifdef _WIN32

   if(GetIcon!= NULL)

  LANGUAGE LANG_ENGLISH,
SUBLANG_ENGLISH_US

     {Icon->Handle= GetIcon(“ICO”); }//改变窗体的图标

  #pragma code_page(1252)

    ::FreeLibrary(Hdl);

  #endif //_WIN32

 }

  //////////////////////////////////////////////////////////////////////////

else {MessageBox(Handle,”不能载入资源Project.dll!”,”错误”,48);}

  // Dialog

}

  ……

//—————————————————————————

  /////////////////////////////////////////////////////////////////////////

然后运行,则窗体的图标变为资源中的图标,两个BitBtn也加载了图形。

  // Menu

到此已完成dll中资源的调用功能。

  ……

四、其它资源

  //////////////////////////////////////////////////////////////////////////

上述只介绍了位图和图标的存取,分别用到LoadIcon和LoadBitmap,对于其它资源的存取如下:

  // Icon

位图:

  ……

mage1->Picture->Bitmap->Handle=LoadBitmap(HInstance,’资源标识符’);

  //////////////////////////////////////////////////////////////////////////

或Image1->Picture->Bitmap->LoadFromResourceName(HInstance,’资源标识符’);

  // Bitmap

鼠标:

  ……

Screen->Cursors[1]=LoadCursor(HInstance,’资源标识符’);

  //////////////////////////////////////////////////////////////////////////

Screen->Cursors[2]=LoadCursor(HInstance,’资源标识符2′);

  // Toolbar

Form1->Cursor=1; //仅用于Form1

  ……

Image1->Cursor=2;//仅用于Image1

  /////////////////////////////////////////////////////////////////////////////

Screen->Cursor=1;// 整个应用程序上都改变

  // TEXTINCLUDE

在这里定义了两套鼠标,使用的话需要在rc文件种定义两次鼠标资源文件。

  1 TEXTINCLUDE DISCARDABLE

图标:

  BEGIN

Application->Icon->Handle = LoadIcon(HInstance,’资源标识符’);

  ”resource.h/0″

AVI文件

  END

在工程中添加一TAnimate控件(在Win32控件面板上),在需要的地方加入:

  2 TEXTINCLUDE DISCARDABLE

Animate1->ResName=”MyAvi” ; //资源标识

  BEGIN

Animate1->Active = True ;

  ”#include “”afxres.h””/r/n”

实践中的一点结果:并不是所有的AVI资源都可以用TAnimate组件来播放,编定程序时要测试。遇到不能用TAnimate组件来播放的AVI资源,则可以把它从资源文件里分离出来,再使用相应的播放组件比如TMediaPlayer来播放。使用完再把分离出来的临时文件删除掉。

  ”/0″

Wave文件

  END

#Include”MMSystem.h”

  3 TEXTINCLUDE DISCARDABLE

char *wav_handle ;

  BEGIN

  HRSRC h = FindResource(HInstance,”MyWav”,”WAV”);

  ”#define _AFX_NO_SPLITTER_RESOURCES/r/n”

  HGLOBAL h1 = LoadResource(HInstance, h);

  ”#define _AFX_NO_PROPERTY_RESOURCES/r/n”

  wav_handle = (char *)LockResource(h1);

  ”/r/n”

 PlaySound(wav_handle,NULL, SND_MEMORY | SND_ASYNC);

  ”#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)/r/n”

  FreeResource(h1);

  ”#ifdef _WIN32/r/n”

//PlaySound(wav_handle,NULL, SND_MEMORY | SND_ASYNC|SND_LOOP);

  ”LANGUAGE 9, 1/r/n”

 //重复播放

  ”#pragma code_page(1252)/r/n”

JPEG图片

  ”#endif/r/n”

#include”jpeg.hpp”

  ”#include “”res//sample.rc2″” // non-Microsoft Visual C++ edited
resources/r/n”

TJPEGImage *Fjpg=new TJPEGImage();

  ”#include “”afxres.rc”” // Standard components/r/n”

TResourceStream *FStream=new
TResourceStream((int)HInstance,”MyJpg”,”JPEG”);

  ”#include “”afxprint.rc”” // printing/print preview resources/r/n”

Fjpg->LoadFromStream(FStream) ;

  ”#include “”afxolecl.rc”” // OLE container resources/r/n”

Image2->Picture->Bitmap->Assign(Fjpg);

  ”#include “”afxolesv.rc”” // OLE server resources/r/n”

EXE文件

  ”#endif/0″

先分离出来,再执行。

  END

SetCurrentDir(path); //设置当前工作目录

  #endif // APSTUDIO_INVOKED

TResourceStream &res = *new TResourceStream( (int)HInstance,
AnsiString(“process”),”EXEFILE” ) ;

  ……

String file=path+”//process.exe”;

  #endif // English (U.S.) resources

 res.SaveToFile(file);

  /////////////////////////////////////////////////////////////////////////////

delete &res;

  #ifndef APSTUDIO_INVOKED

STARTUPINFO si;

  /////////////////////////////////////////////////////////////////////////////

PROCESS_INFORMATION pi;

  // Generated from the TEXTINCLUDE
3 resource.

ZeroMemory(&si,sizeof(si));

  #define
_AFX_NO_SPLITTER_RESOURCES

si.cb=sizeof(si);

  #define
_AFX_NO_PROPERTY_RESOURCES

ZeroMemory(&pi,sizeof(pi));

  #if !defined(AFX_RESOURCE_DLL)
|| defined(AFX_TARG_CHS)

CreateProcess(file3.c_str(),NULL,NULL,NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi);

  #ifdef _WIN32

注意,这里CREATE_NO_WINDOW为不显示窗口,根据需求设置不同的参数,请参照MSDN。

  LANGUAGE LANG_CHINESE,
SUBLANG_CHINESE_SIMPLIFIED

其它资源

  #pragma code_page(936)

可以把资源文件中的源文件分离出来,建立一个临时的物理文件存在于应用程序路径下,然后可以用相应类型的组件来或方法来使用该文件。当程序退出时再不忘把该临时文件删除掉。

  #endif

例如:

  #include “res/sample.rc2” //
non-Microsoft Visual C++ edited resources

 string  tmpDirectory ;

  #include “l.chs/afxres.rc” //
Standard components

TResourceStream  myres ;

  #include “l.chs/afxprint.rc” //
printing/print preview resources

tmpDirectory = ExtractFilePath(paramstr(0));

  #include “l.chs/afxolecl.rc” //
OLE container resources

if (FileExists(tmpDirectory + “//Music1.RMI”))

  #include “l.chs/afxolesv.rc” //
OLE server resources

myres = TResourceStream->Create(hinstance,”music1″,”RMI”);

  #endif

myres->SaveToFile(tmpDirectory +
“Music1.RMI”);//从资源文件中分离出来

 

myres->Free;

  #if !defined(AFX_RESOURCE_DLL)
|| defined(AFX_TARG_ENU)

程序退出的时候删除:

  #ifdef _WIN32

if(FileExists(tempDirectory + ‘//music1.RMI’))

  LANGUAGE LANG_ENGLISH,
SUBLANG_ENGLISH_US

DeleteFile(tempDirectory + ‘//music1.RMI’);

  #pragma code_page(1252)

 

  #endif

结论:这篇文章是网上的。我照着做了一遍,遇到以下问题:

  #include “res/sample.rc2” //
non-Microsoft Visual C++ edited resources

1、创建DLL Wizard 的程序,编译时报错:invalid bitmap format

  #include “afxres.rc” // Standard
components

2、即便Remove 掉 rc资源,编译程序无错,但是没有dll 和 lib  文件生成
,只有obj文件

  #include “afxprint.rc” //
printing/print preview resources

3、测试dll 程序 编译报错:nonportable pointer comparsion

  #include “afxolecl.rc” // OLE
container resources

期待网友帮忙,非常感谢!

  #include “afxolesv.rc” // OLE
server resources

  #endif

  /////////////////////////////////////////////////////////////////////////////

  #endif // not
APSTUDIO_INVOKED

  以上代码中在 #if
!defined(AFX_RESOURCE_DLL) ||
defined(AFX_TARG_CHS)宏定义后面为中文资源,在#if
!defined(AFX_RESOURCE_DLL)||
defined(AFX_TARG_ENU)宏定义后面为英文资源。应该保证中英文资源中都有TEXTINCLUDE段和#ifndef
APSTUDIO_INVOKED段。 这样MFC(Microsoft
Fundermental Class)缺省资源才会被包含。
对于中文资源来讲,这些额外资源的路径应加上l.chs目录名。

  在编译生成可执行文件时,如果生成中文版本,则在Project
Settings对话框中应按图3所示进行设置:在Preprocessor
definitions编辑框中加入AFX_TARG_CHS和AFX_RESOURCE_DLL的定义,并且Language选择框中应选择Chinese(P.R.C.)。如果生成英文版本,则在Project
Settings对话框中应设置如下:在Preprocessor
definitions编辑框中加入AFX_TARG_ENU和AFX_RESOURCE_DLL的定义,并且Language选择框中应选择English(United
States)。

其中AFX_TARG_CHS与936定义了资源文件的简体中文属性。
英文属性中为AFX_TARG_ENU与1252,
日文属性中为AFX_TARG_JPN与932,
繁体中文属性中为AFX_TARG_CHT与950。
翻译时必须改成相应的语言属性。

注意下面两句也应改动:
#include “l.chs//afxres.rc” // Standard components
#include “l.chs//afxprint.rc” // printing/print preview resources
英文为:
#include “afxres.rc” // Standard components
#include “afxprint.rc” // printing/print preview resources
日文为:
#include “l.jpn//afxres.rc” // Standard components
#include “l.jpn//afxprint.rc” // printing/print preview resources
繁体中文为:
#include “l.cht//afxres.rc” // Standard components
#include “l.cht//afxprint.rc” // printing/print preview
resources

  还有一点需要注意,就是所有在代码中显示的文字串都应存储在资源文件中,而不应该在程序中使用硬编码。例如,以下代码就是硬编码:

  ……

  MessageBox(_T(”文件没有找到!”),_T(”错误”)) ;

  ……

  这种提示仅限于Windows简体中文版,而在没有像中文之星、四通利方等翻译软件的Windows英文版平台上显示的将是一堆乱码。正确的方法应该是:

  ……

  Cstring string1, string2 ;

  string1.LoadString(IDS_FILE_NOT_FIND) ;

  string2.LoadString(IDS_ERROR) ;

  MessageBox(string1, string2) ;

  ……

  在中文资源中,IDS_FILE_NOT_FIND对应“文件没有找到!”字符串,IDS_ERROR对应“错误”字符串;在英文资源中IDS_FILE_NOT_FIND对应“File
not found! ”字符串,IDS_ERROR对应“Error”字符串。

  三、不同语种平台的自动选择

  实现这项功能的思路是使用纯资源DLL,把应用程序中的资源都放在纯资源DLL中。这种DLL仅含有资源而没有可执行代码,也就是源文件中仅包含RC资源文件。应用程序中中文和英文资源可放在不同的DLL中。例如,中文资源DLL名为CHINESE.DLL,它放置中文资源;英文资源DLL名为ENGLISH.DLL,它放置英文资源。程序启动时根据Windows平台语种的类型,加载相应的DLL。以后资源就会从对应的DLL中读取,从而能保证使用正确的资源.。

  为了实现这项功能,需要在应用程序类中加入一个变量以存储资源DLL的句柄并重载应用程序类中的InitInstance和ExitInstance函数。

  在应用程序类声明中加入代码如下:

  ……

  protected:

  HINSTANCE m_hLangDLL ;

  ……

  在InitInstance函数开始处加入代码如下:

  // Get the primary language identifier

  WORD wLangPID = PRIMARYLANGID(::GetSystemDefaultLangID()) ;

  // Load the language resource DLL

  switch( wLangPID )

  {

  case LANG_ENGLISH:

  m_hLangDLL = ::LoadLibrary(“english.dll”) ;

  break ;

  case LANG_CHINESE:

  m_hLangDLL = ::LoadLibrary(“chinese.dll”) ;

  break ;

  }

  if( !m_hLangDLL)

  {

  AfxMessageBox(_T(“Unable to load resource DLL!”)) ;

  return FALSE ;

  }

  // Tell the application what module contains our resource

  AfxSetResourceHandle(m_hLangDLL) ;

  ……

  在ExitInstance函数开始处加入代码如下:

  // Free language resource library

  if(m_hLangDLL)

  {

  FreeLibrary(m_hLangDLL) ;

  }

  ……

  操作系统所使用的语言由WIN32函数GetSystemDefaultLangID取得。宏PRIMARYLANGID又取出主语言标识符进行判断,选择应该调用的DLL。DLL的加载由WIN32函数LoadLibrary实现。程序中所使用的资源库由AfxSetResourceHandle函数指定。程序退出时用WIN32函数FreeLibrary卸载。

  还有,在编译资源DLL时别忘了在连接时加上/NOENTRY选项以告诉连接器这是一个唯一资源的DLL,不包含程序执行的入口点。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图