第七讲:资源
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
资源
大多数Windows程序都包含一个定制的图标,Windows将该图标标在应用程序窗口标题栏的左上角。当程序被列在开始菜单中,被显示在屏幕底部的任务栏中,被列在Windows Explorer中,或者作为快捷方式显示在桌面上时,Windows 也显示该程序的图标。有些程序也使用定制鼠标光标来表示程序的不同操作。还有许多Windows程序使用菜单和对话框。菜单、对话框加上滚动条,这是标准Windows应用程序的界面特点。
实际上,图标、光标、菜单和对话框都是相互关联的,它们全部是Windows 的资源类型。资源实际上是一些二进制数据,被储存应用程序的可执行文件中,分为标准资源和定制资源:标准资源包括图标、光标、菜单、对话框、位图、增强资源文件、字体、键盘快捷键、消息表项、字符串表项以及版本信息等;定制资源是指与特定应用程序相关的,除标准资源之外的一些特殊格式的数据。这些资源并不是驻留在程序的数据区域中,即不能从程序源代码中定义的变量直接存取,必须通过Windows提供的API间接的将其加载到内存中,以备使用。我们已经遇到了两个这样的函数,即LoadIcon和LoadCursor,它们出现在以前的范例程序中,它们从Windows中加载二进制图标和光标映象,并传回该图标或光标的句柄。
向程序添加资源:
创建资源描述文件:File菜单→选择New→选择Resource Script→在File Name域中键入文件名(如test)→单击OK.
系统此时自动建立两个文件test.rc和resource.h,其中test.rc是资源描述文件,resource.h是对在资源描述文件中出现的标识符的定义。
添加资源:Insert菜单→选择Resource→选择资源类型→单击New按钮. 每一个资源都一个唯一的ID号,在程序中通过ID号引用资源。如
wndclass.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON)) ;
为了在程序中通过标识符引用在资源描述文件中定义的资源,在程序的前部写上语句#include "resource.h"。
资源文件是用资源编译器RC.EXE编译的,如下图所示。
图一、资源的编译
下面我们先讨论加载资源的通用方法,然后再分别介绍各种标准资源:
查找和加载资源:
使用资源之前,应用程序必须将它们加载到内存中,FindResource和FindResourceEx函数在模块中查找资源并返回指向这些二进制资源数据的句柄,FindResource通过类型和名称定位资源,而FindResourceEx通过类型、名称和语言定位资源。
LoadResource用FindResource返回的资源句柄将对应资源加载到内存中,在应用程序通过LoadResource加载某个资源之后,系统根据内存状况以及应用程序执行情况,会自动卸载或重新加载这个资源,因此应用程序在不需要某个资源时,不需要显式卸载。通过LoadResource加载的资源还需要调用LockResource等相关API才能使用,如果想马上使用标准资源,可以使用下列API:
在程序结束时,应用程序需要调用以下API来释放加速键、位图、光标、图标和菜单等相关资源所占内存,对于其它类型资源,系统会自动从内存中清除其所占内存。
增加、删除、替换资源:
应用程序会经常增加、删除或替换可执行文件中的资源。有两种方法可以实现:第一种是编辑资源定义文件,再重新编译,然后将其加入到可执行文件中;第二种是将资源数据直接考被到可执行文件中。例如:要本地化一个英语应用程序为汉语应用程序,以便在大陆使用,必须替换英语对话框为汉语对话框,程序员可以利用对话框编辑器重新生成新的对话框,编译后加到可执行文件中。
如果已经存在一个二进制形式的对应汉语对话框,程序员可以直接将其考贝
到可执行文件中:BeginUpdateResource创建和更新资源将要被替换的可执行文件句柄,UpdateResource用这个句柄增加、删除或替换可执行文件中的资源,EndUpdateResource关闭可执行文件句柄。
下面的例子演示了如何从一个可执行文件Hand.exe拷贝对话框资源到另一个可执行文件Foot.exe,步骤如下:
1、调用LoadLibrary加载文件Hand.exe
2、调用FindResource和LoadResource定位和加载对话框资源
3、调用LockResource获取指向对话框资源的指针
4、调用BeginUpdateResource打开一个指向Foot.exe的可更新句柄
5、调用UpdateResource,将对话框资源从Hand.exe拷贝到Foot.exe
6、调用EndUpdateResource完成资源更新
HRSRC hResLoad; // handle to loaded resource
HANDLE hExe; // handle to existing .EXE file
HRSRC hRes; // handle/ptr. to res. info. in hExe
HANDLE hUpdateRes; // update resource handle
char *lpResLock; // pointer to resource data
BOOL result;
// Load the .EXE file that contains the dialog box you want to copy.
hExe = LoadLibrary("hand.exe");
if (hExe == NULL)
{
ErrorHandler("Could not load exe.");
}
// Locate the dialog box resource in the .EXE file.
hRes = FindResource(hExe, "AboutBox", RT_DIALOG);
if (hRes == NULL)
{
ErrorHandler("Could not locate dialog box.");
}
// Load the dialog box into global memory.
hResLoad = LoadResource(hExe, hRes);
if (hResLoad == NULL)
{
ErrorHandler("Could not load dialog box.");
}
// Lock the dialog box into global memory.
lpResLock = LockResource(hResLoad);
if (lpResLock == NULL)
{
ErrorHandler("Could not lock dialog box.");