若要实现窗口,请从 CWindowImpl 派生类。在派生类中声明消息映射和消息处理函数。现在可以以三种不同的方式使用类:
基于新 Windows 类创建窗口
CWindowImpl 包含声明 Windows 类消息的 DECLARE_WND_CLASS 宏。该宏实现 GetWndClassInfo 函数,此函数使用 CWndClassInfo 定义新 Windows 类的信息。调用 CWindowImpl::Create 时,会注册此 Windows 类并创建一个新窗口。
注意 CWindowImpl 将 NULL 传递给 DECLARE_WND_CLASS 宏,这意味着 ATL 将生成一个 Windows 类名。若要指定自己的名称,请在 CWindowImpl 派生类中将字符串传递给 DECLARE_WND_CLASS。
示例
下面是基于新 Windows 类实现窗口的类示例:
class CMyWindow : public CWindowImpl<CMyWindow>, ... { public: // Optionally specify name of the new Windows class DECLARE_WND_CLASS("MyName") // If this macro is not specified in your // class, ATL will generate a class name ... BEGIN_MSG_MAP(CMyWindow) MESSAGE_HANDLER(WM_PAINT, OnPaint) END_MSG_MAP() LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // Do some painting code return 0; } };
若要创建窗口,请创建一个 CMyWindow
的实例,然后调用 Create 方法。
注意 若要重写默认的 Windows 类信息,请通过将 CWndClassInfo 成员设置为适当的值,在派生类中实现 GetWndClassInfo 方法。
为现有 Windows 类创建超类
DECLARE_WND_SUPERCLASS 宏允许创建为现有 Windows 类创建超类的窗口。在 CWindowImpl 派生类中指定此宏。像任何其他 ATL 窗口一样,消息由消息映射处理。
使用 DECLARE_WND_SUPERCLASS 时将注册一个新 Windows 类。这个新类与指定的现有类相同,但是将用 CWindowImpl::WindowProc(或重写此方法的函数)替换窗口过程。
示例
下面是为标准 Edit 类创建超类的类示例:
class CMyEdit : public CWindowImpl<CMyEdit>, ... { public: // "Edit" is the name of the standard Windows class. // "MyEdit" is the name of the new Windows class // that will be based on the Edit class. DECLARE_WND_SUPERCLASS("MyEdit", "Edit") ... BEGIN_MSG_MAP(CMyEdit) MESSAGE_HANDLER(WM_CHAR, OnChar) END_MSG_MAP() LRESULT OnChar(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // Do some character handling code } };
若要创建具有超类的“编辑”窗口,请创建 CMyEdit
的实例,然后调用 Create 方法。
为现有窗口创建子类
若要为现有窗口创建子类,请从 CWindowImpl 派生类,并声明消息映射(像前面两种情况中那样)。不过请注意,不要指定任何 Windows 类信息,因为将为现有窗口创建子类。
不是调用 Create,而是调用 SubclassWindow,并向它传递要为其创建子类的现有窗口的句柄。为窗口创建子类后,它将使用 CWindowImpl::WindowProc(或重写此方法的函数)将消息定向到消息映射。若要从对象中分离具有子类的窗口,请调用 UnsubclassWindow。窗口的原始窗口过程于是将还原。
请参见
若要向控件添加消息处理程序(处理 Windows 消息的成员函数),首先在“类视图”中选择控件。然后打开“属性”窗口,选择“消息”图标,接着在对应所需消息的框中单击下拉 (Dropdown) 控件。这将在控件的头文件中添加消息处理程序的声明,在控件的 .cpp 文件中添加处理程序的主干实现。它还将添加消息映射并为处理程序添加一项。
在 ATL 中添加消息处理程序类似于向 MFC 类添加消息处理程序。有关更多信息,请参见添加 MFC 消息处理程序。
下列条件仅适用于添加 ATL 消息处理程序:
- 消息处理程序与 MFC 遵循同一命名约定。
- 新消息映射项添加到主消息映射中。向导不识别替换消息映射和链接。
ATL 提供三种类型的消息处理函数:
消息处理程序的类型 | 对应的消息宏 |
---|---|
MessageHandler | MESSAGE_HANDLER |
CommandHandler | COMMAND_HANDLER |
NotifyHandler | NOTIFY_HANDLER |
本主题描述消息处理函数的语法。
MessageHandler
参数
-
uMsg
- 指定消息。 wParam
- 其他特定于具体消息的信息。 lParam
- 其他特定于具体消息的信息。 bHandled
- 在调用 MessageHandler 之前,消息映射将 bHandled 设置为 TRUE。如果 MessageHandler 不完全处理消息,它应该将 bHandled 设置为 FALSE 以指示消息需要进一步处理。
返回值
消息处理的结果。如果成功,则为 0。
备注
MessageHandler 是消息映射中由 MESSAGE_HANDLER 宏的第二个参数标识的函数的名称。
有关在消息映射中使用此消息处理程序的示例,请参见 MESSAGE_HANDLER。
CommandHandler
参数
-
wNotifyCode
- 通知代码。 wID
- 菜单项、控件或快捷键的标识符。 hWndCtl
- 窗口控件的句柄。 bHandled
- 在调用 CommandHandler 之前,消息映射将 bHandled 设置为 TRUE。如果 CommandHandler 不完全处理消息,它应将 bHandled 设置为 FALSE 以指示消息需要进一步处理。
返回值
消息处理的结果。如果成功,则为 0。
备注
CommandHandler 是消息映射中由 COMMAND_HANDLER 宏的第三个参数标识的函数的名称。
有关在消息映射中使用此消息处理程序的示例,请参见 COMMAND_HANDLER。
NotifyHandler
参数
-
idCtrl
- 发送通知的控件的标识符。 pnmh
- 包含通知代码和附加信息的 NMHDR 结构的地址。对于某些通知消息,该参数指向一个将 NMHDR 结构作为第一个成员的更大的结构。 bHandled
- 在调用 NotifyHandler 之前,消息映射将 bHandled 设置为 TRUE。如果 NotifyHandler 不完全处理消息,它应将 bHandled 设置为 FALSE 以指示消息需要进一步处理。
返回值
消息处理的结果。如果成功,则为 0。
备注
NotifyHandler 是消息映射中由 NOTIFY_HANDLER 宏的第三个参数标识的函数的名称。
有关在消息映射中使用此消息处理程序的示例,请参见 NOTIFY_HANDLER。