|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 兰陵月 于 2018-3-13 23:51 编辑
第5章 使用资源
读者可能注意到大多数Windows程序都包含图标。打开“我的电脑”以后,各个可执行程序显示的图标各不相同,当程序运行后,大多数程序都有菜单。另外,当鼠标移动到窗口中后,光标也有可能变得不同,很多程序还使用对话框来提供用户界面。
菜单、图标与对话框都是可执行文件的组成部分,它们是以资源的形式存放在文件中的。但这些资源并不在源代码的数据段中定义,而是由链接程序放入文件的单独一个节区中,当运行中要用到资源的时候,必须借助API函数装入后才能使用。
除了菜单、图标与对话框,Windows中还有其他一些类型的资源,它们是:菜单和加速键、光标和图标、位图、对话框、字符串资源、版本信息、自定义资源。
资源文件的“源文件”是以rc为扩展名的代码文件,由资源编译器Rc.exe编译成为以res为扩展名的二进制资源文件,最后在链接的时候由Link.exe链入可执行文件中,这在前面的内容中已经有所介绍,在这一章中将介绍资源的定义方法,以及在程序中的使用方法。
5.1 菜单和加速键
5.1.1 菜单和加速键的组成
如下图所示,在窗口中,菜单位于标题栏下面。这个菜单称为“主菜单”或“顶层菜单”,图中的菜单项有“文件”、“查看”和“帮助”。单击主菜单上的项目后,可以弹出下一层菜单,叫做“弹出式菜单”或“子菜单”。子菜单中可以继续包含西一层子菜单。如单击“查看”弹出一个子菜单后,再单击其中的“工具栏”可以继续弹出一个子菜单。在子菜单中可以继续弹出下一层子菜单的菜单项最右边用一个三角箭头表示。
有的程序在窗口的客户区单击鼠标右键也可以弹出一个菜单,单击标题栏图标也可以弹出一个系统菜单,这些菜单都属于弹出式菜单。
菜单中的菜单项有好几种,从资源定义的角度来看,分隔用的横线也是一个菜单项。除横线外其他菜单项可以供用户选择,也可以设置为“禁止”或“灰化”状态暂时停用,如图5.1中“被禁用的菜单项”和“被灰化的菜单项”所示。“禁用”的菜单项看上去和普通的菜单项相同,但无法在上面单击鼠标,“灰化”的菜单项从外观上就已经表示是不可用的。菜单项也可以在左边显示选中标记,如图5.1中的“大图标”前的圆点和“状态栏”前的打钩。圆点表示选中标记是互斥的,打钩表示是不互斥的。
加速键就是菜单项的快捷键,图中的“字体”菜单项右边有个“Alt+F”,表示当窗口是激活的时候,不必打开菜单项,直接按“Alt”加“F”的组合键就相当于选择了“字体”菜单项,同样,直接按下“Ctrl”加“Alt”加“B”键就等于选择了“背景色”菜单项。加速键也是资源的组成部分,一般将最常用的菜单项定义为加速键,以减少打开菜单的操作。加速键的定义要遵循惯例,如“Ctrl+C”和“Ctrl+V”一般定为“拷贝”和“粘贴”,“Ctrl+X”定义为“剪切”等。当然加速键的定义并不是必须的,不定义加速键并不会影响程序的功能。
不管程序中是否定义加速键,Windows总是定义了几个默认的加速键,如“F10”会打开窗口的主菜单,“Alt+空格”会打开系统菜单,“Alt+F4”等于单击了“关闭”按钮等。
5.1.2 菜单和加速键的资源定义
在rc文件中, 各种语句使用的是C语言的格式,因为资源编译器rc.exe根本上就是Visual C++附带的(这一点在第2章就提及过),所以在定义等值语句的时候用的是#define,包含语句使用#include<文件名>,用到十六进制的时候并不是用汇编的语法后面加h,而是用前面加0x的方法,如1234h写为0x1234,注释也要用前面加//的方法。这些在书写的时候一定要注意,以免引起语法错误。
在代码文件的头部,首先要把MASM32 SDK软件包中的resource.h文件包含进来,这个文件中包括了资源定义中很多的预定义值,如窗口属性与加速键的键值等。资源在程序中的引用往往用一个数值来表示,称为资源的ID值,但在定义的时候直接使用数值不是很直观,所以往往用#define语句将数值定义为容易记忆的字符串。
1.菜单的定义
在资源代码文件中菜单的定义格式是:
菜单ID MENU [DISCARDABLE]
BEGIN
菜单项定义
…
END
“菜单ID MENU [DISCARDABLE]”语句用来指定菜单的ID值和内存属性,菜单ID可以是16位的整数,范围是1-65535,在Menu.rc文件中,定义的菜单ID是2000h,但菜单ID也可以用字符串表示,如下面的定义:
MainMenu 、menu
begin
menuitem …
end
表示菜单的ID是字符串型的“MainMenu”,但这样定义的话,在程序中引用的时候就要用字符串指针代替十六进制的菜单ID值,显得相当不方便,所以在实际应用中通常使用十六进制数值当做菜单ID。
数值型ID的范围限制在1-65535之间的原因是字符串在内存中的线性地址总是大于10000h,API函数检测参数时发现参数小于10000h时就可以把它认为是数值型的,大于10000h时就当做字符串指针处理。
menu关键字后面的DISCARDABLE是菜单的内存属性,表示菜单在不再使用的时候可以暂时从内存中释放以节省内存,这是一个可选属性。菜单项的定义语句必须包含在begin和end关键字之内,这两个关键字也可以用花括号{和}代替。
菜单项目的定义方法有3类:
-----------------------------------------------------------
MENUITEM 菜单文字,命令ID [,选项列表] (用法1)
或 MENUITEM SEPARATOR (用法2)
或 POPUP 菜单文字 [,选项列表] (用法3)
BEGIN
Item-definitions
…
END
-----------------------------------------------------------
下面分别就这3类详细说明:
用法1定义的是普通菜单项,图5.1中的“字体”与“背景色”等菜单项都是这样定义的,它的组成部分如下: 菜单文字—显示在菜单项中的字符串。如果需要字符串中某个字母带下划线,那么可以在字母前面加&符号,如“字体(F)”就要写成“字体(&F)…”,带下划线的字母可以被系统自动当做快捷键:在这里,当菜单打开的时候按下F键,那么就相当于鼠标选择了“字体”选项。在同一个弹出菜单中要注意不同的菜单项快捷键应该有所区别。另外,如果要把加速键的提示信息显示在菜单项的右边,如“字体”菜单项中的“Alt+F”字符,可以在两者中间加\t(表示插入一个Tab字符),写为“字体(&F)…\tAlt+F”,这样Tab后面的字符在显示的时候会右对齐。
命令ID—用来分辨不同的菜单项。当菜单被选中的时候,Windows会向窗口过程发送WM_COMMAND消息,消息的参数就是这个命令ID。用命令ID可以分辨用户究竟选中了哪个菜单项,所以不同的菜单项应该定义不同的ID值,除非想让两个菜单项的功能相同。
选项—用来定义菜单项的各种属性,它可以是下列数值:
CHECKED—表示打上选定标志(对钩)
GRAYED—表示菜单项是灰化的。
INACTIVE—表示菜单项是禁用的。
MENUBREAK或MENUBARBREAK—表示将这个菜单项和以后的菜单项列到新的列中。用MENUBREAK时新列与旧列之间无分隔线;用MENUBARBREAK时新列与旧列之间有分隔线。
用法2定义的是菜单项之间的分隔线,显然,分隔线是不需要字符串和选项的。
用法3定义的是弹出式菜单,顶层菜单是由多个弹出式子菜单组成的,所以在Menu.rc文件中,主菜单是由“文件”、“查看”和“帮助”3个顺序定义的弹出式菜单组成的,弹出式菜单的定义也可以嵌套,如“查看”菜单中的“工具栏”又是一个弹出式菜单,在嵌套的时候要注意像写C的源程序一样把begin和end(或者{和})正确地配对。popup菜单的选项列表可以是以下的值:
GRAYED—表示菜单项是灰化的。
INACTIVE—表示菜单项是禁用的。
HELP—表示本项和以后的菜单项时右对齐的,如图5.1中所示的“帮助”菜单。
由于popup菜单项选中的时候会自动将弹出式菜单弹出来,不需要向程序发送消息,所以在定义的参数中不需要命令ID。
有些选项是可以同时定义的,如果要指定超过一个的选项,中间要用逗号隔开,但是也有些小小的限制:GRAYED和INACTIVE不能同时使用,MENUBREAK和MENUBARBREAK也是不能同时使用的。
2.加速键的定义
与菜单的定义相比,加速键的定义要简单得多,具体的语法如下:
-----------------------------------------------
加速键ID ACCELERATORS
BEGIN
键名, 命令ID [,类型] [,选项]
…
END
-----------------------------------------------
加速键ID同样可以是一个字符串或者是1-65535之间的数字,整个定义内容也是用begin和end(或花括号)包含起来,中间是多个加速键的定义项目,每个键占据一行,各字段的含义如下所示。
键名—表示加速键对应的按键,可以有3种方式定义。
“^字母”:表示Ctrl键加上字母键。
“字母”:表示字母,这时类型必须指明是VIRTKEY。
数值:表示ASCII码为该数值的字母,这时类型必须指明为ASCII。
命令ID—按下加速键后,Windows向程序发送的命令ID。如果想把加速键和菜单项关联起来,这里就是要关联菜单项的命令ID。
类型—用来指定键的定义方式,可以是VIRTKEY和ASCII,分别用来表示“键名”字段定义的是虚拟键还是ASCII码。
选项—可以是Alt,Control或Shift中的单个或多个,如果指定多个,则中间用逗号隔开,表示加速键是按键加上这些控制键的组合键。
在键名的定义中,系统按键如F1,F2,BackSpace和Esc等都是用虚拟键的方法定义的,Resource.h中已经包括所有的预定义,它们是以VK_带头的一些值,如VK_BACK,VK_TAB,VK_RETURN,VK_ESCAPE,VK_DELETE,VK_F1和VK_F2等,读者可以查看Resource.h文件。下面是加速键定义的一些例子:
-----------------------------------------------
“^C”, ID ;Ctrl+C
“K”, ID ;Shift+k
“k”, ID,ALT ;Alt+k
98, ID,ASCII ;b(字符b的ASCII为98)
66, ID,ASCII ;B(Shift b)
“g”, ID ;g
VK_F1, ID,VIRTKEY ;F1
VK_F1, ID,VIRTKEY,CONTROL ;Ctrl+F1
VK_F2, ID,VIRTKEY,ALT,SHIFT ;Alt+Shift+F2
-----------------------------------------------
在一个资源代码文件中,可以定义多个菜单和多个加速键表,当然也有其他各式各样的资源,有位图、图标与对话框等,这就涉及如何为这些资源取ID值的问题,取值的时候要掌握的原则是:
(1)对于同类别的多个资源,资源ID必须为不同的值,如定义了两个菜单,那么它们的ID就必须用不同的数值表示,否则将无法分辨。
(2)对于不同类别的资源,资源ID在数值上可以是相同的,如可以将菜单和加速键的ID都定义为1,同时也可以有ID为1的位图或图标等,Windows并不会把它们搞混。
|
评分
-
查看全部评分
|