当前课程知识点:VC++面向对象与可视化程序设计(上):Windows编程基础 > 第5章 资源在Windows编程中的应用 > 5-1 菜单和加速键资源及其应用 > 5-1
返回《VC++面向对象与可视化程序设计(上):Windows编程基础》慕课在线视频课程列表
返回《VC++面向对象与可视化程序设计(上):Windows编程基础》慕课在线视频列表
今天我们开始第5讲的内容
资源在Windows编程中的应用
在这里我们主要介绍菜单、加速键、位图、对话框、图标这些资源
实际上,我们现在用API这个方法完整地编写资源代码
那么我们在后续的MFC构架编程里面,我们将通过图形化的方式构建资源
大家知道通过图形化的方式构建的资源系统会生成一大堆代码
那哪一些是关键代码?可能大家不清楚
通过SDK的API来编写资源代码
那么大家就知道编写一个菜单资源也好、加速键资源也好、位图、对话框、图标等等
编写这些资源,我们最核心的代码是什么
如果大家学会了用API的方法编写资源代码
那么到后面大家学起MFC构架基于图形化界面编写的时候大家就很容识别
在你的操作下,系统根据你的操作而生成的图形资源的代码
那么哪一些是核心代码,哪一些地方你可以进行修改
所以说,从底层自己编写代码的学习还是很重要的
首先我们来学习一下菜单和加速键资源的应用
大家知道菜单由以下几个部分组成
在窗口里面有主菜单条、下拉式菜单框、菜单项热键标识、菜单项加速键标识、以及菜单项分隔线
大家在平时运行程序过程中不见得去认真地分辨过它
但是当你自己需要编写程序的时候,你就要去对每一项的特点进行分辨
平常大家可能关心的就是操作的便捷性
但是当你编写程序的时候,怎么为用户提供便捷的操作,这是你要考虑的
首先我们介绍一下菜单的创建过程
第一,我们要定义菜单
菜单在资源描述文件中的定义是这样的
前面的menuID,菜单的ID,它是一个字符串、或者1-655355之间的整数
但是数字的标识不容易识别,可读性不高,所以通常用字符串
这个MENU是关键字,说明你创建的资源是菜单资源
那么光有菜单的话,你就有一个载入特性选项
比如PRELOAD就是立即加载菜单
还有MOVEABLE就是菜单在内存中可以移动
LOADONCALL需要时加载菜单,等等
这些,大家在学习菜单操作过程中这些选项可以进一步通过参考
微软提供的MSDN帮助文件来帮助大家进一步熟悉
这些,大家更多的可以通过一些相关网站、通过网上提供的资源
通过自主获取学习资源来提升你的学习能力
这里有菜单项列表,比如说POPUP还有MENUITEM就是菜单项
POPUP就是弹出式菜单,这个我们后面继续介绍
我们通过这种模式定义了一个菜单
POPUP是什么?POPUP定义的是弹出式的菜单
那么弹出的应该是一个菜单项的名字,包括它的选项
比如说这个MENUBARBREAK是菜单项的分隔标志
还有这个CHECKED,CHECKED就是大家有时候一个菜单选中时前面打一个勾
那么这就是CHECKED标志
还有INACTIVE,就是禁止一个菜单项,就是这个菜单项不能显示
还有菜单项能显示但不能操作,所以用GRAYED,就是变灰
大家知道,你在操作菜单项的时候,有些菜单项是灰色的
字是灰色的,是不能操作的
在菜单项名中加入&符是用来定义它的热键
比如说,我有一个菜单叫做编辑菜单
POPUP编辑菜单,编辑加&E,这时候你在编辑菜单下面就有一个下划线E
那说明这是一个快捷键操作
当然,你只是加了这样一个东西,并不能进行快捷键的操作
这里只是一个标识,你可以用一个快捷键,用&E进行快捷操作
但是光靠&E的快捷操作还要进行快捷操作的定义
这个后面再介绍
有了菜单就必须有菜单项
MENUITEM就是用来定义菜单项
MENUITEM菜单项的名字,还有菜单的标识
比如说MENUITEM SEPARATOR这是菜单里面的一个分隔线
那么这里的ID是什么?
ID是菜单项的标识
就是每一个菜单下面的菜单项才是具体操作的项
比如说编辑菜单,你选择编辑以后,它会弹出一个编辑菜单
里面包含着比如选择、复制、粘贴,这些是属于菜单项
它在WM COMMAND消息中字参数就包含了菜单的标识
而且每一个菜单项的标识必须唯一
如果一个菜单项的标识不唯一,实际上是没法操作的
而且标识通常在头文件中定义
这里出了一个新的问题,就是头文件中定义菜单的标识
那么也就说今天在我们这一讲里面要涉及.h头文件的编写
在此之前,我们都是学习的.cpp文件的编写
那么从这一讲开始,我们既要写.cpp文件,又要写.h头文件
同时还要编写.rc的资源文件
我们比如说定义了一个My_menu这个菜单资源
这个资源里面我们又挂了一个文件菜单,就是POPUP文件
这个文件里面有新建、打开、关闭、保存、另存为、这里有一个分隔线,还有一个退出
每一个MENUITEM下面菜单项里面都定义了一个ID
IDM_NEW、IDM_OPEN、IDM_CLOSE等等,这就是每一个菜单项的ID
而这个就是快捷操作,比如说&N、&O、&C等等
那么这个ID,前面讲了这个IDM_NEW、IDM_OPEN、IDM_CLOSE用在头文件里面
给它标识了一个对应的数值
而且这些数值对不同的ID,它的数值不能重复
所以你不能够IDM_NEW定义成10以后,不能把IDM_OPEN也定义成10
必须是跟10不一样的
大家看到这是FILE菜单里面的几个菜单项
所以对文件里面对第一个菜单项标识值取为10
后面通常以1为步长连续递增
那么大家可能说我不从10开始,我从去100开始行不行?没有问题
只要你定义的这个值跟别的ID定义的值不重复,都可以
那可能有会有另外一个问题,我这个值不连续行不行?也可以
还是那句话,只要不跟别人重复,都可以
但是为了提高程序的可读性,我们建议每一个菜单里面的菜单项分别连续
那么在这里我就编写一个menu.h头文件
那么大家说头文件一定要取menu吗?可以不取menu,这个根据你的编程习惯
那么有了菜单资源之后,我就要把菜单资源加载
因为你定义了菜单资源之后,系统并不能使用你这个菜单
因为定义的资源在内存里面,并没有挂到应用程序的窗口里面
所以这个时候我要加载
那么加载里面,大家知道在WNDCLASS里面有一个MenuName
这个时候你加载你的菜单资源
那么前面我们都是创建空的应用程序,没有菜单
所以这个地方都是用的缺省的空值
那么现在你就可以用菜单的名字了
比如说我的应用在创建窗口的时候我创建了一个hwnd这个窗口的句柄
要加载菜单资源就要定义一个菜单句柄
那么…我们不管它,可能是别的代码
这个句柄用来干嘛?
就是在当前的实例里面加载My_menu这个我们自己创建的菜单资源
然后返回一个资源句柄
这个句柄就指向了一个菜单资源My_menu
而My_menu是什么?
就是我刚才创建的菜单资源
那么My_menu菜单资源里面只有一个文件菜单
包含文件菜单里面的若干菜单项
这个时候,这个hmenu指向了My_menu
说明hmenu里面包含了文件菜单
到这里为止,菜单并没有挂到窗口去
那么在CreateWindow里面大家去复习一下CreateWindow这个函数
这个函数里面有一个菜单句柄
以后没有菜单句柄的时候这里赋空
有菜单句柄以后,我们把菜单句柄写在这
而这个句柄是指向My_menu
而My_menu下面,刚才看到了是有一个文件菜单
那这样的话,就将文件菜单挂接到你所创建的窗口里去了
那么返回一个指向窗口的句柄
而这个窗口里面就包含了这个菜单资源
而菜单资源就包含了My_menu菜单
My_menu菜单里面包含的是文件菜单以及文件菜单里面的若干个菜单项
那么这就是在创建窗口的时候加载的菜单
当然我们也可以动态地加载菜单
比如说我创建了一个menu2这个菜单资源
然后返回一个hmenu2这个句柄
然后,我要动态创建了,就不在CreateWindow里面直接挂上
而是用SetMenu将这个句柄挂到创建的窗口里面去
我们讲到了菜单操作
刚才只是创建了菜单资源,然后并给它加载
加载后我们要进行的下一步操作是要对菜单项进行操作
所以我们开始介绍菜单项操作
第一,我们可以禁止或激活某个菜单项
用EnableMenuItem来完成,EnableMenuItem就是激活菜单项
激活菜单项并不是都是激活,就是说禁止也算激活,逆向激活
所以在这个menu里面我们有一个激活标识
这个就是哪一个菜单被激活
然后这个是它的标识dwEable
这个标识有如下几种标识
一个是BY_COMMAND以ID值标识菜单项
然后ENABLE是激活,还有一个是BY_POSITION以位置来标识菜单项
还有一个是变灰,这个是禁止
我们还可以设置或取消选中标志
这个就是当设置选中标志的时候菜单项前面会打一个勾
那么我们可以CheckMenuItem
那么对哪一个菜单项进行check,那么可以增加checked标志
还有删除checked标志,也可以通过ID值来标识菜单项
也可以通过位置来标识,位置可以一个个去数,ID用起来可能更方便
我们随着操作的进行可能在操作过程中会增加某些菜单项
或删除某些菜单项
那么我们介绍一下增加菜单项
我们可以在菜单的尾部增加菜单项,用AppendMenu
在这个菜单里面,hmenu里面加入菜单项的标识
以及菜单项的ID和菜单项的内容
比如我们在文件菜单的末尾增加一个关于菜单项
那我们就可以通过AppendMenu
在这个菜单句柄,大家知道的,这个是ENABLE
那么加上的菜单就是可以操作的
这个就是这个参数,就是菜单类型标识是可操作的
这个参数就是菜单项的ID
我们把“关于”这个菜单项的ID设为IDM_ABOUT
这个自己可以设置
当然你不取为IDM_ABOUT,这个“关于”你取为IDM_EDIT
方法上没有错,但是阅读起来容易有歧义
所以一般来说用它的英文标识,英文单词的标识会比较好一点
然后第四个参数是菜单内容
是给人看的,说这个菜单项是什么内容,是“关于”的菜单项
菜单项里面你看到的只是“关于”,而看不到IDM_ABOUT
那么如果在菜单中插入一个菜单项
我们可以InsertMenu
插入的位置可以指定的插入
插入的菜单项的信息以及标识和内容
这个和前面的AppendMenu很相似
比如我们在文件菜单的“退出”项之前加入“打印”
这个跟前面不一样在哪?
它不是在菜单的最后一个位置插入
而是在指定的位置插入
我们用InsertMenu,如果我们在“退出”之前
那么这个“退出”项就是指定位置
这个就是position指定位置指定的退出位置之前
插入一个菜单项,因为我们通过ID指定位置
所以这里是BY_COMMAND
如果我们指定的具体位置按数字位置的话
比如说第二号位置、第三号位置,我们这个就要BY_POSITION
所以我们已经给了ID了以后,就要BY_COMMAND
而且这个标识是ENABLE可用的
这就是插入菜单项的位置,这个位置是退出位置
然后它的菜单项的信息是这个
然后菜单项的标识是PRINT,因为我们要求插入“打印”菜单项
PRINT最后我们看到的是“打印”,然后下划线P这个内容
所以这就是插入菜单项的内容,是这个东西
既然能插入,就可以删除
删除的话,我们也很简单DeleteMenu
比如我们删除文件
菜单中另存为菜单项
那么我们就要把另存为菜单项ID给它
因为既然是ID,所以这里位置的解释一定是BY_COMMAND
如果这里直接给它第几号位置,那么这里就是BY_POSITION
能删除,我们也一样能修改菜单项
我们用的是ModifyMenu
那么我们把文件菜单中的“打开”项改为“加载”项
一样,我们需要修改的位置,这里是句柄,大家知道
这是需要修改的位置,修改的位置就是
我们说的是“打开”项改为“加载”项
那么打开就是OPEN,因为我们直接指的是ID,不是指定位置
所以这个标志flag一定是BY_COMMAND
然后修改后的菜单标识改成加载,我们改成IDM_LOAD
既然是LOAD,那么大家看到的菜单项的名字就是“加载”
这里有下划线L
所以这里5个参数,在这里5个都给大家做了解释
下面我们介绍的是动态地创建菜单
动态地创建菜单可以使系统资源更加节省
在应用程序中动态地创建菜单分为两个步骤
第一个是调用函数CreateMenu创建空的弹出式菜单
然后作为AppendMenu或InsertMenu在菜单项中一个一个菜单项,逐个加入
那么就形成了动态创建菜单
下面我们介绍的是加速键资源
加速键资源是常伴随菜单使用的一种非常有用的资源
在资源描述文件中定义加速键资源
方法是这样的
跟菜单非常类似
这是加速键资源的名字,然后关键字名字ACCELERATORS
然后有一个加速键标识ID
以及它的类型
类型里面就是NOINVERT,就是使用加速键时,菜单项不高亮显示
以及加速键里面其实是一个组合键
组合的方式有ALT、SHIFT、CONTROL
它的一个、两个或者三个
常用的加速键有两种方式
比如,文件菜单中保存项的加速键可定义为CONTROL S
然后我们IDM_SAVE来保存这个菜单项的ID
我们把它定义为这个形式,就是一个向上的箭头、再加上一个字符
然后定义这个ID
这样就可以挂接上去
还有一个就是虚拟键
使用虚拟键作为加速键
比如说F1键作为帮助菜单下的加速键
那么F1跟前面的字符不一样了,它不能用字符表示
所以我们只能用加速键表示
那么就是加速键F1
然后定义的是IDM_HELP,是“帮助”菜单项
然后这里注明它是虚拟键
那加速键资源定义后也同样需要加载
所以通过LoadAccelerators加载
比如说我们定义了加速键资源的句柄
这个hAccel
然后我们通过LoadAccelrators在当前实例句柄里面
加载了加速键一个表
加速键加载后
我们还要翻译加速键
否则加速键是不能够被激活的,不能够使用
那么大家还记得我们在应用程序框架里面
有对键盘命令的翻译TranslateMessage
然后DispatchMessage
然后这时候我们为了翻译加速键
我们再加一个TransAccelerator
然后把加速表的名字,就是就是加速键的句柄放在这
在哪一个窗口中加载的这个加速键资源
那么它的窗口句柄也放着这,然后这是消息的地址
这样的话函数的TransAccelerator是翻译操作的核心
它的作用是对照加速键表,将相关的按键消息
比如说KEYDOWN和KEYUP翻译成COMMAND或者SYSCOMMAND消息
它的特点是将翻译后的消息直接发往窗口
不在消息队列中等待
这就是加速的含义
如果在消息队列中等待,它就起不到加速的作用了
下面我们通过一个例子来介绍菜单资源的使用
-讨论实录
--0-0
-1-1 Windows应用程序的特点
--1-1
-1-2 可视化编程
--1-2
-1-3 关于API
--1-3-1
--1-3-2
-1-4 Windows应用程序组成及编程步骤
--1-4-1
--1-4-2
-1-5 应用程序举例
--1-5-1
--1-5-2
--1-5-3
-02-1 Windows图形设备接口
-02-2 绘图工具与颜色
-02-3 常用绘图函数
-02-4 例题和作业
-第2章源代码
--外部链接
--外部链接
-3-1 设置文本的设备环境
-3-2 文本的输出过程
-3-3 例题和作业
-第3章源代码
--外部链接
-4-1 Windows 应用程序中的键盘与鼠标
--4-1
-4-2 键盘的操作应用举例
--4-2
-4-3 例题
--4-3
-4-3 鼠标在应用程序中的应用
--4-3
-4-4 例题4-4
--4-4
-第4章源代码
--外部链接
-5-1 菜单和加速键资源及其应用
--5-1
-5-1(例1)
--5-1(例1)
-5-2 位图资源及其应用
--5-2
-5-3 对话框资源及其应用
--5-3-1
--5-3-2
-5-4 图标资源的应用
--5-4
-第5章源代码
--外部链接
-第一次作业
--第一次作业--作业
-第二次作业
--第二次作业--作业
-第三次作业
--第三次作业--作业