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:
Create a window based on a new Windows class
Superclass an existing Windows class
Subclass an existing window
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.
Notes
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.
Example
Following is an example of a class that implements a window based on a new Windows class:
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;
}
};
To create a window, create an instance of CMyWindow and then call the Create method.
Notes
To override the default Windows class information, implement the GetWndClassInfo method in your derived class by setting the CWndClassInfo members to the appropriate values.
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(_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;
}
};
To create the superclassed Edit window, create an instance of CMyEdit and then call the Create method.
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).
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.