Painting on the Dialog Box

ABOUT2 also does something relatively unusual: It paints on the dialog box. Let's see how this works. Within the dialog box template in ABOUT2.RC, a blank text control is defined with a position and size for the area we want to paint:

CTEXT "" IDD_PAINT, 68, 54, 60, 60

This area is 15 characters wide and 7-1/2 characters high. Because this control has no text, all that the window procedure for the ”static“ class does is erase the background when the child window control has to be repainted.

When the current color or figure selection changes or when the dialog box itself gets a WM_PAINT message, the dialog box procedure calls PaintTheBlock, which is a function in ABOUT2.C:

PaintTheBlock (hCtrlBlock, nColor, nFigure) ;

The window handle hCtrlBlock had been set during processing of the WM_INITDIALOG message:

hCtrlBlock = GetDlgItem (hDlg, IDD_PAINT) ;

Here's the PaintTheBlock function:

void PaintTheBlock (HWND hCtrl, short nColor, short nFigure)

{

InvalidateRect (hCtrl, NULL, TRUE) ;

UpdateWindow (hCtrl) ;

PaintWindow (hCtrl, nColor, nFigure) ;

}

This invalidates the child window control, updates it, and then calls another function in ABOUT2 called PaintWindow.

The PaintWindow function obtains a device context handle for hCtrl and draws the selected figure, filling it with a colored brush based on the selected color. The size of the child window control is obtained from GetClientRect. Although the dialog box template defines the size of the control in terms of characters, GetClientRect obtains the dimensions in pixels. You can also use the function MapDialogRect to convert the character coordinates in the dialog box to pixel coordinates in the client area.

We're not really painting the dialog box's client area—we're actually painting the client area of the child window control. Whenever the dialog box gets a WM_PAINT message, the child window control is invalidated and then updated to make it believe that its client area is now valid. We then paint on top of it.