MFC界面编程基础(08):菜单(一)

上一篇:MFC界面编程基础(07):文本编程下一篇:MFC界面编程基础(09):菜单(二)

菜单栏、工具栏和状态栏是组成Windows程序图形界面的三个主要元素。大多数Windows程序都提供了菜单,作为用于与应用程序之间交互的一种途径。本节主要介绍与菜单相关的编程知识。

菜单命令响应函数

创建一个MFC单文档工程并运行该程序,对应这个新创建的程序来说,MFC已经帮我们创建了一个菜单,并完成了一些菜单功能。,例如 【文件】 菜单下的 【打开】菜单命令,即可弹出打开文件对话框。
在VS中打开资源视图选型卡,可以看到Menu下有一个IDR_MAINFRAME的菜单资源,它就是我们应用程序界面看到的菜单。

在这里插入图片描述
VS为我们提供了一个所见即所得的资源编辑器,如果我们要为应用程序添加自己的菜单项,可以直接在这个菜单中添加,程序运行之后就能看到自己添加的菜单项。
在这里插入图片描述
当选中菜单项相应的就会在属性面板中显示出该菜单项的所用属性,也可以在次面板中对菜单项的属性做相应的修改。
在这里插入图片描述
在MFC中,把设置为Popup类型的菜单称为弹出菜单,一般默认顶层菜单为弹出式菜单,这种菜单不能响应命令,它的ID也是无法被编辑的,如果把Popup设置为False该菜单就不是弹出菜单,而成为一个菜单项,它的ID也能够被编辑了。MFC中都是采用大写字母来标识资源ID号的
在菜单编辑器中给应用程序添加新的菜单项,然后为其添加消息响应函数。在新添加的菜单项上点鼠标右键,弹出菜单中选择 添加事件处理程序(A)…
在这里插入图片描述
弹出如下对话框:
在这里插入图片描述
我们打算在框架类中响应这个菜单命令,选择CMainFrame类,消息类型选择COMMAND,添加编辑,在框架类中会自动添加该菜单命令的响应函数。
在这里插入图片描述
运行程序,单击新添加的MyTest菜单项,会弹出一个消息框,说明OnMyTest函数被调用了。

菜单命令的路由

下面我们研究一下程序中的各个类对菜单命令的响应顺序,是不是菜单命令只有框架类才能捕获呢?
按照上面讲到的方法依次为CMainFrame之外的其他类,视图类、文档类和应用程序类中添加菜单命令响应函数。
在这里插入图片描述
因为CMenuApp和CMenuDoc类都不是从CWnd类派生出来的,所有他们没有MessageBox成员函数,我们可以使用全局的MessageBox函数,或者使用应用程序框架的函数AfxMessageBox,这里我们使用的后者。
添加完成之后,执行程序,单击新添加的菜单项MyTest,弹出一个对话框
在这里插入图片描述
这就是说视类最先响应了这个菜单命令。关闭这个提示框在没有其他信息显示,说明其他几个菜单命令响应函数没有起作用。
下面,我们将视图类的OnMyTest响应函数删除,再次运行程序,我们会发现是文档类做出了响应。后面依次删除、运行。 实验发现:响应【MyTest】菜单项命令的顺序是:视图类、文档类、框架类,最后才是应用程序类。
菜单命令消息路由的具体过程:当点击某个菜单项时,最先接收到这个菜单命令消息的是框架类。框架类将把接收到的这个消息交给它的子窗口,即视图类,由视类首先进行处理。视类首先根据命令消息映射机制查找自身是否对此消息进行了响应,如果响应了,就调用相应响应函数对这个消息进行处理,消息路由过程结束;如果视类没有对此命令消息做出响应,就交由文档类,文档类同样查找自身是否对这个菜单命令进行了响应,如果响应了,就由文档类的命令消息响应函数进行处理,路由过程结束。如果文档类也未做出响应,就把这个命令消息交还给视类,后者又把该消息交还给框架类。框架类查看自己是否对这个命令消息进行了响应,如果它也没有做出响应,就把这个菜单命令消息交给应用程序类,由后者来进行处理。

Windows消息的分类:

  • 标准消息
    除WM_COMMAND之外,所有WM_开头的消息都是标准消息。从CWnd类派生的类,都可以接受这类消息。
  • 命令消息
    来自菜单,加速键或工具栏按钮的消息。这类消息都以WM_COMMAND形式呈现。从CCmdTarget派生的类,都可以接收这类消息。
  • 通告消息
    由控件产生的消息,例如按钮的单击,列表框的选择都会产生这类消息,目的是为了向其父窗口通知事件的发生。这类消息也是以WM_COMMAND形式呈现的。从CCmdTarget派生的类,都可以接收这类消息。
    CWnd类派生于CCmdTarget类。也就是说,凡是从CWnd派生的类,他们既可以接收标准消息,也可以接收命令消息和通告消息。而对于那些从CCmdTarget派生的类则只能接收命令消息和通告消息,不能接收标准消息。

标记菜单

我们想实现这样的功能:在【文件】子菜单中的【新建】菜单项上添加一个标记(√
)。因为程序的主菜单属于框架窗口,所以需要在框架类窗口创建完成之后再去访问菜单对象。可以在框架类的OnCreate函数的最后(但一定要在return语句之前)添加实现这个功能的代码。

首先要获得程序的菜单栏,也就是要在框架窗口中获得指向菜单栏的指针,这可以通过CWnd的成员函数:GetMenu来实现,函数声明如下:
CMenu* GetMenu() const;
该函数返回一个指向CMenu类对象的指针。CMenu类是一个MFC类,提供了一些与菜单操作有关的成员函数,其中就有获取一个菜单的子菜单功能的成员函数GetSubMenu函数。函数原型如下:
CMenu* GetSubMenu(int nPos) const;
这个函数的参数nPos指定了子菜单的索引号。
为了设置一个标记菜单,需要使用CMenu类的CheckMenuItem这个函数,该函数的功能就是为菜单项添加一个标记,或者移除菜单项的标记。该函数声明如下:
UINT CheckMenuItem( UINT nIDCheckItem, UINT nCheck );
在这里插入图片描述

默认菜单项

有些应用程序的子菜单下有一个菜单项是以粗体形式显示的,以这种形式显示的就是该子菜单的默认菜单项。 要实现的功能:将【文件】子菜单下的【新建】菜单项设置为该子菜单的默认菜单项。为了实现这种菜单项,可以利用CMenu类的SetDefaultItem成员函数来完成。这个函数的声明形式如下所示:
BOOL SetDefaultItem(UINT uItem,BOOL fByPos = FALSE);
默认菜单项的代码实现有两种方式:

  • 利用位置索引的方式来实现,这时,SetDefaultItem函数的第二个参数应该设置为TRUE;
  • 利用菜单项标识的方式来实现,这时,SetDefaultItem函数的第二个参数应该设置为FALSE。
    在这里插入图片描述

注意:一个子菜单只能有一个默认菜单项。

分隔栏

要实现的功能:在子菜单中添加分隔栏。在新添加的子菜单的菜单项的属性页中进行修改,具体如下
选择菜单项,在菜单项的属性窗口中【杂项】的【Separator】设置为True,该菜单项会自动变成一个分隔符。

在这里插入图片描述

注意:分隔栏在子菜单中是占据索引位置的。

禁用菜单项

实现功能:屏蔽某一子菜单下某个菜单项的功能。这里我们将要禁用【文件】子菜单下的【打开】菜单项的功能。 利用CMenu类的成员函数:EnableMenuItem来完成。该函数的作用是设置菜单项的状态:能够使用、禁用或变灰显示。其声明形式如下所示:
UINT EnableMenuItem( UINT nIDEnableItem, UINT nEnable );
返回值:
返回以前的状态(MF_DISABLED, MF_ENABLED, 或MF_GRAYED),如果无效,则返回-1。
参数:

  • nIDEnableItem 指定由nEnable决定的将要有效的菜单项。该参数既可以指定弹出菜单项,也可以指定标准菜单项。
  • nEnable 指定了将要进行的动作。它可以是MF_DISABLED, MF_ENABLED,或MF_GRAYED与 MF_BYCOMMAND或MF_BYPOSITION的组合。这些值通过位与操作进行组合。这些值有下列含义:
  • MF_BYCOMMAND 指定参数给出已存在的菜单项的命令ID号。此为缺省值。
  • MF_BYPOSITION 指定参数给出已存在菜单项的位置。第一项所在的位置是0。
  • MF_DISABLED 使菜单项无效,以便它不能被选择,但不变灰。
  • MF_ENABLED使菜单项有效,以便它能够被选择,并可从变灰的状态中恢复出来。
  • MF_GRAYED 使菜单项无效,以便它不能被选择并同时变灰。
    在这里插入图片描述
    问题:运行后,选择【文件】子菜单下的【新建】菜单项,但是这时仍会出现“打开文件”对话框,这说明【新建】菜单项未被禁用。
    原因是这样的:
    默认情况下,所有菜单项的更新都是由MFC的命令更新机制完成的。如果我们想自己更改菜单项的状态,那就必须先把m_bAutoMenuEnable变量设置为FALSE,之后我们自己对菜单项的状态更新才能起作用。因此,我们就在程序的CMainFrame类构造函数中把m_bAutoMenuEnable这个变量初始化为FALSE
    在这里插入图片描述

移除和装载菜单

实现功能:移除一个菜单。我们利用Cwnd类提供的SetMenu成员函数来实现,该函数的声明形式如下所示:
BOOL SetMenu( CMenu* pMenu );
这个函数有一个CMenu类型指针的参数,它指向一个新菜单对象。如果这个参数值为NULL,则当前菜单就被移除了
在这里插入图片描述
如果想要装载一个菜单资源并显示。我们可将上面程序中移除的菜单在这里再把它显示出来。我们利用CMenu类提供的LoadMenu成员函数来实现:
在这里插入图片描述
该程序先定义了一个菜单对象,Menu实例程序主菜单的资源标识是IDR_MAINFRAME,把这个资源加载到菜单对象中,最后调用SetMenu函数,把程序的菜单设置为刚刚加载的菜单对象,运行会发现程序的菜单又出现了。

问题:
这里定义的CMenu对象:menu是一个局部对象。虽然运行时未出现错误,但在窗口的操作过程中还是会出现一些错误,这都是因为CMenu对象menu是一个局部对象造成的。
解决问题:

  • 将CMenu对象定义为CMainFrame类的一个成员变量;
  • 仍把这个菜单对象定义为局部对象,但在调用SetMenu函数把此对象设置为窗口的菜单之后,立即调用CMenu类的另一个成员函数Detach,以便把菜单句柄与这个菜单对象分离

在这里插入图片描述

MFC菜单命令更新机制

如果要在程序中设置某个菜单项的状态,可以在菜单编辑器中为这个菜单项添加UPDATE_COMMAND_UI消息响应函数,然后在这个函数中进行状态的设置即可。 当程序框架捕获到了CN_UPDATE_COMMAND_UI消息后,最终还是交由该消息的响应函数来处理,我们会发现在这个函数有一个CCmdUI指针类型的参数,利用这个CCmdUI类,可以决定一个菜单项是否可以使用(Enable函数)、是否有标记(SetCheck函数),还可以改变菜单项的文本(SetText函数)。
在这里插入图片描述

实现功能:改变【文件】子菜单下的【保存】菜单项的状态。
在这里插入图片描述
我们可从工具栏上的保存按钮观察代码修改后的结果。
注意:如果要把工具栏上的一个工具按钮与菜单栏中的某个菜单项相关联,只要将它们的ID设置为同一个标识就可以了。

上一篇:MFC界面编程基础(07):文本编程下一篇:MFC界面编程基础(09):菜单(二)
  • 13
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MFC自定义界面HUI,高效简单,含详细注释和示例。 HUI包括基本控件、按钮、标签、编辑框、表格、悬停提示等,可组合出更多功能。资源占用少,效率高,能在低端机上运行,流畅不闪烁,完全满足工控等各种专业软件实现个性化要求。 本资源是“http://download.csdn.net/detail/hhhh63/6961889”的正式发布版。包括3个项目,Hui、HuiDemo1和HuiDemo2。 一、Hui项目 本项目是DLL项目,包括完整的界面库,使用双缓存,局部重画等技术,性能优异。为保证在不同的MFC版本中使用,本次上传提供了这部分的源码,一般不要对其改动。 二、HuiDemo1 简单的应用示例,包括窗口分割,控制面板和主显示区等,展示控件各方向停靠、自动充满、全屏切换、记忆窗口位置和大小、选项设置和保存注册表等功能,用户可直接以此为基础开发新项目。如需扩展其它功能,可从HuiDemo2查找复制相应代码。 三、HuiDemo2 除HuiDemo1的所有功能外,还包括界面库的全部功能和其它实用扩展功能,左中右三栏式分布,左右固定宽度,中间栏大小可变。 1、左边是属性栏,固定宽度,上边是时钟,下边是鼠标信息,当鼠标移到中间的图像区时显示鼠标位置和图像值。 2、中间是图像区,演示如何动态生存索引图像,从下向上移动,自适应大小,长宽比不变,点右边的调色板按钮改变颜色,点保存按钮把当前图像保存到桌面。 3、右边上边是控制栏,在中间的图像区中画各种几何图形,并计算几何图形包围的图像数据的最大值,最小值和平均值。 4、右边下边是表格演示,显示Windows文件夹下的文件列表,自动充满窗口区,随窗口大小改变显示项数,保证界面美观,最下面是搜索和定位功能。 四、运行环境,VC2010或更高版本。 欢迎大家下载并提意见,本资源版权归作者所有,分享供大家研究学心,不得用于商业用途,如有特殊要求请与本人联系。
### 回答1: 《MFC编程技巧与范例详解》是一本关于MFC编程的书籍,主要介绍MFC编程常用的技巧和实例,并对MFC编程进行深入的分析和讲解。本书可以帮助读者更好地掌握MFC编程的基本原理和技巧,提高MFC编程的效率和质量。 本书内容全面,详细介绍了MFC中的常用技巧,包括界面设计、消息处理、对话框、菜单等,同时还详细讲解了一些复杂、深入的MFC编程技巧,如多线程编程、控件编程等。每一章节的案例都非常实用,可以让读者更好地理解并掌握MFC编程技巧。 本书注重实例,提供了大量的代码范例和实例,每个实例都有详细的讲解和说明,方便读者理解和模仿。同时本书还涵盖了一些高级的MFC编程技巧和应用实例,如COM编程、ActiveX控件编程等,这些内容对于需要进行相关开发的读者来说会非常有用。 总之,《MFC编程技巧与范例详解》是一本非常有价值的MFC编程实战书籍,可以让读者在实际开发中更好地应用MFC编程技巧,提高工作效率和开发质量。值得一提的是,读者在学习本书的过程中需要具备一定的C++编程基础,并且需要有一定的MFC编程经验才能更好地理解和掌握本书内容。 ### 回答2: "MFC 编程技巧与范例详解" 是一本介绍 MFC 编程技巧和实例的书籍,它详细地解释了 MFC 框架和常见控件的使用方法,以及一些常见的编程技巧和策略。本书的主要内容包括:数据存储和读取、用户界面设计、对话框编程、多线程编程、图像处理等等。 本书在介绍一些技巧时,提供了许多实际的应用案例,为同学们提供了很好的实践流程和编程思路。此外,本书还讲解了一些高级的 MFC 编程技巧,如 Windows 套接字编程、COM 编程等等,可供读者参考学习。 本书的编写目的是为了帮助初学者更深入地理解 MFC 编程模型,并为有一定编程基础的开发者提供参考。在介绍不同 MFC 编程方面的技巧时,作者很注重实例的细节,比如如何进行错误处理,如何调试代码等等。这些细节对于编程初学者来说非常有帮助,可以让他们更快地掌握这些技术。 总之,"MFC 编程技巧与范例详解" 是一本很好的 MFC 编程学习资料,可以帮助大家快速掌握这种编程框架的特点和技巧,从而更好地开发 Windows 应用程序。 ### 回答3: 《MFC编程技巧与范例详解PDF》是一本介绍MFC编程技巧和实例的参考书籍,适合MFC编程的初学者和进阶者阅读学习。这本书的主要特点是全面、详细、实用,通过大量的代码示例和实际案例,系统地介绍了MFC框架、MFC应用程序设计基本概念、MFC消息传递机制、MFC控件使用、MFC文档视图等方面的知识,让读者快速了解和掌握MFC编程的核心技术。 《MFC编程技巧与范例详解PDF》的组织结构紧凑、内容丰富,包括第1到5章,分别介绍MFC应用程序设计的基础MFC文档视图模式下的开发、MFC控件的使用、MFC消息传递机制和MFC界面设计的技巧。在书中,作者采用了许多实例和案例,贴近实际工作中的需求,让读者能够更好地理解和掌握MFC编程的基本技巧和高级技术。 总的来说,此书内容丰富实用、难度适中,可以帮助读者系统地学习MFC编程的知识和技巧,并且能够在实际编程中运用所学内容。因此,这本书是MFC编程入门者和进阶者学习的好参考。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值