Listing 2: Implementation of base class

#include <windows.h>
#include "WndObj.h"

CWindow::CWindow()
{
    //Set the default data for the window class.
    //These can be reset in the derived class's constructor.

    _WndClass.cbSize = sizeof(_WndClass);
    _WndClass.style = CS_DBLCLKS;
    _WndClass.lpfnWndProc = BaseWndProc;
    _WndClass.cbClsExtra = 0;
    _WndClass.cbWndExtra = 0;
    _WndClass.hInstance = NULL; 
    _WndClass.hIcon = NULL;
    _WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    _WndClass.hbrBackground = 
        (HBRUSH)GetStockObject(WHITE_BRUSH);
    _WndClass.lpszMenuName = NULL;
    _WndClass.hIconSm = NULL;

    _dwExtendedStyle = NULL;
    _dwStyle = NULL;
    _pszClassName = "CWindow";
    _pszTitle = "";
}

HWND CWindow::Create(int x, int y, int nWidth, int nHeight,
    HWND hParent, HMENU hMenu, HINSTANCE hInstance)
{
    _WndClass.lpszClassName = _pszClassName;
    _WndClass.hInstance = hInstance;
    
    //If we're already registered, this call will fail.
    RegisterClassEx(&_WndClass);

    _hwnd = CreateWindowEx(_dwExtendedStyle, _pszClassName,
        _pszTitle, _dwStyle, x, y, nWidth, nHeight,
        hParent, hMenu, hInstance, (void*)this);

    return _hwnd;
}

LRESULT CALLBACK CWindow::BaseWndProc(HWND hwnd, UINT msg,
    WPARAM wParam, LPARAM lParam)
{
    //A pointer to the object is passed in the CREATESTRUCT
    if(msg == WM_NCCREATE)
        SetWindowLongPtr(hwnd, GWLP_USERDATA,
        (LONG_PTR)((LPCREATESTRUCT)lParam)->lpCreateParams);
    
    BOOL bProcessed = FALSE;
    LRESULT lResult;
    
    //Retrieve the pointer
    CWindow *pObj = 
        (CWindow *)GetWindowLongPtr(hwnd, GWLP_USERDATA);

    //Filter message through child classes
    if(pObj)
        lResult = pObj->WindowProc(hwnd, msg, wParam, lParam,
            &bProcessed);

    if(bProcessed)
        return lResult;
    else
    {
        //If message was unprocessed, send it back to Windows.
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
}

LRESULT CWindow::WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
    LPARAM lParam, PBOOL pbProcessed)
{
    //This may be overridden to process messages.
    *pbProcessed = FALSE;
    return NULL;
}