通过 CWindowImpl 实现窗口
若要实现窗口,请从 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 CMyCustomWnd : public CWindowImpl<CMyCustomWnd>
{
public:
// Optionally specify name of the new Windows class
DECLARE_WND_CLASS(_T("MyName"))
// If this macro is not specified in your
// class, ATL will generate a class name
BEGIN_MSG_MAP(CMyCustomWnd)
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 类
下面是将标准 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(_T("MyEdit"), _T("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
return 0;
}
};
若要创建超类 Edit 窗口,请创建一个实例 CMyEdit
,然后调用 Create
方法。
对现有窗口进行子类分析
若要对现有窗口进行子类分析,请从 CWindowImpl
中派生类并声明消息映射,如前两种情况所示。 但是,请注意,未指定任何 Windows 类信息,因为将对现有窗口进行子类分析。
调用 SubclassWindow
而不是调用 Create
,并向其传递要子类的现有窗口的句柄。 当窗口被子类化后,它将使用 CWindowImpl::WindowProc
(或替代此方法的函数)将消息定向到消息映射。 若要从对象中分离子类窗口,请调用 UnsubclassWindow
。 然后,将还原窗口的原始窗口过程。