在Win32中,使用一个资源实际上分成四个步骤,在当前模块寻找资源,加载资源以及锁定资源,使用完毕后释放资源。
HRSRC FindResource(
HMODULE hModule,
LPCTSTR lpName,
LPCTSTR lpType
);
hModule[in] :Handle to the module whose executable file contains the resource. A value of NULL specifies the module handle associated with the image file that the operating system used to create the current process.
lpName[in]: Specifies the name of the resource. For more information, see the Remarks section below.
lpType[in]: Specifies the resource type. For more information, see the Remarks section below. For standard resource types, see Resource Types.
该函数确定具有指定类型和指定名称的资源在指定模块中的位置。
如果成功,返回值是指定资源信息块的句柄;若要获取该资源的句柄,调用LoadResource 函数,并将获取的信息块的句柄传入其中。
该函数内部会使用IS_INTRESOURCE(x)宏来测试x (此时x=lpName或者lpType),当测试为真时,x为资源名称或类型的ID值;否则,这些参数是字符串指针。当字符串的首字符为’#'号时,剩余的字符代表十进制的整数ID值。比如,字符串"#258"代表ID值258.
为了减小资源所需内存数量,程序应该通过ID值而不是名称引用资源。
程序可以使用FindResource 找到任何类型资源,但是该函数应当仅在程序通过调用 LockResource 获取二进制的资源数据前使用。
需要立即使用资源时,程序应该使用下列资源函数一次性完成寻找和加载资源的操作。
Function | Action |
---|---|
FormatMessage | Loads and formats a message-table entry. |
LoadAccelerators | Loads an accelerator table. |
LoadBitmap | Loads a bitmap resource. |
LoadCursor | Loads a cursor resource. |
LoadIcon | Loads an icon resource. |
LoadMenu | Loads a menu resource. |
LoadString | Loads a string-table entry. |
例如,程序应该使用LoadIcon加载一个图标。然而,程序需要将一张图标资源复制到另一个程序当中时,应当使用 FindResource 和 LoadResource 。
HGLOBAL LoadResource(
HMODULE hModule,
HRSRC hResInfo
);
hModule[in]: Handle to the module whose executable file contains the resource. If hModule is NULL, the system loads the resource from the module that was used to create the current process.
hResInfo[in] :Handle to the resource to be loaded. This handle is returned by the FindResource or FindResourceEx function.
加载资源到全局内存中。
如果该函数成功,返回与资源关联数据的句柄。当需要获取资源数据的指针时,调用LockResource函数。
当需要立即使用一个资源时,程序应该使用下列函数一次性的找到和加载资源。
Function | Action | To remove resource |
---|---|---|
FormatMessage | Loads and formats a message-table entry | No action needed |
LoadAccelerators | Loads an accelerator table | DestroyAcceleratorTable |
LoadBitmap | Loads a bitmap resource | DeleteObject |
LoadCursor | Loads a cursor resource | DestroyCursor |
LoadIcon | Loads an icon resource | DestroyIcon |
LoadMenu | Loads a menu resource | DestroyMenu |
LoadString | Loads a string resource | No action needed |
比如,程序使用 LoadIcon 函数加载一个图标,在使用完毕后调用DestroyIcon销毁图标。
实际上,LoadIcon、LoadCursor等函数就是调用了FindResource和LoadResource完成了资源加载。
系统在创建这些资源的进程结束时自动删除这些资源;不过,调用合适的函数可以节约内存、降低进程工作集的大小。
在内存中锁定资源,返回指向资源数据的首字节。
LPVOID LockResource( HGLOBAL hResData);
如果加载的资源锁定了,该函数返回资源首字节的指针;否则,NULL.
只有在包含该资源的模块尚未卸载时,该函数才返回有效指针。不需要解锁资源,因为系统在进程结束时会自动删除这些资源。
在Win32编程中,FreeResource 用来释放资源。
BOOL FreeResource( HGLOBAL hglbResource);
hglbResource[in]: Handle of the resource. It is assumed that hglbResource was created by LoadResource.
该函数可使加载资源的引用数减1。当一个资源的引用数减为 0的时候,资源的内存被释放。
当程序调用LoadResource函数时,会使资源的引用数加1. FreeResource函数已经废弃了,仅仅是为了兼容16位的Windows。对32位的Windows程序,没有必要释放LoadResource加载的资源。
对用其他函数加载的资源,比如LoadIcon, LoadCursor, LoadBitmap, LoadImage, LoadMenu, or LoadAccelerators,FreeResource 已经被下列函数取代。
Resource type | FreeResource replacement |
---|---|
Accelerator | DestroyAcceleratorTable |
Bitmap | DeleteObject |
Cursor | DestroyCursor |
Icon | DestroyIcon |
Menu | DestroyMenu |
当创建这些资源的进程终止时,系统将会自动删除这些资源。然后,调用恰当的释放函数会节约内存。