Creating the Child Windows

BTNLOOK defines a structure called button that contains button window styles and descriptive text strings for each of the 11 types of buttons. The button window styles all begin with the letters BS, which stand for ”button style.“

The 11 button child windows are created in a for loop during WM_CREATE message processing in WndProc. The CreateWindow call uses the following parameters:

Class name "button"
Window text button[i].text
Window style WS_CHILD | WS_VISIBLE | button[i].style
x position cxChar
y position cyChar * (1 + 2 * i)
Width 20 * xChar
Height 7 * yChar / 4
Parent window hwnd

Child window ID i
Instance handle ((LPCREATESTRUCT) lParam) -> hInstance
Extra parameters NULL

The class name parameter is the predefined name. The window style uses WS- CHILD, WS_VISIBLE, and one of the eleven button styles (BS_PUSHBUTTON, BS- DEFPUSHBUTTON, and so forth) in the button structure. The window text parameter (which for a normal window is the text that appears in the caption bar) is text that will be displayed with each button. I've simply used text that identifies the button style.

The x position and y position parameters indicate the placement of the upper left corner of the child window relative to the upper left corner of the parent window's client area. The width and height parameters specify the width and height of each child window.

The child window ID parameter should be unique for each child window. This ID helps your window procedure identify the child window when processing WM_COMMAND messages from it.

The instance handle parameter of the CreateWindow call looks a little strange, but we're taking advantage of the fact that during a WM_CREATE message lParam is actually a pointer to a structure of type CREATESTRUCT (”creation structure“) that has a member hInstance. So we cast lParam into a long (or far) pointer to a CREATESTRUCT structure and get hInstance out.

(Some Window programs use a global variable named hInst to give window procedures access to the instance handle available in WinMain. In WinMain, you need simply set:

hInst = hInstance ;

before creating the main window. In Chapter 4 we used GetWindowWord to obtain the instance handle:

GetWindowWord (hwnd, GWW_HINSTANCE)

Any of these methods is fine.)

After the CreateWindow call, we don't have to do anything more with these child windows. The button window procedure within Windows maintains them for us and handles all repainting jobs. (The exception is the button with the BS_USERBUTTON style; as I'll discuss shortly, this button style requires the program to draw the button.) At the program's termination, Windows destroys these child windows when the parent window is destroyed.