wxWidgets对资源文件的引用

本文详细介绍了在wxWidgets框架下使用资源文件的三种方式,包括直接使用XPM格式资源文件、将xrc文件编译成C++代码文件内嵌资源、以及将xrc文件压缩成XRS文件在程序中解压加载资源。最后推荐了灵活且体积较小的第三种方法。

在Windows下的资源文件为*.rc, 其中定义了程序要使用的资源名称和资源文件名。在Linux下我们使用的资源文件为*.xrc,这种文件是一种XML格式的文件,描述了程序用到的资源文件类型、资源名称和相应的资源文件名。这种XRC格式的资源文件要使用wxWidgets所自带的一个工具wxrc来进行编译,具体可以编译成C++代码文件或者是一个ZIP格式的压缩文件。下面是我在项目中使用资源文件时的xrc文件,具体格式如下:

<?xml version="1.0"?>
<resource version="2.3.0.1">
<object class="wxIcon" name="mainicon">RemoteManager.ico</object>
<object class="wxBitmap" name="AddDepartment_Bmp">AddDepartment.bmp</object>
<object class="wxBitmap" name="AddEmployee_Bmp">AddEmployee.bmp</object>
<object class="wxBitmap" name="AdminPasswordSetting_Bmp">AdminPasswordSetting.bmp</object>
<object class="wxBitmap" name="DataDecrypt_Bmp">DataDecrypt.bmp</object>
<object class="wxBitmap" name="Root_Bmp">Root.bmp</object>
<object class="wxBitmap" name="Workstations_Bmp">Workstations.bmp</object>
<object class="wxBitmap" name="Employees_Bmp">Employees.bmp</object>
<object class="wxBitmap" name="Modify_Bmp">Modify.bmp</object>
<object class="wxBitmap" name="ResetPassword_Bmp">ResetPassword.bmp</object>
<object class="wxBitmap" name="Option_Bmp">Option.bmp</object>
<object class="wxBitmap" name="Register_Bmp">Register.bmp</object>
<object class="wxBitmap" name="Help_Bmp">Help.bmp</object>
<object class="wxBitmap" name="About_Bmp">About.bmp</object>
<object class="wxBitmap" name="Delete_Bmp">Delete.bmp</object>
<object class="wxBitmap" name="Search_Bmp">Search.bmp</object>
<object class="wxBitmap" name="Logo_Bmp">rich.bmp</object>
<object class="wxBitmap" name="NormalOff_Bmp">NormalOff.bmp</object>
<object class="wxBitmap" name="NormalOn_Bmp">NormalOn.bmp</object>
<object class="wxBitmap" name="DepartmentList_Bmp">DepartmentList.bmp</object>
<object class="wxBitmap" name="SelDepartment_Bmp">SelDepartment.bmp</object>
<object class="wxBitmap" name="QuitDepartment_Bmp">QuitDepartment.bmp</object>
<object class="wxBitmap" name="SelPrivilege_Bmp">SelPrivilege.bmp</object>
<object class="wxBitmap" name="SelPosition_Bmp">SelPosition.bmp</object>
</resource>

其中有一个Icon图标文件,其他使用的资源文件全部都是bmp格式的图片文件。

下面就3种wxWidgets使用资源文件的方式进行说明。

1.直接使用XPM格式的资源文件

XPM(X Pixmap)是X Windows系统使用的一种图片文件格式。最初由位于法国Sophia Antipolis的Bull研究中心的Daniel Dardailler和Colas Nahaboo发明,后来Arnaud Le Hors对其进行了改进。
XPM主要用于创建图标位图文件,并支持“transparent color”功能。XPM文件格式源自更早的X BitMap(XBM),是一种符合C语言语法的纯文本文件。
它可以通过#include语句可以将XPM格式的图形数据导入C语言源文件中。基本格式如下:

static char *<variable_name>[] = {
	<Values>
	<Colors>
	<Pixels>
	<Extensions>		
};

例子:

/* XPM */
static char *xface[] = {
	/* Values */
	"48 4 2 1",
	
	/* Colors */
	"a c #ffffff",
	"b c #000000",
	
	/* Pixels */
	"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
	"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
	"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
	"abaabaababaaabaabababaabaabaababaabaaababaabaaab",
};
小图片或者是图标在所有的平台上都可以用XPM格式来表示。XPM文件其实是一个ASCII编码的完全符合C++语法的文本文件,所以可以直接用C++的方式包含到代码中(译者注:显然这样的包含方式在软件编译完成发行的时候就不再需要将资源文件打包提供了,因为资源文件已经以C++代码的方式编译到程序中了。这样最终的可执行程序会变大。)。

如果要使用XPM格式的资源的话,那么首先可以使用一些小工具将资源文件转换并保存程序XPM文件。比如使用如下的一个转换小工具:

http://www.greenhua.com/soft/22993.html

xpm格式文件在wxWidgets中使用:
将memg.xpm复制到wxWidgets库的include目录(或者可以让编译器找到的任何目录)

#include "meng.xpm"

//......其它代码省略

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
    SetIcon(wxIcon(meng_xpm));
/* 使用meng_xpm变量在堆栈上创建了一个图标(这个meng_xpm变量在mondrian.xpm文件里定义的,可用记事本打开meng.xpm文件进行修改)。然后将这个图标和 frame窗口关联在一起。*/ 
}
这样就可以将meng.xpm这个资源文件设置为Frame窗口的图标了。下面是三个具体使用XPM资源文件的链接地址:

http://blog.csdn.net/gohome520/article/details/6798902

http://hi.baidu.com/rk1105/item/e0e91e5431569b908c12edcb

http://blog.linuxphp.org/archives/1181/

2.将xrc文件编译成C++代码文件,然后将资源文件作为静态资源编译内嵌到可执行文件中,这种方式与XPM文件有点类似,这一步操作同样会使得可执行程序变大。

首先需要使用wxrc程序将xrc文件编译成为C++代码文件,wxrc程序是由wxwidgets安装包自带的一个工具,一般安装好wxWidgets开发包之后就会有wxrc命令了。具体命令如下

wxrc resource.xrc -v -c -o resource.h
这个命令运行之后就会产生一个resource.h文件,该文件的内容大致如下所示:
//
// This file was automatically generated by wxrc, do not edit by hand.
//

#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#include <wx/filesys.h>
#include <wx/fs_mem.h>
#include <wx/xrc/xmlres.h>
#include <wx/xrc/xh_all.h>

#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805
    #define XRC_ADD_FILE(name, data, size, mime) \
        wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime)
#else
    #define XRC_ADD_FILE(name, data, size, mime) \
        wxMemoryFSHandler::AddFile(name, data, size)
#endif

static size_t xml_res_size_0 = 410598;
static unsigned char xml_res_file_0[] = {
0,0,1,0,8,0,16,16,0,0,0,0,32,0,104,4,0,0,134,0,0,0,24,24,0,0,0,0,32,0,136,
9,0,0,238,4,0,0,32,32,0,0,0,0,32,0,168,16,0,0,118,14,0,0,48,48,0,0,0,0,
32,0,168,37,0,0,30,31,0,0,64,64,0,0,0,0,32,0,40,66,0,0,198,68,0,0,96,96,
0,0,0,0,32,0,168,148,0,0,238,134,0,0,128,128,0,0,0,0,32,0,40,8,1,0,150,
27,1,0,0,0,0,0,0,0,32,0,40,32,4,0,190,35,2,0,40,0,0,0,16,0,0,0,32,0,0,0,
1,0,32,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,13,0,20,0,44,
15,35,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,70,70,70,
73,45,45,45,57,0,0,0,17,0,0,0,2,0,0,0,1,0,81,40,57,0,125,66,190,0,140,76,
249,0,144,79,255,0,137,75,241,0,119,61,158,0,58,23,22,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,10,156,156,156,229,190,186,183,252,173,173,173,226,141,141,
141,175,38,73,56,172,0,132,67,247,0,136,70,255,3,139,73,255,7,143,80,255,
9,146,84,255,8,146,84,255,4,133,72,213,0,64,38,20,0,0,0,0,0,0,0,0,78,78,
78,13,155,151,149,252,172,104,43,254,189,132,82,254,160,125,98,254,24,132,
76,254,0,132,64,255,5,136,72,255,6,122,62,255,18,162,102,255,19,165,105,
255,16,158,98,255,11,150,89,255,5,127,72,149,0,0,0,0,0,0,0,0,88,88,88,55,
171,157,146,254,187,116,56,254,205,133,78,254,147,112,64,254,0,133,63,255,
4,138,74,255,3,109,54,255,6,122,61,255,24,157,98,255,50,192,141,255,34,
181,126,255,19,164,104,255,11,143,86,234,0,0,0,5,0,0,0,0,134,134,134,99,.......};
//......其他代码省略
void InitXmlResource()
{

    // Check for memory FS. If not present, load the handler:
    {
        wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one"));
        wxFileSystem fsys;
        wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
        wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
        if (f) delete f;
        else wxFileSystem::AddHandler(new wxMemoryFSHandler);
    }

    XRC_ADD_FILE(wxT("XRC_resource/resource.h$RemoteManager.ico"), xml_res_file_0, xml_res_size_0, _T("image/x-ico"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$AddDepartment.bmp"), xml_res_file_1, xml_res_size_1, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$AddEmployee.bmp"), xml_res_file_2, xml_res_size_2, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$AdminPasswordSetting.bmp"), xml_res_file_3, xml_res_size_3, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$DataDecrypt.bmp"), xml_res_file_4, xml_res_size_4, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Root.bmp"), xml_res_file_5, xml_res_size_5, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Workstations.bmp"), xml_res_file_6, xml_res_size_6, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Employees.bmp"), xml_res_file_7, xml_res_size_7, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Modify.bmp"), xml_res_file_8, xml_res_size_8, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$ResetPassword.bmp"), xml_res_file_9, xml_res_size_9, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Option.bmp"), xml_res_file_10, xml_res_size_10, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Register.bmp"), xml_res_file_11, xml_res_size_11, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Help.bmp"), xml_res_file_12, xml_res_size_12, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$About.bmp"), xml_res_file_13, xml_res_size_13, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Delete.bmp"), xml_res_file_14, xml_res_size_14, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$Search.bmp"), xml_res_file_15, xml_res_size_15, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$rich.bmp"), xml_res_file_16, xml_res_size_16, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$NormalOff.bmp"), xml_res_file_17, xml_res_size_17, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$NormalOn.bmp"), xml_res_file_18, xml_res_size_18, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$DepartmentList.bmp"), xml_res_file_19, xml_res_size_19, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$SelDepartment.bmp"), xml_res_file_20, xml_res_size_20, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$QuitDepartment.bmp"), xml_res_file_21, xml_res_size_21, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$SelPrivilege.bmp"), xml_res_file_22, xml_res_size_22, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$SelPosition.bmp"), xml_res_file_23, xml_res_size_23, _T("image/bmp"));
    XRC_ADD_FILE(wxT("XRC_resource/resource.h$resource.xrc"), xml_res_file_24, xml_res_size_24, _T("text/xml"));
    wxXmlResource::Get()->Load(wxT("memory:XRC_resource/resource.h$resource.xrc"));
}
具体的在代码中的使用如下:
#include<wx/xrc/xmlres.h>
#include "resource.h"

//在App的OnInit方法中进行一些初始化
bool CManagerApp::OnInit()
{
        ::wxInitAllImageHandlers();	//初始化当前平台支持的所有的图像处理句柄

        wxXmlResource::Get()->InitAllHandlers();  //初始化XML资源文件处理句柄
        InitXmlResource();		//初始化XML资源,这个函数是由wxrc处理xrc文件之后产生的resource.h文件中定义的一个函数

	//其他代码省略
}

//在要使用到资源文件的代码处可以进行如下的调用

SetIcon(wxXmlResource::Get()->LoadIcon(wxT("mainicon")));	//加载名称为mainicon的icon图标文件作为窗口的图标

wxBitmap bmDiskMan(wxXmlResource::Get()->LoadBitmap(wxT("AddEmployee_Bmp")));   //加载名称为AddEmployee_Bmp的bmp文件并产生一个wxBitmap对象

具体使用实例的链接地址:

http://blog.chinaunix.net/uid-1693970-id-110252.html

http://www.cnblogs.com/nokiaguy/archive/2008/05/13/1195638.html

3.将xrc文件中描述的资源文件压缩成XRS文件,然后在程序中从XRS文件中解压并还原加载这些资源文件。wxrc默认处理后的XRS文件其实就是一个ZIP压缩文件。可以使用如下的命令来进行编译:
wxrc resource.xrc  -o resource.xrs
可以使用如下的命令来查看XRS文件中包含的内容,该命令只会查看其中包含的内容并不会解压该文件:
unzip -t resource.xrs
具体的在代码中的使用如下,注意,按照这种方式使用的话,在最终软件发行时我们需要将resource.xrs这个压缩文件打包到安装包中,原先的xrc文件就不需要了。一般我们将resource.xrs文件放置在程序运行当前目录的res目录中:
#include<wx/filesys.h>
#include<wx/fs_arc.h>
#include<wx/xrc/xmlres.h>

//在App的OnInit方法中进行一些初始化
bool CManagerApp::OnInit()
{
        ::wxInitAllImageHandlers();	//初始化当前平台支持的所有的图像处理句柄

	wxFileSystem::AddHandler(new wxArchiveFSHandler);	//初始化一个解压文件句柄,用于从XRS文件中解压

        wxXmlResource::Get()->InitAllHandlers();  //初始化XML资源文件处理句柄

	wxXmlResource::Get()->Load(wxT("res/resource.xrs"));	//加载XRS文件,一般将XRS文件放置在程序运行目录的res目录下,注意这里不是XRC文件,实际上在产生的XRS文件中已经包含了原先的XRC文件了

	//其他代码省略
}

//在要使用到资源文件的代码处可以进行如下的调用

SetIcon(wxXmlResource::Get()->LoadIcon(wxT("mainicon")));	//加载名称为mainicon的icon图标文件作为窗口的图标

wxBitmap bmDiskMan(wxXmlResource::Get()->LoadBitmap(wxT("AddEmployee_Bmp")));   //加载名称为AddEmployee_Bmp的bmp文件并产生一个wxBitmap对象
总结:比较3中方法,我个人比较倾向于第3种方法,一来这样比较灵活,二来编译后的可执行程序文件会更小一些。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值