标准 Windows 消息的处理程序
标准 Windows 消息 (WM_) 的默认处理程序是在 CWnd
类中预定义的。 类库基于消息名称来命名这些处理程序的名称。 例如,WM_PAINT 消息的处理程序在 CWnd
中声明为:
afx_msg void OnPaint();
afx_msg 关键字通过区分处理程序与其他 CWnd
成员函数来建议 C++ virtual
关键字的效果。 但请注意,这些函数实际上都不是虚函数;它们是通过消息映射实现的。 消息映射仅取决于标准预处理器宏,而不是 C++ 语言的任何扩展。 在预处理后,afx_msg 关键字解析为空格。
若要重写基类中定义的处理程序,只需使用派生类中相同的原型定义一个函数,并为处理程序生成一个消息映射条目。 您的处理程序将“重写”任何类的基类中名称相同的任意处理程序。
在某些情况下,您的处理程序应当调用基类中的已重写处理程序,以便基类和 Windows 可处理消息。 在重写中调用基类处理程序的位置取决于环境。 有时您必须首先调用基类,有时最后调用。 有时如果您选择不处理消息,则将有条件地调用基类处理程序。 有时你应调用基类处理程序,然后根据基类处理程序返回的值或状态有条件地执行你自己的处理程序代码。
注意
如果您打算将传入处理程序的参数传递到基类处理程序,则修改这些参数不安全。 例如,你可能尝试修改 OnChar
处理程序的 nChar 参数(例如,转换为大写)。 此行为非常含糊,但如果你需要实现此效果,请改用 CWnd
成员函数 SendMessage
。
如何确定用于重写给定消息的合适方法:当类向导为给定消息编写处理程序函数的框架时(例如,WM_CREATE 的 OnCreate
处理程序),它会按建议的重写成员函数的形式绘制。 以下示例建议处理程序首先调用基类处理程序并且仅在未返回 -1 的条件下继续。
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
return 0;
}
按照约定,这些处理程序的名称以前缀“On”开头。其中一些处理程序不使用任何参数,而另一些处理程序使用数个参数。 一些处理程序还具有 void
之外的返回类型。 所有 WM_ 消息的默认处理程序在 MFC 参考中作为 CWnd
类的成员函数(其名称以“On”开头)记录。CWnd
中的成员函数声明的前缀为 afx_msg。