MFC TN001--WNDCLASSes and MFC

Created: April 15, 1992

ABSTRACT

This technical note describes the MFC routines for registering special window classes (WNDCLASS structures) that Windows needs. It discusses specific WNDCLASS attributes that MFC and Windows use.

The Microsoft Foundation Class (MFC) library provides a full-featured set of C++ object classes for the MicrosoftÒ WindowsÔ graphical environment. It includes classes that directly support application development for Windows as well as general-purpose classes for collections, files, persistent storage, exceptions, diagnostics, memory management, strings, and time. Each MFC technical note describes a feature of MFC using code fragments and examples.

THE PROBLEM

The attributes of a CWnd object, like an HWND in the MicrosoftÒ WindowsÔ graphical environment, are stored in two places—in the window object and in the WNDCLASS. A WNDCLASS is different from 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 in one of four ways:

Implicitly by MFC

Implicitly by a Windows control (or some other control)

Explicitly by calling the MFC AfxRegisterClass routine

Explicitly by calling the Windows RegisterClass routine

WNDCLASSES AND MFC

The WNDCLASS structure consists of fields that describe a window class. Below is a list of the fields and how they apply to an MFC application.

style Style of window, see below
lpfnWndProc Window procedure, must be AfxWndProc
cbClsExtra Not used
cbWndExtra Not used
hInstance Automatically filled with AfxGetInstanceHandle
hIcon Icon for frame windows, see below
hCursor Cursor used when mouse is over window, see below
hbrBackground Background color, see below
lpszMenuName Not used
lpszClassName Class name, see below

WNDCLASSES PROVIDED

MFC provides three standard window classes: AfxWnd, AfxFrameWnd, and AfxMDIFrameWnd:

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 (that is, the parent) created with CMDIFrameWnd::Create.

Table 1 shows the registered attributes.

Table 1. Registered Attributes

Attribute Class Name    
  AfxWnd AfxFrameWnd AfxMDIFrameWnd

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

If an application provides a resource with the specified AFX_ID_STD_FRAME or AFX_ID_STD_MDIFRAME resource ID, MFC uses that resource. If an application does not provide a resource, MFC uses the default resource. MFC uses the standard application icon (a white box) and the standard arrow cursor.

Two icons support MDI applications with single document types (one for the main application, the other for iconic document/MDI child windows). If you want an MDI application with multiple document types to have different icons for each document type, you must register additional WNDCLASSes.

The values for the background color and the cursor for the MDIFrameWnd are not used because the client area of the MDIFrameWnd is completely covered with the MDICLIENT window. MFC does not support subclassing of the MDICLIENT window, so you should use the standard colors and cursor types.

If you subclass or superclass a Windows control (for example, CButton), your class automatically gets the WNDCLASS attributes provided in the Windows implementation of that control.

THE AFXREGISTERWNDCLASS FUNCTION

MFC provides a helper routine called AfxRegisterWndClass for registering a window class. Given a set of attributes for window class style, cursor, background brush, and icon, AfxRegisterWndClass generates a synthetic name and registers the resulting window class.

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 throws a CResourceException if the window class failed to register (either because of bad parameters or because it was out of Windows memory).

The return string is a temporary pointer to a static string buffer, which is valid until the next call to AfxRegisterWndClass. If you want to save this string, store it in a CString variable.

CString wndClass = AfxRegisterWndClass(CS_DBLCLK, defaultCursor);

.

.

.

CWnd wnd;

wnd.Create(wndClass, ...);

.

.

.

LAST RESORT: USE REGISTERCLASS

To do anything more sophisticated than the capabilities of the AfxRegisterWndClass function, call the RegisterClass function.

Most 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.