400 likes | 701 Views
Multiple Windows, Dialog Boxes. Petzold: Review: Chapter 9 (child window controls) Chapter 11 (dialog boxes). Overview. Dialog boxes are, really, just “multiple windows” especially, child window control But , defined in resource script, . rc , file and has (real) idiosyncrasies
E N D
Multiple Windows, Dialog Boxes Petzold: Review: Chapter 9 (child window controls) Chapter 11 (dialog boxes)
Overview • Dialog boxes are, really, just “multiple windows” • especially, child window control • But, defined in resource script, .rc, file • and has (real) idiosyncrasies • Challenge lies in fact that several display and communication aspects “automated” • which sounds good at first (and for the daily programmer it is) • but result in seemingly idiosyncratic aspects • Will review ideas about child windows, styles, communication among, etc. • Kind of tricky-tedious-detailed … • So, follow along
Steps in Creating WindowsRecall • Define window class • “style” of the class • Function name to handle events • E.g., wndproc, childwinproc • Create the window • “window style” of the window • E.g., WS_Child • Child window controls (in Windowese) are predefined window styles that include input (e.g., mouse and text) handling • E.g., editbox
Multiple Windows - Classes “Behavior” and control of window determined by class and style when created Define a class (below is for “frame” window): Recall, defining “window class” in WinMain … Set a bunch of fields in a C struct and then register class: wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; // e.g., “Party” if (!RegisterClass (&wndclass)) return FALSE ; 1. Sets class name (just a string), to be used later 2. Set name of “window procedure”, so far, WndProc - now others
Multiple Windows - Details: CreateWindow Create a window: Recall, the CreateWindow command (and all those parameters): hWnd = CreateWindow (szChildClass, // window class name "Child Window 1", // window caption WS_CHILD | WS_CAPTION | // window styles – next slides … WS_CLIPSIBLINGS | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX, xScreen / 9, // initial x position yScreen / 2, // initial y position xScreen / 3, // initial x size yScreen / 4, // initial y size hWndMain, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // create parameters Note: 1. Lots of window style flags 2. Note non-NULL parent win handle 3. This is a tricky example and will be a window not of WS_CHILD which still has a parent (popup with parent)
Window Styles • Styles are “or-ed together”: <ws1> | <ws2> | … • WS_BORDER • Creates a window that has a border. • WS_CAPTION • Creates a window that has a title bar (implies the WS_BORDER style). Cannot be used with the WS_DLGFRAME style. • WS_CHILD • Creates a child window. Cannot be used with the WS_POPUP style. • WS_CLIPCHILDREN • Excludes the area occupied by child windows when you draw within the parent window. Used when you create the parent window. • WS_CLIPSIBLINGS • Clips child windows relative to each other … • WS_DISABLED • Creates a window that is initially disabled. • WS_DLGFRAME • Creates a window with a double border but no title. • WS_GROUP • Specifies the first control of a group of controls in which the user can move from one control to the next … • WS_HSCROLL • Creates a window that has a horizontal scroll bar. • WS_MAXIMIZE • Creates a window of maximum size. • WS_MAXIMIZEBOX • Creates a window that has a Maximize button. • WS_MINIMIZE • Creates a window that is initially minimized. For use with the WS_OVERLAPPED style only.
Child Window Controls Child window controls (in Windowese) are predefined window styles, which include input (e.g., mouse and text) handling - More shortly for dialog boxes - Class “Button” handles invert when clicked, etc. - Class “Edit” is in essence a complete text editor, which can be “queried” to return the string which has been input!
Communication Among WindowsRecall Will use with these basic ideas with dialog boxes! Again, basic idea with multiple windows: Some “frame” window has several (typically) child windows In Windows, movement, closing, etc. is handled by windowing system vs. programmer handling for each child window How to communicate between window? Child to parent and parent to child Simply put in the WndProc - or ChildWndProc: hwndParent = GetParent (hwnd); // or save hwndChild on create SendMessage (hwndParent, iMsg, wParem, lParam WndProc (of parent) receives the 3 values iMsg, wParem, lParam iMsg is the “code” for the message, as usual (range WM_USER to 0x7FFF0) program “catches” (as a case) this “new” message e.g., WM_USER value + 1 program uses values of wParam, lParam as codes for further infomation Might send message about mouse clicks (even hits), as checked by code in ChildWndProc, thus isolating this code in a separate procedure Child Window controls operate in essentially this way “Built-in” window procedure associated with window control class sends message back to parent Any WndProc can also communicate to any child window control using the control’s window handle to direct where message is sent
Communication Among Windows Example: How to communicate between windows In ChildWndProc: hwndParent = GetParent (hwnd); // or save hwndChild on create SendMessage (hwndParent, iMsg, wParam, lParam WndProc of parent receives the 3 values iMsg is the “code” for the message: range WM_USER to 0x7FFF0 program “catches” (as a case) this “new” message, e.g., WM_USER value + 1 program uses values of wParam, lParam as codes for further infomation Might send message about mouse clicks (even hits), as checked by code in ChildWndProc isolating this code in a separate procedure
Creating Child Window Control - Button Button is just a child window! which is a “built-in” style hWnd = CreateWindow ("Button", // window class name "Push Button", // window caption WS_CHILD | BS_PUSHBUTTON, // window style 10, // initial x position 10, // initial y position xScreen / 4, // initial x size yScreen / 8, // initial y size hWndPopup2, // parent window handle (HMENU) 4, // window id hInstance, // program instance handle NULL) ; // create parameters
Child Window Control:Communication with Parent Button class wndproc is “built-in”, and does things Don’t see the code, so just have to know what it does! And in some senses this may not make it easier! Communicates with parent with iMsg = WM_COMMAND message (to parent)
An “Imaginary” Button Class Wind Proc Child window (here, from button class) uses codes to communicate with parent: WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CREATE : case WM_LBUTTON: hwndParent = GetParent (hwnd); LOWORD (wParam) = val of Child window id // so you know which control // because there can be > 1! HIWORD (wParam) = val of Notification code // so you know what was done SendMessage (hwndParent, iMsg, wParem, hwnd); : Case WM_DOUBLECLICK: hwndParent = GetParent (hwnd); : SendMessage (hwndParent, iMsg, wParem, lParam); : }
Example: Button Class Codes Param and wParam have information: LOWORD (wParam) = Child window id // so you know which control HIWORD (wParam) = Notification code // so you know what was done lParam = Child window handle // so you can communicate with it Button notification codes, example communication: Identifier Value BN_CLICKED 0 : : BN_DOUBLECLICKED 5
Parent Communicates w/ Child Window Control: Button Example Also, parent window needs to communicate with child window controls For example, will be handling state, e.g., checked or unchecked, of controls Getting handle and/or id for communication Just saw that window handle is conveniently returned to parent Also, for later, can use “id” to get window handle and handle to get “id”: hwndChild = GetDlgItem (hwndParent, id) id = GetWindowLong (hwndChild, GWL_ID) id = GetDlgCtrlId (hwndChild) Examples (“just have to know”): SendMessage (hwndButton, BM_SETSTATE, 1, 0); // flashes button SendMessage (hwndCheck, BM_SETCHECK, 1, 0); // puts check in box SendMessage (hwndCheck, BM_SETCHECK, 1, 1); // removes check in box
Parent Communicates w/ Child Window Control:Edit Box Example Recall, edit child window control, has in effect a text editor as its wndproc i.e., handles typing (keyboard input), display of typed keys on screen not to mention insertion, deletion, etc.! Easy to just get text from edit control - use Windows functions in “your” wndproc: char szBuffer[1000]; hwnd hwndEditCtrl; : // find out how many characters are in edit box - length of string in box iStrLen = GetWindowTextLength; // character are returned in szBuffer iLength = GetWindowText (hwndEditCtrl, szBuffer, iLength)
Petzold Example: BTNLOOK Screen Just a quick example: Creates all button types Shows what happens when each is clicked Here, from top to bottom
Petzold Example: BTNLOOK Code: Label struct, 1 // C stuff first // another big Petzoldish C struct to step through when creating the buttons // as with other elements, windows.h constants, and inside windows magic struct { long style ; char *text ; } button[ ] = { // .style: .*text: BS_PUSHBUTTON, "PUSHBUTTON", BS_DEFPUSHBUTTON, "DEFPUSHBUTTON", BS_CHECKBOX, "CHECKBOX", BS_AUTOCHECKBOX, "AUTOCHECKBOX", BS_RADIOBUTTON, "RADIOBUTTON", BS_3STATE, "3STATE", BS_AUTO3STATE, "AUTO3STATE", BS_GROUPBOX, "GROUPBOX", BS_AUTORADIOBUTTON, "AUTORADIO", BS_OWNERDRAW, "OWNERDRAW" } ; #define NUM (sizeof button / sizeof button[0])
Petzold Example: BTNLOOK Code, WinMain, 2 // nothing new in WinMain int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "BtnLook" ; HWND hwnd ; MSG msg ; WNDCLASSEX wndclass ; wndclass.cbSize = sizeof (wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; : : wndclass.lpszClassName = szAppName ; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ; hwnd = CreateWindow (szAppName, "Button Look", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; }
Petzold Example: BTNLOOK Code, WndProc: Create Buttons, 3a WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { // labels and format strings to display numeric parameter values, as in “sysmetrics” static char szTop[] = "iMsgwParamlParam", szUnd[] = "____ ______ ______", szFormat[] = "%-16s%04X-%04X %04X-%04X", szBuffer[50] ; static HWND hwndButton[NUM] ; // as earlier, array of, here, handles : switch (iMsg) { case WM_CREATE : hdc = GetDC (hwnd) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cyChar = tm.tmHeight + tm.tmExternalLeading ; ReleaseDC (hwnd, hdc) ; // create the buttons (buttons have type and characteristics): // more detail this loop next slide for (i = 0 ; i < NUM ; i++) hwndButton[i] = CreateWindow ("button", // built-in class button[i].text, // label for button WS_CHILD | WS_VISIBLE | button[i].style, // BS_.... cxChar, cyChar * (1 + 2 * i), // xLoc, yLoc 20 * cxChar, 7 * cyChar / 4, // width, height hwnd, // parent window handle (HMENU) i, // control id (more later) ((LPCREATESTRUCT) lParam) -> hInstance, // hinstance NULL) ; return 0 ;
Petzold Example: BTNLOOK Code, WndProc: Create Buttons, 3b // Here is code to create the buttons: for (i = 0 ; i < NUM ; i++) hwndButton[i] = CreateWindow ("button", // built-in class button[i].text, // label for button WS_CHILD | WS_VISIBLE | button[i].style, // BS_PUSHBUTTON, BS_ .... cxChar, cyChar * (1 + 2 * i), // xLoc, yLoc 20 * cxChar, 7 * cyChar / 4, // width, height hwnd, // parent window handle (HMENU) i, // control id – “arbitrary”, but got to have! ((LPCREATESTRUCT) lParam) -> hInstance, // hinstance NULL) ; Here is how displayed buttons appear: To “take it apart”, 1st, recall: button[ ] = { // .style: .*text: BS_PUSHBUTTON, "PUSHBUTTON", BS_DEFPUSHBUTTON, "DEFPUSHBUTTON", …
Petzold: BTNLOOK Code, WndProc: Respond to Button Clicks, 4 case WM_SIZE : rect.left = 24 * cxChar ; rect.top = 2 * cyChar ; rect.right = LOWORD (lParam) ; rect.bottom = HIWORD (lParam) ; return 0 ; case WM_PAINT : InvalidateRect (hwnd, &rect, TRUE) ; hdc = BeginPaint (hwnd, &ps) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; SetBkMode (hdc, TRANSPARENT) ; TextOut (hdc, 24 * cxChar, cyChar, szTop, sizeof (szTop) - 1) ; TextOut (hdc, 24 * cxChar, cyChar, szUnd, sizeof (szUnd) - 1) ; EndPaint (hwnd, &ps) ; return 0 ; // basicaly, just use button info to TextOut - (main idea is that each button has code associated with it) case WM_DRAWITEM : case WM_COMMAND : ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ; // now they tell me! hdc = GetDC (hwnd) ; SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ; TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1), szBuffer, // below is what is put in szBuffer: wsprintf (szBuffer, szFormat, iMsg == WM_DRAWITEM ? "WM_DRAWITEM" : "WM_COMMAND", HIWORD (wParam), LOWORD (wParam), HIWORD (lParam), LOWORD (lParam))) ; ReleaseDC (hwnd, hdc) ; ValidateRect (hwnd, &rect) ; break ;
Finally!, Dialog Boxes Typically, a popup window with child window controls, as above In fact could create a (child) window of your program, with various child window controls Then, handle interactions in the (child) window procedure, which then might pass selected information back to the “main” window procedure This basically the strategy, however, “Windowese” involved, both with respect to terminology and control structure About: Used for getting more information than just by menus Menu item with ellipsis (...) indicates more
Dialog Box Program Structure 1. Dialog (Box) Procedure like a “window procedure” by convention, not do much: initializes, handles messages, ends 2. Dialog Box Manager in Windows handles messages, but passes many on to your dialog box manager 3. Dialog Box again, popup window with child window controls created by ”dialog box template” in resource script Will need to add: 1. Dialog box template in resource script, in <prog>.rc 2. Dialog box procedure (handles msgs, etc.) in source code file, <prog>.c 3. Identifiers in header file, <prog>.h
Simple Example: 1, Screen and Header File Program has single item menu and when select “About...” menu item, displays simple dialog box Piece by Piece: 1. Header file (about.h): #define IDM_ABOUT 1
Simple Example 2: Resource Script - Menu 2. ABOUT1.RC resource script #include <windows.h> #include "about1.h" About1 ICON about1.ico About1 MENU { POPUP "&Help" { MENUITEM "&About About1...", IDM_ABOUT } }
Simple Example 3: Resource Script - Dialog Box Template Script OK, maybe not so simple below … Dialog Box Template is a script for creating graphic + text layout + variable association + … 3. Dialog Box Template as menu template, but more elements – even child windows AboutBox DIALOG 20, 20, 160, 80 // initial location STYLE WS_POPUP | WS_DLGFRAME // style { // dialog items: // locations of each: CTEXT "About1" -1, 0, 12, 160, 8 ICON "About1" -1, 8, 8, 0, 0 CTEXT "About Box Demo Program" -1, 0, 36, 160, 8 CTEXT "(c) Charles Petzold, 1996" -1, 0, 48, 160, 8 // create “default push button” - with IDOK (builtin) as “msg” // value of IDOK sent to program, when this button clicked – how tell what done! DEFPUSHBUTTON "OK" IDOK, 64, 60, 32, 14, WS_GROUP // make them a group } “IDOK” is a windows.h constant, and is, here, the identifier of the button Yes, dialog box can be created with resource editor, but ... Ultimately need to understand working
Simple Example: C Source - WinMain // nothing new here, except icon #include <windows.h> #include "about1.h" WinMain ( ... ) { static char szAppName[ ] = "About1" ; : wndclass.cbSize = sizeof (wndclass) ; : wndclass.hIconSm = LoadIcon (hInstance, szAppName) ; RegisterClassEx (&wndclass) ; hwnd = CreateWindow (szAppName, "About Box Demo Program", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; }
Simple Example: C Source - WndProc // menu selection “invokes” (causes to be shown) dialog box, // and its attendant control structure comes to play // note name “AboutBox” defined in resource script WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static WNDPROC lpfnAboutDlgProc ; static HINSTANCE hInstance ; switch (iMsg) { case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; return 0 ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDM_ABOUT : // display the dialog box (“AboutBox”) controled by “Ab..Proc” DialogBox (hInstance, "AboutBox", hwnd, AboutDlgProc) ; // next page return 0 ; } break ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }
Simple Example: C Source – Dialog Box Procedure 5. Dialog box procedure is a new program element analogous to wndproc’s to date Handles input, from def push button, using identifiers defined in dlg box template! AboutDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { // nothing to do upon creation case WM_INITDIALOG : return TRUE ; // like menu input (WM_COMMAND w/ identifiers, here, from dlg box template) case WM_COMMAND : switch (LOWORD (wParam)) { // defined in dialog box template case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; }
End • . (or not)
A More Complicated Ex: Res Script - Header File ABOUT2.H header file in fact the values given here will be used as array indices in various places in prog. #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
A More Complicated Ex: Res Script - Dialog Box Template Script OK, in real life the resource editor is used (but you could …): 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 }
A More Complicated Ex: C Source, WinMain int iCurrentColor = IDD_BLACK, // just make the current color black iCurrentFigure = IDD_RECT ; // and figure a rectangle // nothing special here int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "About2" ; : wndclass.cbSize = sizeof (wndclass) ; : wndclass.hIconSm = LoadIcon (hInstance, szAppName) ; RegisterClassEx (&wndclass) ; hwnd = CreateWindow (szAppName, "About Box Demo Program", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; }
A More Complicated Ex: C Source, PaintWindow void PaintWindow (HWND hwnd, int iColor, int iFigure) { // again, order here depends on order of definition in header file static COLORREF crColor[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 (crColor[iColor - IDD_BLACK]) ; hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; if (iFigure == 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) ; }
A More Complicated Ex: C Source, PaintTheBlock // note values passed for color and figure void PaintTheBlock (HWND hCtrl, int iColor, int iFigure) { InvalidateRect (hCtrl, NULL, TRUE) ; UpdateWindow (hCtrl) ; PaintWindow (hCtrl, iColor, iFigure) ; }
A More Complicated Ex: C Source, WndProc WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInstance ; PAINTSTRUCT ps ; switch (iMsg) { case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; return 0 ; case WM_COMMAND : switch (LOWORD (wParam)) { // invoke the dialog box upon menu selection case IDM_ABOUT : if (DialogBox (hInstance, "AboutBox", hwnd, AboutDlgProc)) InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT : BeginPaint (hwnd, &ps) ; EndPaint (hwnd, &ps) ; PaintWindow (hwnd, iCurrentColor, iCurrentFigure) ; return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }
A More Complicated Ex: C Source, AboutDlgProc, InitDialog // dialog box procedure AboutDlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { static HWND hCtrlBlock ; static int iColor, iFigure ; switch (iMsg) { case WM_INITDIALOG : iColor = iCurrentColor ; // globals iFigure = iCurrentFigure ; CheckRadioButton (hDlg, IDD_BLACK, IDD_WHITE, iColor) ; CheckRadioButton (hDlg, IDD_RECT, IDD_ELL, iFigure) ; hCtrlBlock = GetDlgItem (hDlg, IDD_PAINT) ; SetFocus (GetDlgItem (hDlg, iColor)) ; return FALSE ;
A Complicated Ex: C Source, AboutDlgProc, WM_COMMAND case WM_COMMAND : // which is identifier value switch (LOWORD (wParam)) { case IDOK : iCurrentColor = iColor ; iCurrentFigure = iFigure ; EndDialog (hDlg, TRUE) ; return TRUE ; case IDCANCEL : EndDialog (hDlg, FALSE) ; return TRUE ; case IDD_BLACK : // exploits values of constants from header file case IDD_RED : case IDD_GREEN : case IDD_YELLOW : case IDD_BLUE : case IDD_MAGENTA : case IDD_CYAN : case IDD_WHITE : iColor = LOWORD (wParam) ; CheckRadioButton // send a msg to child (button) window (hDlg, IDD_BLACK, IDD_WHITE, LOWORD (wParam)); PaintTheBlock (hCtrlBlock, iColor, iFigure) ; return TRUE ; (cont’d)
A Complicated Ex: C Source, AboutDlgProc, WM_COMMAND // end of switch - nothing case IDD_RECT : case IDD_ELL : iFigure = LOWORD (wParam) ; CheckRadioButton (hDlg, IDD_RECT, IDD_ELL,LOWORD (wParam)); PaintTheBlock (hCtrlBlock, iColor, iFigure) ; return TRUE ; } break ; case WM_PAINT : PaintTheBlock (hCtrlBlock, iColor, iFigure) ; break ; } return FALSE ; }
End • .