00. 目录
文章目录
-
- 00. 目录
- 01. 概述
- 02. 消息映射宏
-
- 2.1 BEGIN_MESSAGE_MAP
- 2.2 DECLARE_MESSAGE_MAP
- 2.3 END_MESSAGE_MAP
- 2.4 ON_COMMAND
- 2.5 ON_OLECMD
- 03. 委托和接口映射宏
- 04. 使用消息映射交叉引用
- 05. 子窗口通知消息处理程序
- 06. WM_ 消息的处理程序
- 07. 用户定义的处理程序
01. 概述
引用的此部分列出了所有 消息映射宏 以及所有 CWnd 消息映射项以及相应的成员函数原型:
类别 | 描述 |
---|---|
ON _ 命令消息处理程序 | 处理 WM_COMMAND 由用户菜单选择或菜单访问键生成的消息。 |
子窗口通知消息处理程序 | 从子窗口处理通知消息。 |
WM_ 消息处理程序 | 处理 WM_ 消息,如 WM_PAINT 。 |
用户定义的消息处理程序 | 处理用户定义的消息。 |
由于 Windows 是一种面向消息的操作系统,因此 Windows 环境的大部分编程操作都涉及消息处理。 每次发生击键或鼠标单击事件时,都会将一条消息发送到应用程序,然后该应用程序必须处理该事件。
Microsoft 基础类库提供了为基于消息的编程而优化的编程模型。 在此模型中,“消息映射” 用于指定哪些函数将处理特定类的各种消息。 消息映射包含一个或多个宏,这些宏指定哪些消息将由哪些功能处理。 例如,包含宏的消息映射 ON_COMMAND
可能类似于:
BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
ON_COMMAND(ID_MYCMD, &CMyDoc::OnMyCommand)
END_MESSAGE_MAP()
ON_COMMAND
宏用于处理由菜单、按钮和快捷键生成的命令消息。 可以使用宏来映射以下内容:
Windows 消息
- 控制通知
- 用户定义的消息
命令消息
- 已注册的用户定义消息
- 用户界面更新消息
消息范围
- 命令
- 更新处理程序消息
- 控制通知
02. 消息映射宏
消息映射声明和分界宏
名称 | 描述 |
---|---|
DECLARE_MESSAGE_MAP | 声明将在类中使用消息映射来将消息映射到函数(必须在类声明中使用)。 |
BEGIN_MESSAGE_MAP | 开始消息映射的定义(必须在类实现中使用)。 |
BEGIN_TEMPLATE_MESSAGE_MAP | 开始对包含单个模板参数的类类型的消息映射的定义。 |
END_MESSAGE_MAP | 结束消息映射的定义(必须在类实现中使用)。 |
消息映射宏
名称 | 描述 |
---|---|
ON_COMMAND | 指示哪个函数将处理指定的命令消息。 |
ON_COMMAND_EX | 指示哪个函数将处理指定的命令消息。 |
ON_CONTROL | 指示哪个函数将处理指定的控件通知消息。 |
ON_MESSAGE | 指示哪个函数将处理用户定义的消息。 |
ON_OLECMD | 指示哪个函数将处理 DocObject 或其容器中的菜单命令。 |
ON_REGISTERED_MESSAGE | 指示哪个函数将处理已注册的用户定义消息。 |
ON_REGISTERED_THREAD_MESSAGE | 指示哪个函数将在您具有 CWinThread 类时处理已注册的用户定义消息。 |
ON_THREAD_MESSAGE | 指示哪个函数将在您具有 CWinThread 类时处理用户定义的消息。 |
ON_UPDATE_COMMAND_UI | 指示哪个函数将处理指定的用户界面更新命令消息。 |
消息映射范围宏
名称 | 描述 |
---|---|
ON_COMMAND_RANGE | 指示哪个函数将处理在宏的前两个参数中指定的命令 ID 的范围。 |
ON_UPDATE_COMMAND_UI_RANGE | 指示哪个更新处理程序将处理在宏的前两个参数中指定的命令 ID 的范围。 |
ON_CONTROL_RANGE | 指示哪个函数将处理来自在宏的第二个和第三个参数中指定的控件 ID 的范围的通知。 第一个参数是控件通知消息,如 BN_CLICKED。 |
常用说明
2.1 BEGIN_MESSAGE_MAP
BEGIN_MESSAGE_MAP
开始您的消息映射的定义。
语法
BEGIN_MESSAGE_MAP( theClass, baseClass )
parameters
theClass
指定其消息映射所属的类的名称。
baseClass
指定 类 的基类的名称。
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_WM_CREATE()
END_MESSAGE_MAP()
备注
在实现 ( .cpp) 文件中,该文件定义了类的成员函数,启动带有 BEGIN_MESSAGE_MAP 宏的消息映射,然后为每个消息处理函数添加宏项,并通过 END_MESSAGE_MAP 宏完成消息映射。
2.2 DECLARE_MESSAGE_MAP
声明类定义消息映射。 CCmdTarget
程序中的每个派生类必须提供消息映射来处理消息。
DECLARE_MESSAGE_MAP( )
备注
在类声明的末尾使用 DECLARE_MESSAGE_MAP 宏。 然后,在定义类的成员函数的 .cpp 文件中,使用 BEGIN_MESSAGE_MAP 宏、每个消息处理函数的宏项和 END_MESSAGE_MAP 的宏。
如果在 DECLARE_MESSAGE_MAP 后声明任何成员,则必须为它们指定新的访问类型 (
public
、private
或protected
) 。
示例
class CMainFrame : public CMDIFrameWnd
{
DECLARE_MESSAGE_MAP()
// Remainder of class declaration omitted.
}
2.3 END_MESSAGE_MAP
结束消息映射的定义。
END_MESSAGE_MAP( )
2.4 ON_COMMAND
此宏将命令消息映射到成员函数。
ON_COMMAND( commandId, memberFxn )
parameters
commandId
命令 ID。
memberFxn
命令映射到的消息处理程序函数的名称。
参考示例
BEGIN_MESSAGE_MAP(CMFCListViewDoc, CDocument)
ON_COMMAND(ID_MYCOMMAND, &CMFCListViewDoc::OnMycommand)
END_MESSAGE_MAP()
备注
它指示哪个函数将处理命令用户界面对象(如菜单项或工具栏按钮)的命令消息。
当命令目标对象收到具有指定 ID 的 Windows WM_COMMAND 消息时,ON_COMMAND 将调用成员函数
memberFxn
来处理该消息。使用 ON_COMMAND 将单个命令映射到成员函数。 使用 ON_COMMAND_RANGE 将一系列命令 id 映射到一个成员函数。 只有一个消息映射项可以匹配给定的命令 ID。 也就是说,不能将命令映射到多个处理程序。 有关详细信息和示例,请参阅 消息处理和映射主题。
2.5 ON_OLECMD
通过命令调度接口路由命令 IOleCommandTarget
。
ON_OLECMD( pguid, olecmdid, commandId )
parameters
pguid
命令所属的命令组的标识符。 对于标准组,请使用 NULL。
olecmdid
OLE 命令的标识符。
commandId
发出命令的资源或对象的菜单 ID、工具栏 ID、按钮 ID 或其他 ID。
备注
IOleCommandTarget
允许容器接收源自 DocObject 的用户界面的命令,并允许容器在 “文件” 菜单上发送相同的 (命令,如 “新建”、“打开”、“另存” 和 “打印”。以及复制、粘贴、撤消等操作,请在 “编辑” 菜单中) DocObject。
IOleCommandTarget
比 OLE 自动化的更简单IDispatch
。IOleCommandTarget
完全依赖于一组标准的命令,这些命令很少包含参数,并且不涉及任何类型信息 (命令参数的类型安全降低) 。 如果确实需要调度带有参数的命令,请使用 COleServerDoc:: OnExecOleCmd。
IOleCommandTarget
标准菜单命令已由 MFC 在下列宏中实现:ON_OLECMD_CLEARSELECTION ( )
调度 “编辑清除” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_CLEARSELECTION, ID_EDIT_CLEAR)
ON_OLECMD_COPY ( )
调度编辑复制命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_COPY, ID_EDIT_COPY)
ON_OLECMD_CUT ( )
调度 “编辑剪切” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_CUT, ID_EDIT_CUT)
ON_OLECMD_NEW ( )
调度 File New 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_NEW, ID_FILE_NEW)
ON_OLECMD_OPEN ( )
调度文件打开命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_OPEN, ID_FILE_OPEN)
ON_OLECMD_PAGESETUP ( )
调度文件页面设置命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_PAGESETUP, ID_FILE_PAGE_SETUP)
ON_OLECMD_PASTE ( )
调度 “编辑粘贴” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_PASTE, ID_EDIT_PASTE)
ON_OLECMD_PASTESPECIAL ( )
调度 “编辑” “选择性粘贴” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_PASTESPECIAL, ID_EDIT_PASTE_SPECIAL)
ON_OLECMD_PRINT ( )
调度文件打印命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_PRINT, ID_FILE_PRINT)
ON_OLECMD_PRINTPREVIEW ( )
调度文件 “打印预览” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_PRINTPREVIEW, ID_FILE_PRINT_PREVIEW)
ON_OLECMD_REDO ( )
调度编辑重做命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_REDO, ID_EDIT_REDO)
ON_OLECMD_SAVE ( )
调度文件保存命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_SAVE, ID_FILE_SAVE)
ON_OLECMD_SAVE_AS ( )
调度文件的 “另存为” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_SAVEAS, ID_FILE_SAVE_AS)
ON_OLECMD_SAVE_COPY_AS ( )
调度 “文件另存为” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_SAVECOPYAS, ID_FILE_SAVE_COPY_AS)
ON_OLECMD_SELECTALL ( )
调度 “编辑全部选择” 命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_SELECTALL, ID_EDIT_SELECT_ALL)
ON_OLECMD_UNDO ( )
调度 “编辑” 撤消命令。 实现方式:
ON_OLECMD(NULL, OLECMDID_UNDO, ID_EDIT_UNDO)
03. 委托和接口映射宏
MFC 为委托和接口映射支持以下宏:
名称 | 描述 |
---|---|
BEGIN_DELEGATE_MAP | 开始一个委托映射。 |
BEGIN_INTERFACE_MAP | 开始接口映射的定义。 |
CommandHandler 委托 | 向命令源注册回调方法。 |
END_DELEGATE_MAP | 结束委托映射。 |
END_INTERFACE_MAP | 终止实现文件中的接口映射。 |
EVENT_DELEGATE_ENTRY | 在委托映射中创建条目。 |
INTERFACE_PART | 用于 BEGIN_INTERFACE_MAP 宏与对象将支持的每个接口的 END_INTERFACE_MAP 宏。 |
MAKE_DELEGATE | 将事件处理程序附加到托管控件。 |
04. 使用消息映射交叉引用
在标记为的项中 ,为派生的 CWnd 类编写你自己的成员函数。 将函数命名为您喜欢的任何名称。 其他函数,如 OnActivate
,是 CWnd
类的成员函数。 如果调用这些函数,则会传递消息给 DefWindowProc
Windows 函数。 要处理 Windows 通知消息,请重写派生类中相应的 CWnd
函数。 您的函数应调用基类中的重写函数使基类和 Windows 响应消息。
在所有情况下,请将函数原型放在 CWnd
派生的类标头中,并对消息映射条目进行编码,如下所示。
使用了以下术语:
术语 | 定义 |
---|---|
id | 任何用户定义的菜单项 ID(WM_COMMAND 消息)或控件 ID(子窗口通知消息)。 |
“message”和“wNotifyCode” | 在 WINDOWS.H 中定义的 Windows 消息 ID。 |
nMessageVariable | 包含 Windows 函数返回值的变量的名称 RegisterWindowMessage 。 |
05. 子窗口通知消息处理程序
有五种类别的子窗口通知消息:
类别 | 描述 |
---|---|
泛型控件处理程序 | 泛型控件通知代码的处理程序。 |
用户按钮处理程序 | 用户按钮通知代码的处理程序。 |
组合框处理程序 | 组合框通知代码的处理程序。 |
编辑控件处理程序 | 编辑控件通知代码的处理程序。 |
列表框处理程序 | 列表框通知代码的处理程序。 |
06. WM_ 消息的处理程序
以下主题对应于映射条目。
主题 | 映射条目 |
---|---|
A - C | 通过 ON_WM_CTLCOLOR ON_WM_ACTIVATE |
D - E | 通过 ON_WM_ERASEBKGND ON_WM_DEADCHAR |
F - K | 通过 ON_WM_KILLFOCUS ON_WM_FONTCHANGE |
L - M | 通过 ON_WM_MOVING ON_WM_LBUTTONDBLCLK |
N - O | 通过 ON_WM_NCRBUTTONUP ON_WM_NCACTIVATE |
P - R | 通过 ON_WM_RENDERFORMAT ON_WM_PAINT |
S | 通过 ON_WM_SYSKEYUP ON_WM_SETCURSOR |
T - Z | 通过 ON_WM_WININICHANGE ON_WM_TIMECHANGE |
07. 用户定义的处理程序
以下映射项对应于函数原型。
映射条目 | 函数原型 |
---|---|
ON_MESSAGE ( , ) | afx_msg LRESULT memberFxn ( WPARAM,LPARAM ) ; |
ON_REGISTERED_MESSAGE ( , ) | afx_msg LRESULT memberFxn ( WPARAM,LPARAM ) ; |
ON_THREAD_MESSAGE ( , ) | afx_msg void memberFxn ( WPARAM、LPARAM ) ; |
ON_REGISTERED_THREAD_MESSAGE ( , ) | afx_msg void memberFxn ( WPARAM、LPARAM ) ; |