通过 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。 然后,将还原窗口的原始窗口过程。

另请参阅

实现窗口