Implementing a Window with CWindowImpl

To implement a window, derive a class from CWindowImpl. In your derived class, declare a message map and the message handler functions. You can now use your class in three different ways:

Creating a window based on a new Windows class

CWindowImpl contains the DECLARE_WND_CLASS macro to declare Windows class information. This macro implements the GetWndClassInfo function, which uses CWndClassInfo to define the information of a new Windows class. When CWindowImpl::Create is called, this Windows class is registered and a new window is created.

Note   CWindowImpl passes NULL to the DECLARE_WND_CLASS macro, which means ATL will generate a Windows class name. To specify your own name, pass a string to DECLARE_WND_CLASS in your CWindowImpl-derived class.

Following is an example of a class that implements a window based on a new Windows class:

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;
   }
};

To create a window, create an instance of CMyWindow and then call the Create method.

Note   To override the default Windows class information, implement the GetWndClassInfo method in your derived class by setting the CWndClassInfo members to the appropriate values.

Superclassing an existing Windows class

The DECLARE_WND_SUPERCLASS macro allows you to create a window that superclasses an existing Windows class. Specify this macro in your CWindowImpl-derived class. Like any other ATL window, messages are handled by a message map.

When you use DECLARE_WND_SUPERCLASS, a new Windows class will be registered. This new class will be the same as the existing class you specify, but will replace the window procedure with CWindowImpl::WindowProc (or with your function that overrides this method).

Following is an example of a class that superclasses the standard Edit class:

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("Edit", "MyEdit")

   ...
   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
   }
};

To create the superclassed Edit window, create an instance of CMyEdit and then call the Create method.

For more information about superclassing, see Window Procedure Superclassing in the Win32 SDK.

Subclassing an existing window

To subclass an existing window, derive a class from CWindowImpl and declare a message map, as in the two previous cases. Note, however, that you do not specify any Windows class information, since you will subclass an already existing window.

Instead of calling Create, call SubclassWindow and pass it the handle to the existing window you want to subclass. Once the window is subclassed, it will use CWindowImpl::WindowProc (or your function that overrides this method) to direct messages to the message map. To detach a subclassed window from your object, call UnsubclassWindow. The window's original window procedure will then be restored.

For more information about subclassing, see Window Procedure Subclassing in the Win32 SDK.