Dialogs, GUI coders best friend
There's hardly a windows program out there that doesn't use dialog boxes. Just go File -> Open in any text editor or any other kind of editor for that matter and voila, you are presented with a dialog box, one that probably allows you to select a file to be opened.
Dialogs aren't limited to the standard open file ones, they can look like and do whatever you choose. The attractive point of dialogs is that they provide a quick way to arrange and create a GUI (Graphic User Interface) and even some default processing, cutting down on the amount of code you must write.
One thing to remember is that dialogs are just windows. The difference between a dialog and a "normal" window is that the system does some additional default processing for dialogs, such as creating and initialising controls, and handling tab order. Nearly all APIs that are applicable to "normal" windows will work just as well on dialogs, and vice versa!
The first step is to create the dialog resource. The resource file we will use in this example is included in the download.
So! We now need to write a Dialog Procedure to process message for this box. Don't worry this is nothing new, it's practicly the same as our main Window Procedure (but not exactly).
PROCEDURE AboutDlgProc(hwnd : HWND; msg : UINT; wParam : WPARAM; lParam : LPARAM) : BOOL [EXPORT, OSCall]; BEGIN CASE msg OF | WM_INITDIALOG : RETURN TRUE; | WM_COMMAND : CASE LOWORD(wParam) OF | IDOK : FUNC EndDialog(hwnd, IDOK); | IDCANCEL : FUNC EndDialog(hwnd, IDCANCEL); ELSE END; ELSE RETURN FALSE; END; RETURN TRUE; END AboutDlgProc;
There are a few important differences between a dialog procedure and window
procedure. One is that you DO NOT call
Secondly, in general you return FALSE for messages you don't process, and TRUE for
messages you do process, UNLESS the message specifies you return something
else. Note that this is what we do above, the default is to do nothing and return FALSE,
while messages we do handle break the
Thirdy, You do not call
Finally, instead of handling
Enough chit-chat, lets create it....
| WM_COMMAND : CASE LOWORD(wParam) OF | ID_HELP_ABOUT : ret := DialogBoxId(Instance, IDD_ABOUT, hwnd, AboutDlgProc); IF ret = IDOK THEN MessageBox(hwnd, "Dialog exited with IDOK.", "Notice", MB_OK BOR MB_ICONINFORMATION); ELSIF ret = IDCANCEL THEN MessageBox(hwnd, "Dialog exited with IDCANCEL.", "Notice", MB_OK BOR MB_ICONINFORMATION); ELSIF ret = -1 THEN MessageBox(hwnd, "Dialog failed!", "Error", MB_OK BOR MB_ICONINFORMATION); END; (* other menu commands *)
This is the code I used to create my about box, you can probably guess that
this is to be merged into your
Since we want the menu on our main window to create the dialog, we obviously want to
put this code in the
Now I stored the return value from the call to
ret := DialogBoxId(Instance, IDD_ABOUT, hwnd, AboutDlgProc);
This is the only important part, and you can choose to put it wherever in your
code that you want the dialog to come up.
A perticularly astute reader might eventually wonder, if
Another effect of using DialogBox is that your main window is disabled untill the dialog is dismissed. Sometimes this is what we want, and sometimes it isn't, such as when we want to use a dialog as a floating toolbar. In this case we want to be able to interact with both out dialog and our main window, and this will be the focus of the next section.
Copyright © 1998-2011, Brook Miles. All rights reserved. Adapted for Modula-2 by Frank Schoonjans, with permission.