消息映射范围的处理程序

本文介绍如何将一系列消息映射到单个消息处理程序函数(而不是只将一条消息映射到一个函数)。

有时需要以完全相同的方式处理多个消息或控件通知。 这种情况下,可能希望将所有消息映射到单个处理程序函数。 借助消息映射范围,可以针对一系列连续的消息执行此操作:

  • 可以将一系列命令 ID 映射到:

    • 命令处理程序函数。

    • 命令更新处理程序函数。

  • 可以针对一系列控件 ID 将控件通知消息映射到消息处理程序函数。

本文涉及的主题包括:

编写消息映射条目

在 .CPP 文件中添加消息映射条目,如以下示例所示:

ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, &OnDoSomething)

消息映射条目包含以下项:

  • 消息映射范围宏:

  • 宏的参数:

    前两个宏采用三个参数:

    • 范围中开始的命令 ID

    • 范围中结束的命令 ID

    • 消息处理程序函数的名称

    这一系列命令 ID 必须是连续的。

    第三个宏 ON_CONTROL_RANGE 还采用控件通知消息作为第一个参数,例如 EN_CHANGE

声明处理程序函数

在 .H 文件中添加处理程序函数声明。 以下代码显示此操作:

public:
   afx_msg void OnDoSomething(UINT nID);

单个命令的处理程序函数通常不使用参数。 消息映射范围处理程序函数需要额外的 UINT 类型的参数 nID,更新处理程序函数不需要。 此参数是第一个参数。 额外参数包含指定用户实际所选命令所需的额外命令 ID。

若要详细了解更新处理程序函数的参数要求,请参阅一系列命令 ID 的示例

一系列命令 ID 的示例

使用范围的一种情况是处理 MFC 示例 HIERSVR 中 Zoom 命令等命令。 此命令缩放视图,将其缩放为正常大小的 25% 到 300%。 HIERSVR 的视图类使用范围来处理 Zoom 命令,其消息映射条目类似以下内容:

ON_COMMAND_RANGE(ID_VIEW_ZOOM25, ID_VIEW_ZOOM300, &OnZoom)

编写消息映射条目时,请指定:

  • 两个命令 ID,用以开始和结束这一连续的范围。

    此处它们是 ID_VIEW_ZOOM25 和 ID_VIEW_ZOOM300

  • 命令的处理程序函数的名称。

    此处是 OnZoom

函数声明如下所示:

public:
   afx_msg void OnZoom(UINT nID);

更新处理程序函数的情况类似,也非常适合使用范围,并且可能在更多情况下需要用到。 为大量命令编写 ON_UPDATE_COMMAND_UI 处理程序并一再编写或复制相同的代码,这是相当常见的。 解决方案是使用 ON_UPDATE_COMMAND_UI_RANGE 宏将一系列命令 ID 映射到一个更新处理程序函数。 命令 ID 的范围必须是连续的区间。 有关示例,请参阅 HIERSVR 示例视图类中的 OnUpdateZoom 处理程序及其 ON_UPDATE_COMMAND_UI_RANGE 消息映射条目。

单个命令的更新处理程序函数通常采用 CCmdUI* 类型的单个参数 pCmdUI。 不同于处理程序函数,消息映射范围的更新处理程序函数不需要额外的 UINT 类型的参数 nIDCCmdUI 对象中包含指定用户实际所选命令所需的命令 ID。

一系列控件 ID 的示例

还有一种情况也很有趣,就是针对一系列控件 ID 将控件通知消息映射到单个处理程序。 假设用户可以单击 10 个按钮中的任意按钮。 若要将所有 10 个按钮映射到一个处理程序,消息映射条目如下所示:

ON_CONTROL_RANGE(BN_CLICKED, IDC_BUTTON1, IDC_BUTTON10, OnButtonClicked)

在消息映射中编写 ON_CONTROL_RANGE 宏时,请指定:

  • 特定的控件通知消息。

    此处是 BN_CLICKED

  • 与一系列连续控件关联的控件 ID 值。

    此处是 IDC_BUTTON1 和 IDC_BUTTON10

  • 消息处理程序函数的名称。

    此处是 OnButtonClicked

编写处理程序函数时,请指定额外的 UINT 参数,如下所示

void CRangesView::OnButtonClicked(UINT nID)
{
   int nButton = nID - IDC_BUTTON1;
   ASSERT(nButton >= 0 && nButton < 10);
   // ...
}

单个 BN_CLICKED 消息的 OnButtonClicked 处理程序不采用任何参数。 一系列按钮的同一处理程序采用一个 UINT。 使用额外参数可以标识负责生成 BN_CLICKED 消息的特定控件

示例中显示的代码很典型:转换传递给消息范围内 int 的值并断言就是这种情况。 然后可以根据单击的按钮采取其他一些操作。

另请参阅

声明消息处理程序函数