Dialog BoxesIntroductionIn this part of the tutorial, we will cover:
There is much lamenting of the number of lines required to write a Windows application with a window. Estimates range from 40 lines to over 100. I am here to tell you - it can be done in under 15. ResourcesIn Windows, many of your program elements (icons, cursors, bitmaps, menus, dialogs, accelerators and strings) are stored separately from the main program code. They are stored as resources. To create resources, you need a .RC file, known as a resource script. You will need a resource editor to design resources. While it is possible to generate resource scripts by hand, it is a tedious, error-prone and time-consuming process of trial and error, and not recommended. A resource editor is integrated into most IDEs. The first step in creating a dialog box is to design it. Create a resource script in your editor of choice and add a dialog box. Add OK and Cancel buttons and assign them IDs of IDOK and IDCANCEL respectively. Give the dialog box an ID of IDD_DIALOG1. Your dialog box should look something like the following.
When you save your resource file, your resource editor will produce a header (.h) file that maps these IDs to numbers. You will need this file when you write your code. In the examples below, I call this file 'resource.h'. If yours is something different, replace the name in the examples. When you build your program, you will have to include your resource script in the project or on the command line. This varies from compiler to compiler. Creating a dialog boxNow we've created our dialog box resource, our next step is to write some code to call up the box.Before we do so, it is worth taking note of the difference in this area from standard DOS programming. In DOS, you had complete control over the order in which things happened, and you took action at certain points. In a modern GUI, this is no longer acceptable, and programs are now event-driven. Windows will send you a message when something happens or it wants you to do something. In order to accept messages, therefore, we need to give Windows some code to handle these messages, and this code is a callback function. Windows will 'call back' your function when a message arrives. (That doesn't mean you have to do anything, but you still need the callback.) #include <windows.h> #include <tchar.h> #include "resource.h" BOOL MainDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return FALSE; } int _tmain(void) { DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)MainDialogProc, 0); return 0; } If you're running VC++, make sure you select 'Win32 Console Application' when you select 'New Project'. And there we have it - a Windows program in 13 lines of code. That was easy, wasn't it? Having problems? If your program just quits without producing a dialog box, check that the RC (resource script) file is included in your project (or whatever method you require for your compiler). Now, this program doesn't do a great deal, as you can see if you look in the callback function. However, it has a lot of functionality - you can move the box around, click buttons, interact with any other controls you may have put on there. To make the box respond, however, we will need to handle the messages from Windows. Message HandlingThe messages are passed into our MainDialogProc. The uMsg parameter contains the message identifier. The wParam and lParam arguments contain data associated with the message. The hWnd parameter is a 'handle' to our window. Handles are numbers that identify an item of a specific type. In this case, hWnd is a unique number that identifies our dialog box. We will use this number whenever we want to Let's handle the Close icon first. We can do this by testing to see if the uMsg parameter is WM_CLOSE, which says that either the Close icon was clicked or someone pressed Alt+F4. When that happens, we want to close the box. Since we may want to add several messages, we will use a switch statement. BOOL MainDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
EndDialog(hWnd, 0);
return TRUE;
}
return FALSE;
}
When we process a message, we return TRUE to say 'we've handled this message, don't take the default action'. Our box can now accept the 'Close' button at the top right. Command HandlingThe next step is to accept some input from the controls. Again, Windows sends us a message. This time, the message ID is WM_COMMAND. The particular control ID is passed in the low-order word of wParam, so we will want to switch on that. Other parameters are passed in wParam and lParam, so it is most convenient to move this to a separate function. Our message handling function now contains: BOOL MainDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
return MainDialog_OnCommand(hWnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
case WM_CLOSE:
EndDialog(hWnd, 0);
return TRUE;
}
return FALSE;
}
and we have another function, called MainDialog_OnCommand: BOOL MainDialog_OnCommand(HWND hWnd, WORD wCommand, WORD wNotify, HWND hControl)
{
switch (wCommand)
{
case IDOK:
MessageBox(hWnd, _T("Bye-bye world!"), _T("Sample Application"), MB_OK);
// fall through
case IDCANCEL:
EndDialog(hWnd, wCommand);
break;
}
return TRUE;
}
There are a multitude of other messages available. You can read about them in MSDN. These, though, are the important ones for now. In summary then: we have managed to put up a dialog box and get it to respond to push buttons - but we have achieved something that would be difficult ever to approach in DOS, in just a few lines of code. Our final program is about 40 lines long. In the next section, we will add some controls to our dialog box to make it more useful. |
|
Copyright © David McCabe, 1998 - 2001. All rights reserved. You will need to download and install the m-math control to display any equations on this Web site. Without this control, you will not see most of the equations. Please do not e-mail me asking why the equations do not display! |