Windows资源文件的读取
《把脉VC++》第6章使用文件存取对象,本章讨论常见的文本文件、二进制文件的存取格式,除了properties文件格式、INI文件格式、CSV文件格式等文本文件格式外,最后重点讨论作为数据交换的一种通用格式XML及对其的操作方式,包括MsXML和ADO.NET存取方式。本节为大家介绍Windows资源文件的读取。
6.3.5 Windows资源文件的读取
Windows资源是一种特殊的存储形式,它通常存在于EXE和DLL模块中,Windows程序常常使用资源来存储程序需要的图标、工具栏等信息。但我们也可以在某些合适的场合考虑采用资源文件来作为反持久化的介质。
“合适的场合”,该如何理解?注意到当前运行的程序其资源文件在运行时期是只读的,所以说资源文件不适合那些需要动态更新的信息,它必须是在设计阶段就能确定的信息。举个例子,一些下拉框的信息可能来自于某些字典表,而这些字典项的内容在程序的运行期间是不变的(比如,性别包含两项:男、女),这个时候我们可以考虑采用资源文件。另外一种场合,如果在程序中创建一个Word文件,可能需要一个Word模板,或者说我们的Access数据库可能需要一个空白的模板,而我们又不希望在程序发布时多带一个文件,那么这个时候,就需要使用资源文件了。
资源就存在当前正在运行的程序中,我们让这个程序读取自己的资源,这犹如一个高明的医生给自己做腹腔手术。Windows提供的API函数如表6-12所示。
资源 | |
函数 | 含义 |
LoadAccelerators | 加载快捷键资源 |
LoadBitmap | 加载位图资源 |
LoadCursor | 加载光标资源 |
LoadIcon | 加载图标资源 |
LoadMenu | 加载菜单资源 |
LoadString | 加载字符串资源 |
这里面仅仅列出常见类型(快捷键、位图、光标、图标、菜单、字符串)的资源的加载。表6-13列出的是加载所有类型的资源的函数。
资源 | |
函数 | 含义 |
FindResource | 从指定模块中加载指定名称、类型的资源 |
SizeofResource | 获取资源数据的长度 |
LoadResource | 加载指定的资源至内存 |
LockResource | 锁定指定的资源,并返回指向资源数据的指针 |
FreeResource | 释放指定的资源 |
我们通常加载某个资源的步骤如下所示:
使用LoadLibrary()加载模块,或者获取当前应用程序的模块。
调用FindResource()从指定模块中查找指定的资源,返回该资源的句柄。
调用SizeofResource ()获取资源数据的长度。
调用LoadResource()将资源加载至内存。
调用LockResource()锁定资源,并返回指向资源数据的指针。
通过数据指针操作数据。
使用完毕,调用FreeResource()释放指定的资源。
现在动手
如下例程序演示了如何在当前程序中添加一个Word资源,并在运行时读取它,请读者仔细体验。
选择【Win32】→【Win32项目】→【控制台程序】命令,创建ResLoader。
打开资源视图,导入一个Word文档,资源类型定义为”WORD”,资源名为IDR_WORD1,如图6-22所示。
#include “stdafx.h”
#include “ResLoader.h”
CWinApp theApp;
int _tmain()
{
int nRetCode = 0;
if (!AfxWinInit(::GetModuleHandle(NULL),NULL, ::GetCommandLine(), 0))
{
_tprintf(_T(“错误: MFC 初始化失败\n”));
nRetCode = 1;
}
else
{
HRSRC hRes = FindResource(theApp.m_hInstance, MAKEINTRESOURCE(IDR_WORD1), _T(“WORD”));
//获取长度
DWORD len = SizeofResource(theApp.m_hInstance, hRes);
HGLOBAL hg = LoadResource(theApp.m_hInstance, hRes);
LPVOID lp = (LPSTR)LockResource(hg);
//将资源中的内容保存至某个Word文件中
CFile file;
file.Open(_T(“out.doc”), CFile::modeWrite | CFile::modeCreate);
char * cp = (char *)lp;
for(int i = 0; i < len; i++)
{
file.Write(cp++, 1);
}
CString filePath = file.GetFilePath();
file.Close();
//打开该文件
ShellExecute(NULL, _T(“open”), filePath, NULL, NULL, SW_SHOW);
FreeResource(hg);
}
return nRetCode;
}