TN006:消息映射

此说明描述了 MFC 消息映射设备。

问题

Microsoft Windows 实现在使用其消息处理设备的窗口类的虚函数。 由于涉及的大量消息,提供一个单独的虚函数为每个窗口消息将创建一个禁止大 vtable。

由于系统定义的 windows 消息的数量,随着时间的推移,并且,由于应用程序可以定义自己的窗口消息,消息映射提供阻止破坏现有代码的接口更改的间接寻址。

概述

MFC 提供了一种替代用于处理信息的传统的基于 windows 的程序发送到窗口中的 switch 语句。 映射从消息添加到方法中定义,这样,当消息由 windows 时收到,适当的方法自动调用。 此消息映射设备设计类似于虚函数,但优点不能对 C++ 虚函数。

定义消息映射

DECLARE_MESSAGE_MAP 宏声明类的三个成员。

  • 私有一些 AFX_MSGMAP_ENTRY 项调用 _messageEntries。

  • 指向 _messageEntries 数组的受保护的 AFX_MSGMAP 结构调用 messageMap 。

  • 返回 messageMap地址的受保护的虚函数调用 GetMessageMap

在任何类的声明应将使用消息映射,此宏。 按照约定,它是在类声明的末尾。 例如:

class CMyWnd : public CMyParentWndClass
{
    // my stuff...

protected:
    //{{AFX_MSG(CMyWnd)
    afx_msg void OnPaint();
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

,在创建新的类时,这是 AppWizard 生成的格式和类向导。 //和 //{}} 括号用于访问 ClassWizard 是必需的。

消息映射中的表是使用扩展到消息映射项宏的设置。 表从 BEGIN_MESSAGE_MAP 启动宏调用中,定义类由此消息映射处理,并且父类处理消息传递。 与 END_MESSAGE_MAP 的表结束宏调用。

在这两之间宏调用是此消息映射要处理的每个消息的项。 每个标准 windows 消息具有生成该消息的项窗体 ON_WM_MESSAGE_NAME 的宏。

标准函数签名用于打开每个窗口消息的参数并提供类型定义安全。 这些签名在 CWnd声明的文件 Afxwin.h 能找到。 每个标有用户识别的关键字 afx_msg 。

备注

类向导需要您在消息映射处理程序声明使用 afx_msg 关键字。

通过使用简单的约定,这些函数签名派生的。 函数的名称从 "On始终以”。 后跟 windows 消息与 “WM_”移除的和大写的每个单词的首字母大写。 排序参数是 LOWORD执行的 wParam (lParam) 然后 HIWORD(lParam)。 未使用的参数不是。 由 MFC 类包装的任何句柄转换为指向相应的 MFC 对象的指针。 下面的示例演示处理 WM_PAINT 消息以及如何使 CMyWnd::OnPaint 函数调用:

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
    //{{AFX_MSG_MAP(CMyWnd)
    ON_WM_PAINT()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

必须定义在这些函数或类定义的范围外,消息映射表。 在外部 “C”不应将其放入块。

备注

类向导将修改出现在 //的消息映射项和 //{}} 注释括号内。

用户定义的 windows 消息

使用 ON_MESSAGE 宏,用户定义的在消息映射可能包括。 此宏接受一个消息号和窗体的方法:

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

    #define WM_MYMESSAGE (WM_USER + 100)

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
    ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()

在此示例中,我们建立与用户定义的消息的标准 WM_USER 基派生的 windows 消息 ID 的自定义消息处理程序。 下面的示例演示如何调用此处理程序:

CWnd* pWnd = ...;
pWnd->SendMessage(WM_MYMESSAGE);

使用此方法用户定义的消息的大小必须在范围 WM_USER 到 0x7fff。

备注

类向导不支持从类向导用户界面的访问权限的 ON_MESSAGE 处理程序实例。必须从 Visual C++ 编辑器手动输入它们。类向导将分析这些项并可用来浏览它们与任何其他消息映射项。

注册窗口消息

RegisterWindowMessage 函数用于定义确保为唯一的在系统中的一个新的 windows 消息。 宏 ON_REGISTERED_MESSAGE 用于处理这些消息。 此宏接受包含注册窗口消息 ID UINT NEAR 变量的名称 例如

class CMyWnd : public CMyParentWndClass
{
public:
    CMyWnd();

    //{{AFX_MSG(CMyWnd)
    afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

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

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
    //{{AFX_MSG_MAP(CMyWnd)
    ON_REGISTERED_MESSAGE(WM_FIND, OnFind)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

注册窗口消息 ID 变量 (在本例中 WM_FIND) 必须是 NEAR 变量由于 ON_REGISTERED_MESSAGE 实现的方式。

使用此方法用户定义的消息的大小在范围 0xC000 到 0xFFFF。

备注

类向导不支持从类向导用户界面的访问权限的 ON_REGISTERED_MESSAGE 处理程序实例。必须从文本编辑器手动输入它们。类向导将分析这些项并可用来浏览它们与任何其他消息映射项。

命令消息

从菜单和快捷键的命令消息与 ON_COMMAND 宏的消息映射进行处理。 此宏接受一个命令 ID 和方法。 具有 wParam 等于指定的命令 ID 只的特定 WM_COMMAND 消息用消息映射项指定的方法处理。 命令函数不采用参数的处理程序并将返回 void。 宏具有以下形式:

ON_COMMAND(id, memberFxn)

命令更新消息传递同一个结构路由,但是,使用 ON_UPDATE_COMMAND_UI 宏。 命令更新函数采用单个参数的处理程序成员,对 CCmdUI 对象的指针,并返回 void。 宏有窗体

ON_UPDATE_COMMAND_UI(id, memberFxn)

高级用户可以使用 ON_COMMAND_EX 宏,是命令消息处理程序中的一个扩展的窗体。 宏提供 ON_COMMAND 功能的扩展。 扩展的命令处理程序成员函数采用包含命令 ID 的一个参数, UINT ,并返回 BOOL。 返回值应该是指示的 TRUE 命令已得到处理。 否则路由将继续其他命令目标对象。

这些窗体的示例:

  • 内部 Resource.h (通常是生成由 Visual C++)

    #define    ID_MYCMD      100
    #define    ID_COMPLEX    101
    
  • 在类声明的内部

    afx_msg void OnMyCommand();
    afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI);
    afx_msg BOOL OnComplexCommand(UINT nID);
    
  • 在消息映射定义中

    ON_COMMAND(ID_MYCMD, OnMyCommand)
    ON_UPDATE_COMMAND_UI(ID_MYCMD, OnUpdateMyCommand)
    ON_COMMAND_EX(ID_MYCMD, OnComplexCommand)
    
  • 在实现文件

    void CMyClass::OnMyCommand()
    {
        // handle the command
    }
    
    void CMyClass::OnUpdateMyCommand(CCmdUI* pCmdUI)
    {
        // set the UI state with pCmdUI
    }
    
    BOOL CMyClass::OnComplexCommand(UINT nID)
    {
        // handle the command
        return TRUE;
    }
    

使用一条命令处理程序,高级用户可以处理应用程序中的命令的大小: ON_COMMAND_RANGEON_COMMAND_RANGE_EX。 请参见产品文档有关这些宏的更多信息。

备注

类向导支持创建 ON_COMMANDON_UPDATE_COMMAND_UI 处理程序,但是,它不支持创建 ON_COMMAND_EXON_COMMAND_RANGE 处理程序。但是,类向导将分析并可用来浏览所有四个命令处理程序变量。

控件通知消息

从子级发送的消息控件添加到窗口有多余位信息在其消息映射项:控件的 ID. ,只有满足以下条件,在消息映射项指定的消息处理程序调用:

  • 控件通知代码 ( lParam的高位字中。),如 BN_CLICKED,与消息映射项指定的通知代码。

  • 控件 ID (wParam) 与消息映射项指定的控件 ID。

自定义控件通知消息可以使用 ON_CONTROL 宏定义使用自定义通知代码的消息映射项。 此宏有窗体

ON_CONTROL(wNotificationCode, id, memberFxn)

对高级使用 ON_CONTROL_RANGE 可用于处理从控件大小的特定控件通知与同一处理程序中。

备注

类向导不支持创建 ON_CONTROLON_CONTROL_RANGE 处理程序在用户界面。您必须手动输入它们与文本编辑器。类向导将分析这些项并可用来浏览它们与任何其他消息映射项。

windows 公共控件用于复杂控件通知使用更强大的 WM_NOTIFY 。 使用 ON_NOTIFYON_NOTIFY_RANGE 宏, MFC 此版本的对此新消息直接支持。 请参见产品文档有关这些宏的更多信息。

请参见

其他资源

由Number "技术说明

技术说明按类别