The simple dialog box in ABOUT1 demonstrates the basics of getting a dialog box up and running; now let's try something a little more complex. The ABOUT2 program, shown in Figure 10-3, demonstrates how to manage controls (in this case, radio buttons) within a dialog box procedure and also how to paint on the client area of the dialog box.
ABOUT2.MAK
#----------------------
# ABOUT2.MAK make file
#----------------------
about2.exe : about2.obj about2.def about2.res
link about2, /align:16, NUL, /nod slibcew libw, about2
rc about2.res
about2.obj : about2.c about2.h
cl -c -Gsw -Ow -W2 -Zp about2.c
about2.res : about2.rc about2.h about2.ico
rc -r about2.rc
ABOUT2.C
/*------------------------------------------
ABOUT2.C -- About Box Demo Program No. 2
(c) Charles Petzold, 1990
------------------------------------------*/
#include <windows.h>
#include "about2.h"
long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
short nCurrentColor = IDD_BLACK,
nCurrentFigure = IDD_RECT ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szAppName [] = "About2" ;
MSG msg ;
HWND hwnd ;
WNDCLASS wndclass ;
if (!hPrevInstance)
{
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;
RegisterClass (&wndclass) ;
}
hwnd = CreateWindow (szAppName, "About Box Demo Program",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, nCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
void PaintWindow (HWND hwnd, short nColor, short nFigure)
{
static DWORD dwColor [8] = { RGB (0, 0, 0), RGB ( 0, 0, 255),
RGB (0, 255, 0), RGB ( 0, 255, 255),
RGB (255, 0, 0), RGB (255, 0, 255),
RGB (255, 255, 0), RGB (255, 255, 255) } ;
HBRUSH hBrush ;
HDC hdc ;
RECT rect ;
hdc = GetDC (hwnd) ;
GetClientRect (hwnd, &rect) ;
hBrush = CreateSolidBrush (dwColor [nColor - IDD_BLACK]) ;
hBrush = SelectObject (hdc, hBrush) ;
if (nFigure == IDD_RECT)
Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
else
Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
DeleteObject (SelectObject (hdc, hBrush)) ;
ReleaseDC (hwnd, hdc) ;
}
void PaintTheBlock (HWND hCtrl, short nColor, short nFigure)
{
InvalidateRect (hCtrl, NULL, TRUE) ;
UpdateWindow (hCtrl) ;
PaintWindow (hCtrl, nColor, nFigure) ;
}
BOOL FAR PASCAL AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
{
static HWND hCtrlBlock ;
static short nColor, nFigure ;
switch (message)
{
case WM_INITDIALOG :
nColor = nCurrentColor ;
nFigure = nCurrentFigure ;
CheckRadioButton (hDlg, IDD_BLACK, IDD_WHITE, nColor) ;
CheckRadioButton (hDlg, IDD_RECT, IDD_ELL, nFigure) ;
hCtrlBlock = GetDlgItem (hDlg, IDD_PAINT) ;
SetFocus (GetDlgItem (hDlg, nColor)) ;
return FALSE ;
switch (message)
{
case WM_CREATE :
hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInstance) ;
return 0 ;
case WM_COMMAND :
switch (wParam)
{
case IDM_ABOUT :
if (DialogBox (hInstance, "AboutBox", hwnd,
lpfnAboutDlgProc))
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
}
break ;
case WM_PAINT :
BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
PaintWindow (hwnd, nCurrentColor, nCurrentFigure) ;
return 0 ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
ABOUT2.RC
/*---------------------------
ABOUT2.RC resource script
---------------------------*/
#include <windows.h>
#include "about2.h"
about2 ICON about2.ico
About2 MENU
{
POPUP "&Help"
{
MENUITEM "&About About2...", IDM_ABOUT
}
}
#define TABGRP (WS_TABSTOP | WS_GROUP)
AboutBox DIALOG 20, 20, 140, 188
STYLE WS_POPUP | WS_DLGFRAME
{
CTEXT "About2" -1, 0, 12, 140, 8
ICON "About2" -1, 8, 8, 0, 0
CTEXT "About Box Demo Program" -1, 4, 36, 130, 8
CTEXT "" IDD_PAINT, 68, 54, 60, 60
GROUPBOX "&Color" -1, 4, 50, 54, 112
RADIOBUTTON "&Black" IDD_BLACK, 8, 60, 40, 12, TABGRP
RADIOBUTTON "B&lue" IDD_BLUE, 8, 72, 40, 12
RADIOBUTTON "&Green" IDD_GREEN, 8, 84, 40, 12
RADIOBUTTON "Cya&n" IDD_CYAN, 8, 96, 40, 12
RADIOBUTTON "&Red" IDD_RED, 8, 108, 40, 12
RADIOBUTTON "&Magenta" IDD_MAGENTA, 8, 120, 40, 12
RADIOBUTTON "&Yellow" IDD_YELLOW, 8, 132, 40, 12
RADIOBUTTON "&White" IDD_WHITE, 8, 144, 40, 12
GROUPBOX "&Figure" -1, 68, 120, 60, 40, WS_GROUP
RADIOBUTTON "Rec&tangle" IDD_RECT, 72, 134, 50, 12, TABGRP
RADIOBUTTON "&Ellipse" IDD_ELL, 72, 146, 50, 12
DEFPUSHBUTTON "OK" IDOK, 20, 168, 40, 14, WS_GROUP
PUSHBUTTON "Cancel" IDCANCEL, 80, 168, 40, 14, WS_GROUP
}
ABOUT2.H
/*----------------------
ABOUT2.H header file
----------------------*/
#define IDM_ABOUT 1
#define IDD_BLACK 10
#define IDD_BLUE 11
#define IDD_GREEN 12
#define IDD_CYAN 13
#define IDD_RED 14
#define IDD_MAGENTA 15
#define IDD_YELLOW 16
#define IDD_WHITE 17
#define IDD_RECT 20
#define IDD_ELL 21
#define IDD_PAINT 30
ABOUT2.ICO
FIG 1003.EPB
ABOUT2.DEF
;-----------------------------------
; ABOUT2.DEF module definition file
;-----------------------------------
NAME ABOUT2
DESCRIPTION 'About Box Demo No. 2 (c) Charles Petzold, 1990'
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE
HEAPSIZE 1024
STACKSIZE 8192
EXPORTS WndProc
AboutDlgProc
The About box in ABOUT2 has two groups of radio buttons. One group is used to select a color, and the other group is used to select either a rectangle or an ellipse. The rectangle or ellipse is shown in the dialog box with the interior colored with the current color selection. If you press the OK button, the dialog box is ended, and the program's window procedure draws the selected figure on its own client area. If you press Cancel, the client area of the main window remains the same. The dialog box is shown in Figure 10-4 on the following page. Although the ABOUT2 dialog box uses the predefined identifiers IDOK and IDCANCEL for the two push buttons, each of the radio buttons has its own identifier beginning with the letters IDD (”ID for dialog box control“). These identifiers are defined in ABOUT2.H.