WIN32汇编语言教程:第05章 使用资源 · 5.1 菜单和加速键(3)
2. 加速键的定义
和菜单的定义相比,加速键的定义要简单得多,具体的语法如下:
加速键ID ACCELERATORS BEGIN 键名, 命令ID [,类型] [,选项] ... END
加速键ID同样可以是一个字符串或者是1~65 535之间的数字,整个定义内容也是用begin和end(或花括号)包含起来,中间是多个加速键的定义项目,每个键占据一行,各字段的含义如下所示。
● 键名——表示加速键对应的按键,可以有3种方式定义:
"^字母":表示Ctrl键加上字母键。
"字母":表示字母,这时类型必须指明是VIRTKEY。
数值:表示ASCII码为该数值的字母,这时类型必须指明为ASCII。
● 命令ID——按下加速键后,Windows向程序发送的命令ID。如果想把加速键和菜单项关联起来,这里就是要关联菜单项的命令ID。
● 类型——用来指定键的定义方式,可以是VIRTKEY和ASCII,分别用来表示“键名”字段定义的是虚拟键还是ASCII码。
● 选项——可以是Alt,Control或Shift中的单个或多个,如果指定多个,则中间用逗号隔开,表示加速键是按键加上这些控制键的组合键。这些选项只能在类型是VIRTKEY的情况下才能使用。
在键名的定义中,系统按键如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并不会把它们搞混。
5.1.3 使用菜单和加速键
在完成资源文件所示的编写后,来看看如何在程序中使用菜单和加速键,例子程序的运行界面如图5.1所示,这里先列出程序的功能说明,读者可以先尝试一下,以便在以下的程序分析中有所印象。程序功能如下:
● 程序在用户选择了任何一个菜单项以后,会弹出一个对话框,将接收到的菜单命令ID显示出来。
● 选择“大图标”、“小图标”、“列表”和“详细资料”菜单项后,选中的菜单项前面会出现一个圆点选中标记,4个菜单项的选择是互斥的。
● 在“状态栏”及“工具栏”菜单的3个菜单项中选择后,选中的菜单项前面会出现对钩标记,它们是不互斥的。
● 在窗口的客户区单击鼠标右键会弹出和“查看”菜单一致的弹出式菜单。
● 在标题栏图标上单击鼠标左键,会弹出系统菜单,注意上面比默认的菜单多了两项:“帮助主题”和“关于本程序”。
接下来,将逐步分析这些功能是如何实现的。下面是Menu.asm源代码,代码是在第04章的FirstWindow程序的基础上改写的,这是编写Win32汇编程序的一个常用方法——拷贝一个模板程序再进行修改会节省很多的时间。
.386 .model flat, stdcall option casemap :none ;#################################################################### ; Include 文件定义 ;#################################################################### include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;#################################################################### ; Equ 等值定义 ;#################################################################### ICO_MAIN equ 1000h ;图标 IDM_MAIN equ 2000h ;菜单 IDA_MAIN equ 2000h ;加速键 IDM_OPEN equ 4101h IDM_OPTION equ 4102h IDM_EXIT equ 4103h IDM_SETFONT equ 4201h IDM_SETCOLOR equ 4202h IDM_INACT equ 4203h IDM_GRAY equ 4204h IDM_BIG equ 4205h IDM_SMALL equ 4206h IDM_LIST equ 4207h IDM_DETAIL equ 4208h IDM_TOOLBAR equ 4209h IDM_TOOLBARTEXT equ 4210h IDM_INPUTBAR equ 4211h IDM_STATUSBAR equ 4212h IDM_HELP equ 4301h IDM_ABOUT equ 4302h ;#################################################################### ; 数据段 ;#################################################################### .data? hInstance dd ? hWinMain dd ? hMenu dd ? hSubMenu dd ? .const szClassName db 'Menu Example',0 szCaptionMain db 'Menu',0 szMenuHelp db '帮助主题(&H)',0 szMenuAbout db '关于本程序(&A)...',0 szCaption db '菜单选择',0 szFormat db '您选择了菜单命令:%08x',0 ;#################################################################### ; 代码段 ;#################################################################### .code ;#################################################################### _DisplayMenuItem proc _dwCommandID local @szBuffer[256]:byte pushad invoke wsprintf,addr @szBuffer,addr szFormat,_dwCommandID invoke MessageBox,hWinMain,addr @szBuffer,\ offset szCaption,MB_OK