使用资源
你可能需要参考本教程后面的附表查看关于使用VC++和BC++编辑资源的更多消息.
在我们进行进一步的对资源进行讨论前我先提一点以免我要在每一段重写一次.你不需要编译此段中的內容,它仅仅是例子.
资源是你可执行文件中预定义的二进制数据.你用资源脚本来创建资源,就是以".rc"结尾的那种文件.商业的编译器一般有可视化的资源编辑器让你能不用手动编辑资源脚本但有些时候你必须这样做,特別是你用的编译器沒有可视化的资源编辑器的时候,或是不支持你需要的功能的时候.
不幸的是,不同的编译器以不同的方式处理资源.我将尽力对工作所需要的资源处理中的通用部分进行解释.
MSVC++中的资源编辑器让手工编辑资源很困难,因为它又加了一些专有的格式,而且把你手动编辑的文件弄得一团糟.
通常说你不用为手动编辑.rc文件而操心,但是知道如何手工修攺它是很有好处的.另外一件烦心的事情是MSVC++总是把资源头文件命名为”resource.h”,即使你想起一个別的名字.为简便叙述起见我暂时先遵循这一个规则,将后面的关于编译器的附表中将指出怎样攺变这个规则.
首先让我们来看一个很简单的资源脚本,只有一个图标.
#include "resource.h"
IDI_MYICON ICON "my_icon.ico"
这就是整个文件了.IDI_MYICON是资源的标识,ICON是类型,"my_icon.ico"是包含其的外部文件.这些应该在所有的编译器上都可以工作.
那么"#include
"resource.h"干什么用?因为你的程序需要一种标识这个图标的方式,最好的方式就是给个一个独一无二的ID(IDI_MYICON).我们可以创建"resource.h"并在我们的资源脚本和源文件中同时包含它.
#define IDI_MYICON 101
可以看到我们给IDI_MYICON赋了101的值.我们可以忘掉那个标识符只用101来引用这个图标,但是IDI_MYICON表达的意思更清楚,而且在你拥有一大堆资源的时候也容易记忆.
现在我们来添加一个MENU资源:
#include "resource.h"
IDI_MYICON ICON "my_icon.ico"
IDR_MYMENU MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
END
这次IDR_MYMENU是资源的名字,MENU是类型.看见BEGIN和END沒有?有些资源编辑器或是编译器用{代替BEGIN和}代替END.如果你的编译器两者都支持的话你随便选一种就是了.如果它只支持一种的话,你就需要做一些替換.
我们还添加了一个新的标识符ID_FILE_EXIT,所以我们为了在我们的程序中使用的话,先要在资源头文件resource.h中添加一下.
#define IDI_MYICON 101
#define ID_FILE_EXIT 4001
在大的工程中生成这些标识并要一直保持它们的定义是一件很繁杂的事务,这就是为什么很多人使用一个可视化的资源编辑器来做这些事情.它们有时也会出点问题,比如你可能遇到很多资源项拥有相同的标识之类的问题,这时候你就可能要自已来解決它们.
现在来看下怎么在你的程序中使用资源.
HICON hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
LoadIcon()和很多其它的使用资源的函数的第一个参数为当前运行程序的实例的句柄(在WinMain()中给出,也可用像前面章节中讲的那样用GetModuleHandle()来获取).第二个参数为资源的标识.
你可能在想MAKEINTRESOURCE()干什么用或在迷惑为什么LoadIcon()要吃一个LPCTSTR型的参数而不是UINT之类,当我们传给它一个标识的时候.MAKEINTRESOURCE()所做的就是把我们资源标识的整型数强转为LoadIcon()所要的LPCTSTR类型.这里我们可以看到标识资源的第二种方法,使用字符串.几乎沒有人这样做了,所以我就不详叙细节了,但是基本上如你不用#define为你的源定义一个整数的话那么它的名字以一个字符串来解释,在你的程序中这样来引用:
HICON hMyIcon = LoadIcon(hInstance, "MYICON");
LoadIcon()和一些別的使用资源的API函数能夠通过检查高字来判別传给它的是一个整数还是一个指向字符串的指针.如果为0(所有小于等于65535的整数)则它认为它为一个资源标识.这也把你你的标识限制在65535下面了,除非你的确有很多很多的资源,应该不成问题.如果不是0则它认为它为一个字符串的指针,它就用名字来找资源.当然除非文档中明确指明了这一点,最好不要依赖API的这个特性.
比如,对于菜单命令ID_FILE_EXIT,这个特性就不能工作,因为它们只能为整型.
|