Microsoft Foundation Classes                             Microsoft Corporation
Technical Notes                                        

#1 : WNDCLASSes and MFC

This note describes the MFC routines for registering special
WNDCLASSes as needed by MS-Windows.  Specific WNDCLASS attributes
used by MFC and Windows are discussed.

=============================================================================

The Problem
===========

The attributes of a CWnd object, like an HWND in Windows, are stored
in two places, the window object and the WNDCLASS.  A WNDCLASS is different
than a C++ class.  The MFC C++ class in Windows still requires that
the name of a WNDCLASS be passed to the creation function.  This WNDCLASS
must be registered via one of four means:

    * implicitly by MFC
    * implicitly by an MS-Windows control (or some other control)
    * explicitly by calling the MFC routine AfxRegisterClass
    * explicitly by calling the Windows routine RegisterClass

-----------------------------------------------------------------------------
WNDCLASSes and MFC
==================

The WNDCLASS structure consists of various fields used to describe a
window class.  Here are the fields and how they apply to an MFC app.

    style               -- style of window, see below
    lpfnWndProc         -- window proc, must be 'AfxWndProc'
    cbClsExtra          -- not used
    cbWndExtra          -- not used
    hInstance           -- automatically filled with AfxGetInstanceHandle()
    hIcon               -- icon for frame windows, see below
    hCursor             -- cursor for when mouse is over window, see below
    hbrBackground       -- background color, see below
    lpszMenuName        -- not used
    lpszClassName       -- class name, see below

-----------------------------------------------------------------------------
Provided WNDCLASSes
===================

MFC provides 3 standard window classes.

    "AfxWnd" is used for all child windows created with CWnd::Create().

    "AfxFrameWnd" is used for frame windows (both stand-alone CFrameWnds
    and CMDIChildWnds).

    "AfxMDIFrameWnd" is used for the MDI frame window (i.e. the parent)
    created with CMDIFrameWnd::Create().


The following table shows the registered attributes:

Class name -->     AfxWnd    AfxFrameWnd          AfxMDIFrameWnd

Attribute
---------
style              0         0                    0
icon               none      AFX_IDI_STD_FRAME    AFX_IDI_STD_MDIFRAME
cursor             arrow     arrow                arrow
background color   none      COLOR_WINDOW         n/a

NOTE: if the application provides a resource with the specified 'AFX_ID*'
resource ID, MFC will use that resource.  Otherwise the default resource
is used.  For the icon, the standard app icon is used (a white box),
and for the cursor, the standard arrow cursor is used.

NOTE: we provide two alternative icons for supporting MDI applications
with single document types (one icon for the main app, the other icon
for iconic document/MDIChild windows).  If you desire an MDI application
with multiple document types with different icons, you must register
additional WNDCLASSes.

NOTE: the values for background color and cursor for the MDIFrameWnd
are not used since the client area of the MDIFrameWnd is completely
covered with the "MDICLIENT" window.  We do not support subclassing
of the "MDICLIENT" window and you should be sticking to the standard
colors and cursor types.

-----------------------------------------------------------------------------
Subclassing controls:
=====================

If you subclass or superclass a Windows control (eg: CButton) then your class
automatically gets the WNDCLASS attributes as provided in the Windows
implementation of that control.

-----------------------------------------------------------------------------
The AfxRegisterWndClass() Function
==================================

MFC provides a helper routine for registering a window class.
Given a set of attributes for: window class style, cursor,
background brush and icon, a synthetic name is generated, and
the resulting window class registered.

const char* AfxRegisterWndClass(UINT nClassStyle,
        HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon);

This function takes the arguments (all except the first one default
to zero) and returns a temporary string of the registered window
class.

AfxRegisterWndClass will throw a CResourceException if the window
class failed to register (either because of bad parameters, or out of
Windows memory).

NOTE: the string returned is a temporary pointer to a static string buffer
which is valid until the next call to AfxRegisterWndClass.  If you want
to keep this string around, store it in a CString variable.

        CString wndClass = AfxRegisterWndClass(CS_DBLCLK, defaultCursor);

        ...
        CWnd wnd;
        wnd.Create(wndClass, ...);
        ...

-----------------------------------------------------------------------------
Last resort: use RegisterClass
==============================

If you want to do anything more sophisticated than what
AfxRegisterWndClass provides, you can always call the Windows API
'RegisterClass'.

Most of the MFC window creation routines take a string name for a
window class as the first parameter, and any window class name
can be used, regardless of how it was registered.

-----------------------------------------------------------------------------
