消息映射宏 (MFC)

为了支持消息映射,MFC 提供了以下宏:

消息映射声明和分界宏

名称 描述
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

有关消息映射、消息映射声明和分界宏,以及消息映射宏的详细信息,请参阅消息映射消息处理和映射主题。 有关消息映射范围的详细信息,请参阅消息映射范围的处理程序

BEGIN_MESSAGE_MAP

开始消息映射的定义。

语法

BEGIN_MESSAGE_MAP( theClass, baseClass )

参数

theClass
指定其消息映射的类的名称。

baseClass
指定 theClass 的基类的名称。

备注

在定义类的成员函数的实现 (.cpp) 文件中,使用 BEGIN_MESSAGE_MAP 宏开始消息映射,为每个消息处理程序函数添加宏条目,然后使用 END_MESSAGE_MAP 宏完成消息映射。

有关消息映射的详细信息,请参阅消息映射

示例

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
   ON_WM_CREATE()
END_MESSAGE_MAP()

要求

标头afxwin.h

BEGIN_TEMPLATE_MESSAGE_MAP

开始在包含单个模板参数的类类型上定义消息映射。

语法

BEGIN_TEMPLATE_MESSAGE_MAP( theClass, type_name, baseClass )

参数

theClass
指定其消息映射的类的名称。

type_name
为类指定的模板参数的名称。

baseClass
指定 theClass 的基类的名称。

备注

此宏类似于 BEGIN_MESSAGE_MAP 宏;但是,此宏适用于包含单个模板参数的类。

在类的方法实现部分中,使用 BEGIN_TEMPLATE_MESSAGE_MAP 宏开始消息映射;然后为每个消息处理程序方法添加宏条目,就像对标准消息映射的操作一样。 与 BEGIN_MESSAGE_MAP 宏一样,使用 END_MESSAGE_MAP 宏完成模板消息映射。

有关为模板类实现消息映射的详细信息,请参阅如何:为模板类创建消息映射

要求

标头afxwin.h

DECLARE_MESSAGE_MAP

声明类定义了一个消息映射。 程序中的每个 CCmdTarget 派生类都必须提供消息映射来处理消息。

语法

DECLARE_MESSAGE_MAP( )

备注

在类声明末尾使用 DECLARE_MESSAGE_MAP 宏。 然后,在定义类的成员函数的 .cpp 文件中,使用 BEGIN_MESSAGE_MAP 宏、每个消息处理程序函数的宏条目以及 END_MESSAGE_MAP 宏。

注意

如果在 DECLARE_MESSAGE_MAP 之后声明任何成员,必须为它们指定新的访问类型(publicprivateprotected)。

有关消息映射和 DECLARE_MESSAGE_MAP 宏的详细信息,请参阅消息处理和映射主题

示例

class CMainFrame : public CMDIFrameWnd
{
   DECLARE_MESSAGE_MAP()

   // Remainder of class declaration omitted.

要求

标头afxwin.h

END_MESSAGE_MAP

结束消息映射的定义。

语法

END_MESSAGE_MAP( )

备注

有关消息映射和 END_MESSAGE_MAP 宏的详细信息,请参阅消息处理和映射主题

要求

标头afxwin.h

ON_COMMAND

此宏将命令消息映射到成员函数。

语法

ON_COMMAND( commandId, memberFxn )

参数

commandId
命令 ID。

memberFxn
命令映射到的消息处理程序函数的名称。

备注

它指示哪个函数将处理来自命令用户界面对象(如菜单项或工具栏按钮)的命令消息。

当命令目标对象接收具有指定 ID 的 Windows WM_COMMAND 消息时,ON_COMMAND 将调用成员函数 memberFxn 来处理该消息。

使用 ON_COMMAND 将单个命令映射到成员函数。 使用 ON_COMMAND_RANGE 将命令 ID 的范围映射到一个成员函数。 只有一个消息映射条目可以匹配给定的命令 ID。 也就是说,无法将一个命令映射到多个处理程序。 有关详细信息和示例,请参阅消息处理和映射主题

示例

BEGIN_MESSAGE_MAP(CMFCListViewDoc, CDocument)
   ON_COMMAND(ID_MYCOMMAND, &CMFCListViewDoc::OnMycommand)
END_MESSAGE_MAP()

要求

标头afxmsg_.h

ON_COMMAND_EX

扩展的命令处理程序成员函数。

语法

ON_COMMAND_EX(commandId, memberFxn);

参数

commandId
命令 ID。

memberFxn
命令映射到的消息处理程序函数的名称。

备注

命令消息处理程序的扩展形式可用于高级用途。 ON_COMMAND_EX 宏用于此类消息处理程序,它提供了 ON_COMMAND 功能的一个超集。 扩展的命令处理程序成员函数采用单个参数(一个包含命令 ID 的 UINT),并返回 BOOL。 返回值应为 TRUE,指示已处理命令;否则,将继续路由到其他命令目标对象。

有关详细信息,请参阅“技术说明 [TN006:消息映射]tm006-message-maps.md)”。

要求

头文件:afxmsg_.h

ON_CONTROL

指示哪个函数将处理自定义控件通知消息。

语法

ON_CONTROL( wNotifyCode, commandId, memberFxn )

参数

wNotifyCode
控件的通知代码。

commandId
命令 ID。

memberFxn
命令映射到的消息处理程序函数的名称。

注解

控件通知消息是从控件发送到其父窗口的通知消息。

对于必须映射到消息处理程序函数的每个控件通知消息,消息映射中应正好有一个 ON_CONTROL 宏语句。

有关详细信息和示例,请参阅消息处理和映射主题

要求

标头afxmsg_.h

ON_MESSAGE

指示哪个函数将处理用户定义的消息。

语法

ON_MESSAGE( message, memberFxn )

参数

message
消息 ID。

memberFxn
消息映射到的消息处理程序函数的名称。

函数的类型必须为 afx_msg LRESULT (CWnd::*)(WPARAM, LPARAM)

注解

用户定义消息是不属于标准 Windows WM_MESSAGE 消息的任何消息。 选择消息 ID 时,必须使用 WM_USER (0x0400) 到 0x7FFF 或 WM_APP (0x8000) 到 0xBFFF 范围内的值。 有关消息 ID 的详细信息,请参阅 WM_APP

对于必须映射到消息处理程序函数的每个用户定义消息,消息映射中应正好有一个 ON_MESSAGE 宏语句。

注意

除了用户定义消息外,ON_MESSAGE 还处理不太常见的 Windows 消息。 有关详细信息,请参阅消息映射

有关详细信息和示例,请参阅消息处理和映射主题用户定义的处理程序

示例

#define WM_MYMESSAGE (WM_USER + 100)

BEGIN_MESSAGE_MAP(CMyWnd2, CWnd)
   ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()

// inside the class declaration
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

LRESULT CMyWnd2::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
   UNREFERENCED_PARAMETER(wParam);
   UNREFERENCED_PARAMETER(lParam);

   // Handle message here.

   return 0;
}

要求

标头afxmsg_.h

ON_OLECMD

通过命令调度接口 IOleCommandTarget 路由命令。

语法

ON_OLECMD( pguid, olecmdid, commandId )

参数

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( )

调度“文件新建”命令。 实现为:

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)

要求

标头afxdocob.h

ON_REGISTERED_MESSAGE

Windows RegisterWindowMessage 函数用于定义一个新的窗口消息,可保证该消息在整个系统中是唯一的。

语法

ON_REGISTERED_MESSAGE( nMessageVariable, memberFxn )

参数

nMessageVariable
已注册的窗口消息 ID 变量。

memberFxn
消息映射到的消息处理程序函数的名称。

备注

此宏指示哪个函数将处理已注册的消息。

有关详细信息和示例,请参阅消息处理和映射主题

示例

static UINT NEAR WM_FIND = RegisterWindowMessage(_T("COMMDLG_FIND"));

BEGIN_MESSAGE_MAP(CMyWnd3, CWnd)
   ON_REGISTERED_MESSAGE(WM_FIND, OnFind)
END_MESSAGE_MAP()

要求

标头afxmsg_.h

ON_REGISTERED_THREAD_MESSAGE

指示哪个函数将处理由 Windows RegisterWindowMessage 函数注册的消息。

语法

ON_REGISTERED_THREAD_MESSAGE(nMessageVariable, memberFxn )

参数

nMessageVariable
已注册的窗口消息 ID 变量。

memberFxn
消息映射到的 CWinThread 消息处理程序函数的名称。

注解

RegisterWindowMessage 用于定义一个新的窗口消息,可保证在整个系统中是唯一的。 当你有 CWinThread 类时,必须使用 ON_REGISTERED_THREAD_MESSAGE,而不是 ON_REGISTERED_MESSAGE

要求

标头afxmsg_.h

ON_THREAD_MESSAGE

指示哪个函数将处理用户定义的消息。

语法

ON_THREAD_MESSAGE( message, memberFxn )

参数

message
消息 ID。

memberFxn
消息映射到的 CWinThread 消息处理程序函数的名称。

备注

当你有 CWinThread 类时,必须使用 ON_THREAD_MESSAGE,而不是 ON_MESSAGE。 用户定义消息是不属于标准 Windows WM_MESSAGE 消息的任何消息。 对于必须映射到消息处理程序函数的每个用户定义消息,消息映射中应正好有一个 ON_THREAD_MESSAGE 宏语句。

要求

标头afxole.h

ON_UPDATE_COMMAND_UI

此宏指示哪个函数将处理用户界面更新命令消息。

语法

ON_UPDATE_COMMAND_UI( messageId, memberFxn )

参数

messageId
消息 ID。

memberFxn
消息映射到的消息处理程序函数的名称。

注解

对于必须映射到消息处理程序函数的每个用户界面更新命令,消息映射中应正好有一个 ON_UPDATE_COMMAND_UI 宏语句。

有关详细信息和示例,请参阅消息处理和映射主题

要求

标头afxole.h

ON_COMMAND_RANGE

使用此宏将一个连续的命令 ID 范围映射到单个消息处理程序函数。

语法

ON_COMMAND_RANGE( id1, id2, memberFxn )

参数

id1
位于连续命令 ID 范围开头的命令 ID。

id2
位于连续命令 ID 范围末尾的命令 ID。

memberFxn
命令映射到的消息处理程序函数的名称。

备注

ID 的范围以 id1 开头,以 id2 结尾。

使用 ON_COMMAND_RANGE 将命令 ID 的范围映射到一个成员函数。 使用 ON_COMMAND 将单个命令映射到成员函数。 只有一个消息映射条目可以匹配给定的命令 ID。 也就是说,无法将一个命令映射到多个处理程序。 有关映射消息范围的详细信息,请参阅消息映射范围的处理程序

没有对消息映射范围的自动支持,因此必须自行放置宏。

示例

// The code fragment below shows how to use ON_COMMAND_RANGE macro
// to map a contiguous range of command IDs to a single message
// handler function (i.e. OnRangeCmds() in the sample below). In
// addition, it also shows how to use CheckMenuRadioItem() to check a
// selected menu item and makes it a radio item.

BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
   ON_COMMAND_RANGE(ID_COMMAND_RANGECMD1, ID_COMMAND_RANGECMD3, &CChildFrame::OnRangeCmds)
END_MESSAGE_MAP()

void CChildFrame::OnRangeCmds(UINT nID)
{
   CMenu* mmenu = AfxGetMainWnd()->GetMenu();
   CMenu* submenu = mmenu->GetSubMenu(5);
   submenu->CheckMenuRadioItem(ID_COMMAND_RANGECMD1, ID_COMMAND_RANGECMD3,
      nID, MF_BYCOMMAND);
}

要求

标头afxmsg_.h

ON_UPDATE_COMMAND_UI_RANGE

将连续的命令 ID 范围映射到单个更新消息处理程序函数。

语法

ON_UPDATE_COMMAND_UI_RANGE( id1, id2, memberFxn )

参数

id1
位于连续命令 ID 范围开头的命令 ID。

id2
位于连续命令 ID 范围末尾的命令 ID。

memberFxn
命令映射到的更新消息处理程序函数的名称。

注解

更新消息处理程序可以更新与命令关联的菜单项和工具栏按钮的状态。 ID 的范围以 id1 开头,以 id2 结尾。

没有对消息映射范围的自动支持,因此必须自行放置宏。

要求

标头afxmsg_.h

ON_CONTROL_RANGE

使用此宏将连续的控件 ID 范围映射到指定的 Windows 通知消息的单个消息处理程序函数,例如 BN_CLICKED

语法

ON_CONTROL_RANGE( wNotifyCode, id1, id2, memberFxn )

参数

wNotifyCode
处理程序要响应的通知代码。

id1
位于连续控件 ID 范围开头的命令 ID。

id2
位于连续控件 ID 范围末尾的命令 ID。

memberFxn
控件映射到的消息处理程序函数的名称。

备注

ID 的范围以 id1 开头,以 id2 结尾。 为来自任何映射控件的指定通知调用处理程序。

没有对消息映射范围的自动支持,因此必须自行放置宏。

有关为控件 ID 范围实现处理程序函数的详细信息,请参阅消息映射范围的处理程序

要求

标头afxmsg_.h

另请参阅

ON_COMMAND
TN006:消息映射
COleCmdUI
COleServerDoc::OnExecOleCmd
RegisterWindowMessage
用户定义的处理程序
CCmdUI