93.6 Window Classes

A window class is implemented by a window procedure. A window procedure can be registered with either the RegisterWindowClassA or RegisterWindowClassW function. By using the A version of the function, the program tells the system that the windows of the created class expect messages with text or character parameters to use the ANSI character set; by registering the window class with a call to the wide-character version of the function, the program can request that the system pass text parameters of messages as Unicode. The IsWindowUnicode function allows programs to query the nature of each window.

The following code fragment shows how to register an ANSI and a Unicode window class and how to write the window procedures for either case. For the purposes of this example, all function calls and structures are shown with the explicit A or W types. Using the techniques explained in the previous section, it would be possible to write this example using generic types, so that it can be compiled either way depending on the setting of the #define UNICODE compile-time flag.

/* Register an ANSI window class. */

WNDCLASSA AnsiWndCls;

AnsiWndCls.style = CS_DBLCLKS | | CS_PARENTDC;

AnsiWndCls.lpfnWndProc = (WNDPROC)AnsiWndProc;

AnsiWndCls.cbClsExtra = 0;

AnsiWndCls.cbWndExtra = CBEDITEXTRA;

AnsiWndCls.hInstance = hmodUser;

AnsiWndCls.hIcon = NULL;

AnsiWndCls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_IBEAM);

AnsiWndCls.hbrBackground = NULL;

AnsiWndCls.lpszMenuName = NULL;

AnsiWndCls.lpszClassName = "TestAnsi";

RegisterClassA(&AnsiWndCls);

/* Register a Unicode window class. */

WNDCLASSW UnicodeWndCls;

UnicodeWndClass.style = CS_DBLCLKS | | CS_PARENTDC;

UnicodeWndClass.lpfnWndProc = (WNDPROC)UniWndProc;

UnicodeWndClass.cbClsExtra = 0;

UnicodeWndClass.cbWndExtra = CBEDITEXTRA;

UnicodeWndClass.hInstance = hmodUser;

UnicodeWndClass.hIcon = NULL;

UnicodeWndClass.hCursor = LoadCursor(NULL, (LPTSTR)IDC_IBEAM);

UnicodeWndClass.hbrBackground = NULL;

UnicodeWndClass.lpszMenuName = NULL;

UnicodeWndClass.lpszClassName = L"TestUnicode";

RegisterClassW(&UnicodeWndClass);

The following code fragment shows the difference between handling the WM_CHAR message in an AnsiWndProc window procedure and a UniWndProc window procedure:

/* ANSI Window Procedure */

LONG AnsiWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

/* Dispatch the messages that can be received. */

switch (message) {

case WM_CHAR:

/*

* wParam - the value of the key

* lParam - modifiers, repeat count etc (not used)

*/

if (lstrcmpA('Q', wParam)) {

.

.

.

}

else {

.

.

.

}

break;

.

.

.

}

}

/* Unicode Window Procedure */

LONG UniWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

/* Dispatch the messages that can be received. */

switch (message) {

case WM_CHAR:

/*

* wParam - the value of the key

* lParam - modifiers, repeat count etc (not used)

*/

if (lstrcmpW(L'Q', wParam)) {

.

.

.

}

else {

.

.

.

}

break;

.

.

.

}

}

In the preceding example, all text in messages received by AnsiWndProc will be composed of ANSI characters, and all text in messages received by UniWndProc will be composed of Unicode characters.