Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
109 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

The CWindow Class

The CWindow class is nothing more than a light wrapper around an HWND.  It implements most of the standard Win32 window functions and adds a few useful functions like CenterWindow() and ResizeClient().  Keep in mind that the CWindow object and the window itself are separate entities.  The construction and destruction of the window is independent of the CWindow object.  Another important thing to note is that CWindow cannot be used to implement a window.  It can only be used to wrap existing windows or create windows using an existing window class [2], [3].

To create an edit control using CWindow we simply use CWindow's Create() function.

CWindow EditCtrl;

EditCtrl.Create(_T("EDIT"), hParent, CWindow::rcDefault,_T(""),WS_CHILD);

The first parameter is the name of the window class; in this case "EDIT".  The second is the HWND of the parent window.  The third parameter is a RECT structure defining the size and position of the window.  The fourth is the windows caption, and the fifth is the style.  There are actually a few more parameters but they provide default values, and this example doesn't need to change these values.  For complete documentation see the CWindow reference on MSDN [3].

If the edit control already existed and we simply wished to use the CWindow methods to access it, we could use CWindow's Attach() method to assign the existing HWND to the CWindow object.  There's also a corresponding Detach() method that clears the handle from the CWindow object.  Additionally, CWindow provides a convenient constructor that takes an HWND and attaches the CWindow object to it.

void SomeFunction(HWND hEditCtrl)
{
  CWindow EditCtrl;

  EditCtrl.Attach(hEditCtrl);
  EditCtrl.SetWindowText(_T("This is a Test"));
}

//  or

void SomeFunction2(HWND hEditCtrl)
{
  CWindow EditCtrl(hEditCtrl);

  EditCtrl.SetWindowText(_T("This is a Test"));
}

CWindow also implements operator= and an HWND conversion operator.  This allows CWindow objects to be assigned HWNDs

EditCtrl  =  hEditCtrl;

and anywhere an HWND is called for a CWindow can be used instead.

CWindow EditCtrl;

EditCtrl.Create(_T("EDIT"), NULL, CWindow::rcDefault,_T(""),WS_CHILD);
SomeFunction(EditCtrl);

Don't worry about allowing a CWindow object to go out of scope while a window handle is still attached; the window will not be destroyed.  As mentioned earlier, the lifetime of the CWindow object and the window itself are independent.  To actually destroy the attached window use CWindow's DestroyWindow() method.

For complete documentation on CWindow and its methods see the CWindow reference on MSDN [3], [1].

The CWindowImpl Class

The CWindowImpl class, unlike the CWindow class, actually implements a window.  To use CWindowImpl we define a new class that inherits from CWindowImpl. This new class must be passed as the first parameter of the template.  The second parameter is a base class whose default value is CWindow.  This allows CWindowImpl to inherit all the methods provided by CWindow (CWindowImpl also uses CWindow's m_hWnd member to store the HWND when a CWindowImpl instance is used to create a window.  Because of this dependency the second parameter of the CWindowImpl template must be CWindow or a derivative of CWindow).  For the time being we'll leave the second parameter as is.  The third and final parameter is a traits class.  The traits class provides information about the window styles used when creating a window [4], [1].  We'll also ignore this parameter for now.  Below is the beginning of CWindowImpl's definition.

template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
class ATL_NO_VTABLE CWindowImpl : public CWindowImplBaseT< TBase, TWinTraits >
{
  public:
	DECLARE_WND_CLASS(NULL)
…

Let's add a new file to our project called mainwnd.h.  To it we'll add a class called MainWnd that inherits from CWindowImpl.  We'll also need to include atlwin.h.  Below is our start of mainwnd.h.

#include <atlwin.h>

class MainWnd : public CWindowImpl<MainWnd>
{
};

Defining a Window Class

In standard Win32 programming we define a window class by creating an instance of a WNDCLASSEX structure, setting its members, and passing it to RegisterClassEx().  Note that when I refer to a window class I'm speaking of the properties set in and registered with the WNDCLASSEX structure and not a C++ class.  CWindowImpl simplifies this by providing a handful of macros used to help define and register the window class.  The DECLARE_WND_CLASS macro in the CWindowImpl definition listed earlier is one of these macros.  Passing NULL creates a window class using a random class name.  Since DECLARE_WND_CLASS(NULL) is declared in CWindowImpl, any classes derived from CWindowImpl also inherit this functionality.  If you want to give your window class a specific name you'll need to override CWindowImpl's declaration.  To do this, simply pass the name you wish to use to DECLARE_WND_CLASS in your derived class [1], [2].  Go ahead and make this change to mainwnd.h.  Use anything you like for the class name.  Our new mainwnd.h file should look something like the code below.

#include <atlwin.h>

class MainWnd : public CWindowImpl<MainWnd>
{
public:
  DECLARE_WND_CLASS(_T("Specific_Class_Name"))

};

We'll spend more time working with window classes later. For now the DECLARE_WND_CLASS macro is all we need to get our window class defined.





Message Handling

Contents
  Introduction
  Windows Class
  Message Handling
  Conclusion

  Source code
  Printable version
  Discuss this article

The Series
  Getting Started
  Windowing