友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
C语言实例教程(PDF格式)-第18部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
Windows可以自动的决定是否使标准控制菜单中的项变灰。类CWnd可
以通过响应WM_INITMENU来执行检查或变灰,该消息在所有菜单显示
之前发送。
表4。 4 成员函数AppendMenu 的nFlags参数
值 含义
MF_CHECKED 在菜单项前面放置一个默认的选中
标记。当应用程序提供了选中标记
位图时,则使用表示选中状态的位
图。
MF_UNCHECKED 清除菜单项前面的选中标记。如果
应用程序提供了选中标记位图,则
使用表示不选中状态的位图。
MF_DISABLED 禁止某项被选择,但不使其变灰。
MF_ENABLED 允许某项被选择。
MF_GRAYED 禁止某项被选择,并使其变灰。
…………………………………………………………Page 197……………………………………………………………
MF_MENUBARBREAK 对于静态菜单,将项放到新的一
行,对于弹出菜单,将项放到新的
一列。新的弹出菜单列和旧的列使
用垂直分隔线隔开。
MF_MENUBREAK 将项放到新的一行,或弹出菜单的
新的一列。列之间没有任何分隔
线。
MF_OWNERDRAW 指定项为一个自绘制项。当菜单第
一次显示时,拥有该菜单的窗口将
收到消息WM_MEASUREITEM,该消息
包括了菜单项的高度和宽度。而每
次当需要更新菜单项的显示外观
时,将发送消息。该选对顶层菜单
项无效。
WM_POPUP 指定该菜单项具有一个相关联的弹
出菜单。ID参数指定与该项相关的
弹出菜单句柄。该标志用来添加顶
层弹出菜单或将一弹出菜单添加到
另一弹出菜单。
WM_SEPARATOR 绘制一个水平分隔线。仅用于弹出
式菜单。该行不可以变灰,不可以
被禁止,也不可以被加亮,并且其
它参数被忽略。
MF_STRING 指定菜单项为一字符串。
如果由函数GetSystemMenu返回的指针不为空,则通过一个CString对
象strAboutMenu从资源文件中加载字符串IDS_ABOUTBOX。如果成功的
话 (通过检验strAboutMenu是否为空来判断),将该菜单项添加到控制
菜单中。
添加菜单项使用类CMenu的成员函数AppendMenu。该函数具有如下的
原型:
BOOL AppendMenu( UINT nFlags; UINT nIDNewItem = 0; LPCTSTR lpszNewItem = NULL );
BOOL AppendMenu( UINT nFlags; UINT nIDNewItem; const CBitmap* pBmp );
第一个参数nFlags指定了在新添加菜单时关于新增菜单项的状态的信
息。它可以为表4。4所列的一个或多个值。需要注意的事是表4。4中所
列的某些标志是互斥的,也就是说这其中的一些标志不可以同时使
用。关于这方面的详细信息请参考Visual C++中关于成员函数
AppendMenu的联机文档。
…………………………………………………………Page 198……………………………………………………………
l 注意:
l 在程序设计中 (尤其是在涉及到图形编程时!),图形化的菜单
是不是对用户具有更大的吸引力?要达到这一点,在菜单编程中
使用位 图参数就大功告成了 !是不是相 当简单?
如果nFlags参数被设置为MF_POPUP,参数nIDNewItem为一个弹出菜单
的句柄;如果nFlags参数被设置为MF_SEPARATOR,该参数被忽略;对
于其它情况,它为新增菜单项的命令ID。
随着参数nFlags的不同,参数lpszNewItem具有不同的解释,如表4。5
所示。
表4。 5 nFlags参数不同时对lpszNewItem参数的不同解释
Nflags的值 对lpszNewItem的解释
MF_OWNERDRAW 包括一个由应用程序提供的32位值,
应用程序使用该值来维护与该菜单项
相关联的附加数据。该32位值在应用
程序处理消息WM_MEASUREITEM和
WM_DRAWITEM时可用,它被保存在这
些消息提供的结构的itemData成员
中。
MF_STRING 包括指向以null结束的字符串的指
针。
MF_SEPARATOR lpszNewItem参数被忽略。
在第二种格式的成员函数AppendMenu中,参数pBmp指向一个CBitmap
对象,该对象将被用作菜单项。
函数SetIcon用来将句柄设置为某一特定图标,该图标由第一个参数
标识。第二个参数指定和图标的大小,如果该参数为真,表示图标为
32象素' 32象素大小;如果为假,表示图标为16象素' 16象素大小。
最后,由于我们没有将输入焦点设置为某一个特定的控件,因此消息
处理函数OnInitDialog返回真值TRUE。
(3) 消息处理成员函数OnSysmand
类CDialogDemoDlg的OnSysmand成员函数非常之简单,首先它检查
用户选择的命令是否IDM_ABOUTBOX (注意在if语句中使用了表达式
nID & 0xFFF0),如果是的话,声明一个类CAboutDlg的对象,调用该
…………………………………………………………Page 199……………………………………………………………
对象的DoModal成员函数以模态方式显示该对话框;否则,函数
OnSysmand调用基类的成员函数OnSysmand。前面已经提到过,
对于应用程序自己添加的控制菜单项 (如这里的IDM_ABOUTBOX),不要
调用基类提供的成员函数OnSysmand进行默认处理。
(4) 消息处理成员函数OnPaint
首先,类CWnd的成员函数IsIconic用来判断一个窗口是否被最小化。
如果是,函数IsIconic返回真值 (非零值);反之,返回假值 (零)。如
果IsIconic返回真,则以当前this指针 (它指向当前CDialogDemoDlg
对象)为参数构造类CPaintDC的对象dc。类CPaintDC封装了Windows应
用程序重绘时所使用的设备描述表。然后,成员函数SendMessage向
窗口发送一条WM_ICONERASEBKGND消息,该条消息表示在重画被最小
化的窗口的图标之前需要对图标背景进行填充。而类CDC的成员函数
GetSafeHdc返回该类的成员函数m_hDC,即相应的输出设备上下文,
该设备上下文作为WM_ICONERASEBKGND 的wParam参数被发送。
接着成员函数OnPaint分别以SM_CXICON和SM_CYICON有参数调用Win32
API函数GetSystemMetrics (注意它并不是类CDialogDemoDlg及其基
类,典型的如CWnd的成员函数),从而得到以象素为单位的图标默认
宽度和高度,图标大小的典型值为32' 32,但我们不可以在应用程序
中作此假设,因为它依赖于所安装的显示硬件,并可能随用户对系统
设置的改变而改变。
然后类CWnd的成员函数GetClientRect将当前客户区矩形的度量放入
第一个参数所指向的CRect对象中。类CRect封装了由左上角和右下角
所确定的一个矩形。其成员函数Width和Height分别返回所确定矩形
的宽和高。然后通过计算得到使图标居中的坐标。最后调用类CDC的
成员函数DrawIcon绘制由m_hIcon所标识的图标。
如果当前窗口并未被最小化,类CDialogDemoDlg的OnPaint成员函数
调用基类提供的相应成员函数。
(5) 消息处理函数OnQueryDragIcon
消息处理函数OnQueryDragIcon只是简单的返回句柄m_hIcon,并将其
类型强制转换为HCURSOR。
程序所使用的资源如图4。9所示。
…………………………………………………………Page 200……………………………………………………………
a。 类CAboutDlg所对应的对话框
b。 类CDialogDemoDlg所对应的对话框
c。 对话框CDialogDemoDlg所用的图标
图4。 9 在应用程序DialogDemo中所用到的资源
现在即可编译并运行应用程序DialogDemo,其结果如图4。10。通过单
击控制菜单中的项 “关于DialogDemo”,可以打开如图4。9中a所示的
对话框。而无论单击 “确定”还是 “取消”,应用程序DialogDemo都
将被关闭。
图4。 10 应用程序DialogDemo的运行结果
第五节 小结
本章详细的分析了由AppWizard生成的一个基于对话框的应用程序,
这是进行下一步对控件的学习的基础。同时,我们还借用该程序说明
了使用MFC编写的应用程序的结构,涉及到了以下的一些内容:
l 从CWinApp派生的应用程序类
…………………………………………………………Page 201……………………………………………………………
l MFC应用程序的消息映射机制和方法
l 从CDialog派生的对话框类 (这里CDialog又从CWnd派生)
我们在这些内容上花费了大量的篇幅,但就算是这样还是未能将其完
全的阐述清楚。它们是一些比较复杂,但并不神秘的东西,然而一旦
理解了这些东西,那么你对MFC的理解立刻就会上升一个层次,从而
在实际编程的过程中获益更多。
在本章,我们对代码进行几乎是逐行逐字的讲解和说明,这是考虑到
初学者对于MFC的编程方式比较陌生的情况。在后面几章的内容中,
我们对于一些关系不是很紧密的内容不再作详细的讲述,你需要随时
查阅Visual C++的联机文档,好在里面有数不清的资源可以利用。但
是应该记住一点,我们建议你弄懂示例程序中的每一行所完成或实现
的功能,只有这样,才能充分利用这些经过实践证明是可行的编程方
法和技巧,从而在比较短的时期内很快的提高自己的编程水平和能
力。
…………………………………………………………Page 202……………………………………………………………
第五章 响应用户命令
我们很容易想见,在Windows 95程序设计中,一个很重要的方面就是
对各种消息的响应。而在这其中,各种输入命令的响应又几乎占据着
最重要的地位。就象我们在前面的章节中所介绍的那样,窗口可以说
是Microsoft Windows的最重要的用户界面对象,而第二重要的用户
界面对象就得算是菜单了,用户选择可用命令的一个最常用,也是最
重要的手段就是菜单。这一点,通过查看Windows API中菜单所支持
的庞大的功能也可以更直观的看出。当然,我们也可以发现,在一些
情况下,我们可以有更快捷,有时也更有效的命令输入方式,就是使
用加速键或者工具条。当然,出于对界面介绍的完整性考虑,我们在
本章的末尾,也会简单的介绍滑块控件,进度条以及一些上下控件的
基础知识。
即使是Microsoft Windows的临时用户也知道,在应用程序的主窗口
的顶部会出现一个菜单条,在Windows 95中,Microsoft还提示使用
对象的上下文菜单。用户所需要做的,简单到只需要轻轻单击一下鼠
标右键就可以了。(在后面的程序设计中,我们会看到,要是你觉得
使用双击右键更有意思的话,作出这种改变几乎没有什麽更多的工
作。)同时,我们也会向你展示实现图符菜单的简单方法。在该节的
最后,我们还会介绍如何对系统菜单进行操作。
加速器是这样的一个按键,程序负责将这一按键解释成一个命令,从
用户程序的角度看,在菜单选择与加速器按键的选择并没有什麽差
别,这是通过Windows为二者生成相同的消息决定的。对于程序员来
说,将加速键显示在相应菜单的右侧是一个良好的习惯,它为熟练用
户提供了进行更方便选择提供了一种可能性。但是从程序设计的角度
看二者却是分别定义的………菜单是用菜单资源定义的,而加速键是用
加速键资源定义的。
工具条是第三种命令输入机制。工具条是一个带有按钮的窗口,它使
用户发出命令的动作节省到在相应按钮上按一下鼠标即可。当然,由
于工具条本身也要占据屏幕空间,因此,放在工具条上的命令应该是
最常用的。而且,出于对用户的尊重,在用户不希望使用它的时候,
应该能将工具条隐去。AppWizard 自动创建的工具条提供这种能力,
但我们会对此作出更详细的解释。
在本章的最后,我们会对一些在Windows下常用的控件,比如滑块控
件,进度条以及上下控件的一些基础知识。总得来说,我们准备在本
章中介绍如下知识:
…………………………………………………………Page 203……………………………………………………………
l 菜单消息响应
l 快捷键消息响应
l 工具条消息响应
l 对上下控件、进度条、以及轨道消息响应
第一节 菜单消息响应
在程序接口中,我们最常用的选择方式就是用菜单进行选择。而对于
从程序员来说,我们所要做的很大一部分工作,就是对程序的输入进
行响应。无庸置疑,菜单可以有多种实现的方式。从用户的使用角度
来说,当然希望可以有多种多样的选择。我们常常建立下拉菜单,也
可以建立一些必要的图符菜单,当然在必要的时候,我们业应该建立
一种使用上更便捷的上下文菜单。而在很多情况下,我们希望对菜单
进行动态的操作――在许多时候,这甚至是一种很重要的事情,对在
我们下面的章节中也会有所提及。
从下面开始,我们将按以下的顺序对菜单消息的响应进行讲解。
让我们先看看怎样在资源编辑器中实现菜单。
首先新建一个基于单文档界面的程序,这只需要在AppWizard新建程
序的第一步(如图5。1)中在Application Type选择时选择Single
document即可。
图5。 1 建立单文档界面程序:Step1
…………………………………………………………Page 204……………………………………………………………
我们设该应用程序的名称为Menu。同时,由于是首次建立不是基于对
话框的程序,我们简单的说一下建立的过程。(基于对话框的程序
AppWizard只需要四步,而基于文档的程序需要六步。)
在第二步(如图5。2所示)中,我们将设定数据库支持,由于我们现在
建立的只是简单的单文档程序,我们选择不需要任何数据库支持。
在第三步 (如图5。3所示)中,我们将设定生成的标准程序中的文档
支持。AppWizard提供有容器类 (Container)与服务类 (Server)应用,
我们保持缺省设置。(不需要容器类与服务类支持,但保留ActiveX
Control控件支持。)
图5。 2 建立单文档界面程序Step 2
图5。 3 建立单文档界面程序Step 3
…………………………………………………………Page 205……………………………………………………………
在第四步(如图5。4)中;我们去除掉打印预览及打印支持。但我们保持
工具条,状态条,三维控制支持。对刚使用的文件列表数设置为四。
在第五步(如图5。5)中,我们将设定是否设置提示及怎样使用MFC库。
在刚开始时,我们设定需要提示,同时,动态链接MFC库。
在最后一步中(如图5。6)中,我们将设定AppWizard将要为我们生成的
类。
图5。 4 建立单文档界面程序Step 4
图5。 5 建立单文档界面程序Step 5
这样,我们就建立起一个具有Document/View结构的简单的应用程
序。
…………………………………………………………Page 206……………………………………………………………
在进行进一步的编程以前,我们希望你能对照在第四章中对基本框架
的解释,对产生的其它文件 (MenuDoc和MenuView)我们将在第六章中
作详细的解释,现在读者要是理解得不大清楚,可以先跳过去这一部
分。在作进一步的编程之前,建议读者先将AppWizard生成的程序编
译,运行,看看AppWizard都为我们实现了什麽功能。
图5。 6 建立单文档界面程序Step 6
下面我们对程序的菜单作一些修改。
图5。 7 菜单资源IDR_MAINFRAME0
图5。 8 菜单资源IDR_MAINFRAME1
…………………………………………………………Page 207……………………………………………………………
图5。 9 系统菜单
如图5。7所示;为我们的程序运行菜单的一个画面。该菜单的属性为
IDR_MAINFRAME0
而下面的两个图片为我们的应用程序运行时的另外一组菜单。该菜单
的属性为IDR_MAINFRAME1。
在程序中;我们的改变了Help和Draw菜单;如图5。8所示。
最后;我们改变了系统菜单;并改变了其中的一个选项的功能。如图5。9
所示。
作为补充;下面我们看一下程序所实现的绘图以及系统菜单被改变后
实现的功能(如图5。10所示)。
图5。 10 程序的一个运行画面 (系统菜单中新增菜单被选择)
我们认为;通过第四章中基于对话框的程序以后;读者应该已经掌握了
实现菜单的修改的方法;但为了下面描述的方便;我们在此列出各菜单
项的属性。
l 注意:
…………………………………………………………Page 208……………………………………………………………
l 下面的代码摘自菜单完成后的文件Menu。rc中(该文件以文本形式
保存;可以用写字板或者记事板打开。为了更清楚地理解下面的代
码,我们粗略的讲解一下菜单资源的语法:
关键字POPUP表明其后的BEGIN与END之间的为其弹出式子菜单
的内容。
关键字MENUITEM标识一具体的子菜单内容。MENUITEM后所跟
的第一部分为 菜单标题,其最后一部分则为标识该菜单项的
ID号
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!