友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
VC语言6.0程序设计从入门到精通-第12部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
望读者能够仔细阅读推敲,并在后面章节的学习过程中能够反复翻阅体会,以便达到对 MFC
应用程序框架的深刻理解。
·41 ·
…………………………………………………………Page 51……………………………………………………………
第 3 章 菜单与加速键
第 3 章 菜单与加速键
菜单是 Windows 程序界面的重要元素,程序的各种操作和功能都是通过单击菜单项完成
的。一个设计合理、功能完善的菜单能极大地方便用户的使用。加速键是菜单的辅助功能,
程序使用者可以通过快捷键直接访问常用的菜单选项。本章就介绍在程序中创建菜单和加速
键的方法。
3。1 消息与事件
Windows 应用程序是通过消息驱动的,因此消息和事件是Windows 程序设计的核心概念。
本节将简要介绍消息和事件的处理过程,为以后的编程实践打下基础。
3。1。1 事件驱动机制
在生活中,人们都会对外界发生的各种各样的和自身相关的刺激做出一定的反应,这就
是所谓的应激性。Windows 系统中也有类似的应激性,也就是本小节要介绍的概念—事件
驱动机制。
Windows 作为一个以图形界面为主的操作系统,主要面向与用户的交互。这个特点决定
了在 Windows 上面运行的程序大部分都要以等待用户输入,并根据用户输入做出相应的操作
为主要运行方式 。因此,用户输入是 Windows 系统中消息和事件的一个主要来源。根据用户
输入做出相应的操作,这个过程称为消息处理的过程。同时 Windows 系统也将系统和程序,
程序和程序之间的相互作用,抽象为另外一类消息和事件。这样程序在运行中与系统环境的
相互作用就体现为接收消息,然后对消息进行处理。这就是事件驱动机制的主要内涵。
Windows 下的应用程序的主要工作是进行消息的循环处理,通过循环等待消息的到来和
事件的发生,然后对不同的消息和事件运行相关的代码,完成相应的操作。
3。1。2 消息和消息映射
Windows 系统中的程序大部分都是通过消息和事件驱动的。为了完成各种功能,Windows
提供了大量的消息。这些消息主要有 3 种类型。
o 标准 Windows 消息:消息名以 WM_ 为前缀的消息(也有例外,如控件通知消息
WM_MAND ),例如 WM_SIZE (改变窗口大小消息)、WM_MOVE (移动窗口
消息)等。
o 控件通知消息:由列表框、按钮等控件或子窗口发给其父窗口的通知消息 ,以
WM_MAND 为消息名,消息中包含有控件通知代码,用以区分不同的控件通知
…………………………………………………………Page 52……………………………………………………………
第 3 章 菜单与加速键
消息。
o 命令消息:命令消息也以 WM_MAND 为消息名,在消息中包含有命令的标识符,
用以区分不同的命令。命令消息主要来自菜单、工具栏和加速键。其中菜单和加速键
消息将是本章要学习的内容。
上面的这 3 类消息在 MFC 中有统一的处理框架,即消息映射机制。消息映射机制将消
息及其处理函数表示成一一对应的表,并对这张表进行分析处理。
CCmdTarget 类的派生类用
于存放消息映射机制,使用消息映射必须在源程序中加入以下两方面内容:
(1)在类的头文件中加入如下语句:
DECLARE_MESSAGE_MAP()
例如在类 CTestApp 的头文件 TestApp。h 中有如下代码段:
class CTestApp : public CWinApp
{
public:
CTestApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTestApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CTestApp)
afx_msg void OnAppAbout();
// NOTE the ClassWizard will add and remove member functions here。
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
DECLARE_MESSAGE_MAP()就添加在 CTestApp 类的定义程序块的末尾。
(2 )在类的实现文件中加入消息映射表:
BEGIN_MESSAGE_MAP(类名; 父类名)
……
消息映射表项
……
END_MESSAGE_MAP()
在 CTestApp 类的实现文件 TestApp。cpp 的开头、常量定义的后面,就有如下消息映射表
的代码:
/////////////////////////////////////////////////////////////////////////////
·43 ·
…………………………………………………………Page 53……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
// CTestApp
BEGIN_MESSAGE_MAP(CTestApp; CWinApp)
//{{AFX_MSG_MAP(CTestApp)
ON_MAND(ID_APP_ABOUT; OnAppAbout)
// NOTE the ClassWizard will add and remove mapping macros here。
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document mands
ON_MAND(ID_FILE_NEW; CWinApp::OnFileNew)
ON_MAND(ID_FILE_OPEN; CWinApp::OnFileOpen)
// Standard print setup mand
ON_MAND(ID_FILE_PRINT_SETUP; CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
MFC AppWizard 生成的应用程都已经自动包含消息映射的代码,但用户也可以在源程序
中手动添加。同时 Visual C++另一个强大的工具 ClassWizard 也提供了处理消息映射表的自动
化机制。当然,ClassWizard 只能够生成类和消息处理的框架,包括创建消息处理函数的声明,
而具体的实现代码还需要用户去补充。
在类中,消息处理函数都是类的成员函数 。当程序要对一个消息进行响应时,消息映射
机制就会自动调用该函数。用 ClassWizard 添加消息处理函数时,会自动添加以下 3 部分内
容:
o 在类的定义中添加该消息处理成员函数的函数声明;
o 在类的消息映射表中加入相应的消息映射表项;
o 在类的实现中加入该消息处理成员函数的函数实现。
注意 ClassWizard 添加的函数实现中,只是一个不能完成任何操作的空函数框架,还需
要加入具体的实现代码。但当用户手动添加消息处理函数时,也必须添加上述 3 部分内容。
对于标准 Windows 消息,在 CWnd 类中已经预定义了默认的处理函数,有确定的函数名,
一般以 On 开头,以消息名为函数名的后半部分,例如 WM_PAINT 消息的处理函数为
OnPaint(),WM_CREATE 消息处理函数是 OnCreate() 。这些预定义的消息处理函数根据消息
的不同有不同的参数和返回值。
对于控件通知消息和命令消息,一般没有默认的消息处理函数,可以由用户自定义。MFC
建议这类函数命名应遵循一些约定,一般以 On 开头,函数名中应包含该消息的简要说明,
ClassWizard 在创建这类消息处理函数时会提供一个建议的函数名,一般无需
方便阅读代码。
修改。例如 OnFileOpen()函数表明处理命令标识符 ID_FILE_OPEN 的命令消息。
本章和以后的章节都将主要利用 ClassWizard 为程序添加消息处理函数。因此下面简要
介绍一下 ClassWizard 对话框,如图 3…1 所示。在 IDE 主菜单栏中选择“View|ClassWizard ”
菜单命令,或者在开发环境的界面中直接按快捷键 Ctrl+W,即可打开“MFC ClassWizard ”
对话框。选择“Message Maps ”的选项卡,即可进行编辑消息映射的设置。
·44 ·
…………………………………………………………Page 54……………………………………………………………
第 3 章 菜单与加速键
图 3…1 消息映射选项卡
ClassWizard 对话框的“Message Maps ”(消息映射)选项卡中的各项功能介绍如下:
o Project (工程)下拉列表框:用于选择需要编辑的工程名称。
o Class name (类名)下拉列表框:用于选择需要编辑消息映射的类的名称。选择好类
后,在该下拉列表框 和“Project ”下拉列表框的下一行将显示所选类的头文件和源文
件路径。
o Object IDs (对象ID )列表框:以列表形式显示可以产生消息的对象的 ID,包括菜单
项、按钮等的 ID 。该列表框的第一项总是显示所选择的类。
o Messages (消息)列表框:列举在“Object IDs ”列表框中选定的对象所能产生的各种
消息。
o Member functions (成员函数)列表框:以列表形式显示选定的类中的成员函数。该列
表框中只列出与消息处理函数以及 MFC 中与消息处理有关的虚函数。前者标记为
“W ”,并在函数名后显示对应的消息映射宏;后者标记为“V ”。
o Add Class (添加类)按钮:单击该按钮,添加新的类到工程中。该按钮在“MFC
ClassWizard ”对话框中的所有选项卡中都存在。
o Add Function (添加函数)按钮:单击该按钮添加选定消息的新的消息处理函数,包
括在消息映射定义中添加对应的宏指令,在选定的类中添加该消息处理函数的声明和
完成基本功能的代码实现。如果选定的消息已经有消息处理函数,则该按钮无效。对
于对象产生的消息,单击该按钮将弹出如图 3…2 所示的对话框,要求用户输入消息处
理函数的名称,在“Member function name ”(成员函数名称)输入框中输入函数名,
确定后 ClassWizard 就会自动添加该消息处理函数。对于由该选定的类产生的消息,
MFC 已经定义好了消息处理函数名称,单击“Add Function ”按钮将直接添加该消息
处理函数,不会提示用户输入自定义的函数名。注意,只有单击“MFC ClassWizard ”
的“OK ”按钮或者“Edit Code ”按钮退出“MFC ClassWizard ”对话框后,ClassWizard
才会真正修改源文件。
·45 ·
…………………………………………………………Page 55……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
图 3…2 添加消息处理函数的对话框
o Delete Function (删除函数)按钮:单击该按钮删除选定消息的消息处理函数,包括函
数的声明和定义该消息映射的宏语句。如果选定的消息没有消息处理函数,则该按钮
无效。注意,当该函数已经存在于源文件中时,单击该按钮会提示如图 3…3 所示的对
话框,告诉用户 ClassWizard 只能删除该函数的声明和定义该消息映射的宏语句,而
无法删除该函数的实现代码,用户需要手动删除。
图 3…3 提示用户手动删除消息处理函数的对话框
o Edit Code (编辑代码)按钮:单击该按钮退出“MFC ClassWizard ”对话框,同时 IDE
的代码编辑窗口直接转到选定消息的处理函数进行编辑。该按钮也使得在“MFC
ClassWizard ”中所做的更改生效。如果选定的消息没有消息处理函数,则该按钮无效。
o OK (确定)按钮:单击该按钮使得在“MFC ClassWizard ”中的编辑生效,并退出“MFC
ClassWizard ”对话框。
o Cancel (取消)按钮:单击该按钮取消所有“MFC ClassWizard ”对话框中的设置,并
退出“MFC ClassWizard ”对话框。
3。1。3 消息处理过程
在 Windows 程序设计中,消息的处理是通过消息循环进行接收与分发的。MFC 运用消
息映射机制封装了这一处理过程。下面介绍 MFC 中消息的处理过程。
1.标准 Windows 消息和控件通知消息
标准 Windows 消息和控件通知消息的处理过程比较简单。这类消息必须由 CWnd 或其派
生类的对象处理,消息传递到封装对应的窗口或子窗口的类的对象中。也就是说,当关闭程
序的时候,会产生一个 WM_CLOSE 消息并通知主框架类,主框架类调用相应的处理函数进
行程序关闭前的清理操作,如保存文件和数据等。
2 .命令消息
命令消息与其他两个类型的消息不同,它可以由应用程序其他类的对象(例如应用类对
象、文档对象和文档模板对象)处理。这就涉及一个消息传递路径的问题,具体来说就是允
·46 ·
…………………………………………………………Page 56……………………………………………………………
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!