Jump to content

PMGuide - Dialog Windows: Difference between revisions

From EDM2
Created page with "Dialog windows (also called dialog boxes) provide a high-level method for applications to display and gather information. This chapter describes the creation and use of dialog..."
 
Ak120 (talk | contribs)
mNo edit summary
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
{{IBM-Reprint}}
{{PMGuide}}
Dialog windows (also called dialog boxes) provide a high-level method for applications to display and gather information. This chapter describes the creation and use of dialog windows and message boxes in your PM applications.
Dialog windows (also called dialog boxes) provide a high-level method for applications to display and gather information. This chapter describes the creation and use of dialog windows and message boxes in your PM applications.


Line 44: Line 46:


In creating enhanced message boxes, the MB2INFO button information block structure is used to specify button style flags as shown in the following table:
In creating enhanced message boxes, the MB2INFO button information block structure is used to specify button style flags as shown in the following table:
<pre>
{|class=wikitable
┌────────────────────┬────────────────────────────────────────┐
!Style Name||Description
│Style Name         │Description                            │
|-
├────────────────────┼────────────────────────────────────────┤
|MB_APPLMODAL||Message box is application modal. This is the default case.
│MB_APPLMODAL        │Message box is application modal. This
|-
│                    │is the default case.                   │
|MB_CUSTOMICON||A user-specified value.
├────────────────────┼────────────────────────────────────────┤
|-
│MB_CUSTOMICON      │A user-specified value.                 │
|MB_ERROR||Message box contains a small red circle with a red line across it.
├────────────────────┼────────────────────────────────────────┤
|-
│MB_ERROR            │Message box contains a small red circle
|MB_ICONASTERISK||Message box contains an information (i) icon.
│                    │with a red line across it.             │
|-
├────────────────────┼────────────────────────────────────────┤
|MB_ICONEXCLAMATION||Message box contains an exclamation point (!) icon.
│MB_ICONASTERISK    │Message box contains an information (i)
|-
│                    │icon.                                   │
|MB_ICONHAND||Message box contains a small red circle with a red line across it.
├────────────────────┼────────────────────────────────────────┤
|-
│MB_ICONEXCLAMATION  │Message box contains an exclamation     │
|MB_ICONQUESTION||Message box contains a question mark (?) icon.
│                    │point (!) icon.                         │
|-
├────────────────────┼────────────────────────────────────────┤
|MB_INFORMATION||Message box contains an information (i) icon.
│MB_ICONHAND        │Message box contains a small red circle
|-
│                    │with a red line across it.             │
|MB_MOVEABLE||Message box is moveable. A title bar and system menu with Move, Close and Task Manager choices are displayed.
├────────────────────┼────────────────────────────────────────┤
|-
│MB_ICONQUESTION    │Message box contains a question mark (?)
|MB_NOICON||Message box is not to contain an icon.
│                    │icon.                                   │
|-
├────────────────────┼────────────────────────────────────────┤
|MB_NONMODAL||Message box is modeless (the program continues after displaying the message box).
│MB_INFORMATION      │Message box contains an information (i)
|-
│                    │icon.                                   │
|MB_QUERY||Message box contains a question mark (?) icon.
├────────────────────┼────────────────────────────────────────┤
|-
│MB_MOVEABLE        │Message box is moveable. A title bar   │
|MB_SYSTEMMODAL||Message box is system modal.
│                    │and system menu with Move, Close and   │
|-
│                    │Task Manager choices are displayed.     │
|MB_WARNING||Message box contains an exclamation point (!) icon.
├────────────────────┼────────────────────────────────────────┤
|}
│MB_NOICON          │Message box is not to contain an icon.
 
├────────────────────┼────────────────────────────────────────┤
│MB_NONMODAL        │Message box is modeless (the program   │
│                    │continues after displaying the message
│                    │box).                                   │
├────────────────────┼────────────────────────────────────────┤
│MB_QUERY            │Message box contains a question mark (?)
│                    │icon.                                   │
├────────────────────┼────────────────────────────────────────┤
│MB_SYSTEMMODAL      │Message box is system modal.           │
├────────────────────┼────────────────────────────────────────┤
│MB_WARNING          │Message box contains an exclamation     │
│                    │point (!) icon.                         │
└────────────────────┴────────────────────────────────────────┘
</pre>
====Minimizing Dialog Windows====
====Minimizing Dialog Windows====
Whenever the dialog window is to be minimized to the desktop (as opposed to the Minimized Window Viewer), the program should hide all its child control windows, then restore them when the dialog needs to be restored.
Whenever the dialog window is to be minimized to the desktop (as opposed to the Minimized Window Viewer), the program should hide all its child control windows, then restore them when the dialog needs to be restored.


====Dialog Data Structures====
====Dialog Data Structures====

Latest revision as of 01:27, 22 May 2024

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Presentation Manager Programming Guide and Reference
  1. How to Use this Book
  2. Device Functions
  3. Direct Manipulation Functions
  4. Dynamic Data Formatting Functions
  5. Hooks and Procedures
  6. Profile Functions
  7. Spooler Functions
  8. Window Functions
  9. Message Processing
  10. Data Types
  11. Errors
  12. Atom Tables
  13. Button Controls
  14. Clipboards
  15. Combination Box
  16. Container Controls
  17. Control Windows
  18. Cursors
  19. Dialog Windows
  20. Direct Manipulation
  21. Drawing in Windows
  22. Dynamic Data Exchange
  23. Entry-Field Controls
  24. File Dialog Controls
  25. Font Dialog Controls
  26. Frame Windows
  27. Hooks
  28. Initialization Files
  29. Keyboard Accelerators
  30. List-Box Controls
  31. Menus
  32. Messages and Message Queues
  33. Multiple-Line Entry Field Controls
  34. Mouse and Keyboard Input
  35. Mouse Pointers and Icons
  36. Notebook Controls
  37. Painting and Drawing
  38. Presentation Parameters
  39. Resource Files
  40. Scroll-Bar Controls
  41. Slider Controls
  42. Spin Button Controls
  43. Static Controls
  44. Title-Bar Controls
  45. Value Set Controls
  46. Windows
  47. Window Classes
  48. Window Procedures
  49. Window Timers
  50. Appendices
  51. Notices
  52. Glossary

Dialog windows (also called dialog boxes) provide a high-level method for applications to display and gather information. This chapter describes the creation and use of dialog windows and message boxes in your PM applications.

Note: Dialog windows, dialog boxes, and message boxes all are secondary windows to the user.

About Dialog Windows

A dialog window is a temporary window that contains one or more control windows and, typically, is used to display messages to and gather input from the user. An application usually destroys a dialog window immediately after using it.

The OS/2 operating system contains many functions and messages that help manage the control windows that make up a dialog window, thereby easing the burden of maintaining complex input and output systems.

Modal and Modeless Dialog Windows

Dialog windows can be modal or modeless. A modal dialog window requires that the dialog window be dismissed before the user can activate other windows in the same application. Generally, an application uses a modal dialog window to get essential information from the user before proceeding with an operation. A modeless dialog window allows the user to activate other windows in the same application without dismissing the dialog window. Both modal and modeless dialog windows allow the user to activate windows in another application before responding to the dialog window.

Modal dialog windows are easier for an application to manage because they are created, perform their task, and are closed, all with a single function call.

Modeless dialog windows require more attention from the application because they exist until explicitly dismissed. Modeless dialog windows provide a more flexible interface, however, by allowing the user to move to other windows in the application before responding to the dialog window.

Dialog Items

A dialog item is a child window of the dialog window, which usually is a window of class WC_FRAME. The operating system provides many predefined window classes, called control windows, that you can use as dialog items. Predefined control windows include static display boxes, text-entry fields, buttons, and list boxes. You also can use customized window classes as dialog items.

Dialog items are windows and, thus, can be manipulated by all window-management functions relating to size, position, and visibility. Dialog items always are owned by the dialog frame window. Most predefined control-window classes send notification messages to their owners when the user interacts with their control windows. The dialog frame window receives these notification messages and passes them to the application through the application-defined dialog procedure.


Dialog-Item Groups

Items within a dialog window can be organized into dialog-item groups. When items are arranged in a group, the user can move from one item to another in the same group by using the direction keys. When the user presses a direction key, the focus will not shift to items in other groups within the dialog window.

Arranging items in groups is useful for radio buttons and check boxes. Although some control types also can be displayed this way, entry-field controls cannot; they process direction keys themselves, as do MLE, value-set, container, slider, and notebook controls.

The first item in a dialog-item group has the WS_GROUP window style. All subsequent items in the dialog template are considered part of that group until another item is given the WS_GROUP style, which begins a new group.

The WS_TABSTOP style often is used along with the WS_GROUP style. WS_TABSTOP marks the items that can receive the focus when the user presses the Tab key. Each time the user presses the Tab key, the focus moves to the next item that has the WS_TABSTOP style. Generally, the WS_GROUP and WS_TABSTOP styles are defined together for the first item of each group in the dialog template. This makes it possible for a user to press the Tab key to move among groups of items and to use the direction keys to move among items in a group.

The WS_TABSTOP style should not be used for radio buttons because the system automatically maintains a tab stop on any selected item in a radio-button group; therefore, when the Tab key is pressed in a group of radio buttons, the focus remains on the currently selected item.

The WS_GROUP and WS_TABSTOP styles are also useful for preventing the user from moving to a particular button when using the keyboard. For example, if the dialog window has OK and Cancel push buttons, they should be in the same group, with the OK push button as the first item in the group. The user can press Tab to select the OK push button but not the Cancel push button. To move to the Cancel button using the keyboard, the user first must press the Tab key to move to the OK push button, and then press a direction key to move the focus to the Cancel push button.

Message Boxes

Message boxes are dialog windows predefined by the system and used as a simple interface for applications, without the necessity of creating dialog-template resources or dialog procedures. Message boxes are best for short notification messages that require a simple acknowledgment or choice by the user. Applications do not specify a dialog procedure for message boxes, so they cannot readily change the action of a message box. However, there is no need to do so, since there are many predefined message-box styles. There are two types of message boxes available to applications: standard and enhanced.

Standard Message Boxes

To generate a standard message box, an application calls WinMessageBox and specifies the type of message box and message text. The system displays the message and waits for the user to dismiss the message box by selecting a button in the message box. The system then returns a result code to the application, indicating which button the user selected.

Standard message boxes are always modal-either application-modal or system-modal. Application-modal (the default style) means that the user cannot activate another window in the current application before responding to the message box but can switch to another application. System-modal means that the user cannot activate another window in any application before responding to the message box. A system-modal message box should be used only to display urgent error messages (running out of memory, for example).

Enhanced Message Boxes

To generate an enhanced message box, an application calls WinMessageBox2. An enhanced message box has all the functionality of the standard message box, with the addition of the following:

  • It can be modeless.
  • Its buttons can be customized with text and icons.
  • It can support customized icons in the window icon field.

In creating enhanced message boxes, the MB2INFO button information block structure is used to specify button style flags as shown in the following table:

Style Name Description
MB_APPLMODAL Message box is application modal. This is the default case.
MB_CUSTOMICON A user-specified value.
MB_ERROR Message box contains a small red circle with a red line across it.
MB_ICONASTERISK Message box contains an information (i) icon.
MB_ICONEXCLAMATION Message box contains an exclamation point (!) icon.
MB_ICONHAND Message box contains a small red circle with a red line across it.
MB_ICONQUESTION Message box contains a question mark (?) icon.
MB_INFORMATION Message box contains an information (i) icon.
MB_MOVEABLE Message box is moveable. A title bar and system menu with Move, Close and Task Manager choices are displayed.
MB_NOICON Message box is not to contain an icon.
MB_NONMODAL Message box is modeless (the program continues after displaying the message box).
MB_QUERY Message box contains a question mark (?) icon.
MB_SYSTEMMODAL Message box is system modal.
MB_WARNING Message box contains an exclamation point (!) icon.

Minimizing Dialog Windows

Whenever the dialog window is to be minimized to the desktop (as opposed to the Minimized Window Viewer), the program should hide all its child control windows, then restore them when the dialog needs to be restored.

Dialog Data Structures

Each item in a dialog window is described by a DLGTITEM data structure. This structure is rarely accessed directly by an application, since system functions handle most of the manipulation of dialog items. Applications that create dialog items that are not defined as part of a dialog-template resource must create dialog-window-item structures in memory.

A dialog window can have many items, so applications can use another structure, DLGTEMPLATE, to define the items. This structure consists of header information, followed by an array of dialog-window items. Applications that create dialog windows without using dialog resources must create a dialog template in memory, and, then, call the WinCreateDlg function.

Dialog Resources

Most applications define dialog templates in resource files rather than constructing template data structures in memory at run time. The dialog resource file defines the size and style of the dialog-window frame and specifies each dialog item.

The dimensions and position of each dialog item are specified in dialog coordinates, which are based on the size of the system font. A horizontal unit is one-fourth the average width of the characters in the system font; a vertical unit is one-eighth the average height of the characters in the system font. The origin of the dialog template is the lower-left corner of the dialog window. The operating system provides the WinMapDlgPoints function for converting dialog coordinates into window coordinates.

Using Message Boxes and Dialog Windows

The simplest dialog window is the message box. Most message boxes present simple messages and offer the user one, two, or three responses (represented by buttons). A message box is easy to use and is appropriate when an application requires a clearly defined response to a static message. However, standard message boxes lack flexibility in size and placement on the screen and are limited in the choices they offer the user. Applications that require more control over the size, position, and content should use enhanced message boxes or regular Dialog Windows instead of standard message boxes.

Creating a Standard Message Box

There are three parts to a message box: the icon, the message, and buttons. Applications specify the icons and buttons by using message-box style constants. Message text is specified by a null-terminated string.

To create a message box, the application calls WinMessageBox, which displays the message box and processes user input until the user selects a button in the message box. The WinMessageBox return value indicates which button the user selected.

The following code fragment illustrates how to create a message box with a default Yes button, a No button, and a question-mark (?) icon. This example assumes that you have defined a string resource with the MY_MESSAGESTR_ID identifier in the resource file.

    UCHAR  szMessageString[255];
    ULONG  ulResult;

    WinLoadString(hab, (HMODULE) NULL, MY_MESSAGESTR_ID,
        sizeof(szMessageString), szMessageString);

    ulResult = WinMessageBox(hwndFrame,  /* Parent    */
        hwndFrame,                       /* Owner     */
        szMessageString,                 /* Text      */
        (PSZ) NULL,                      /* caption   */
        MY_MESSAGEWIN,                   /* Window ID */
        MB_YESNO |
        MB_ICONQUESTION |
        MB_DEFBUTTON1);                  /* Style     */

     if (ulResult == MBID_YES) {

          /* Do yes case. */

     } else {

          /* Do no case.  */
     }

The WinMessageBox function returns predefined values indicating which button has been selected.

Notice that strings for message boxes should be defined as string resources to facilitate program translation for other countries. However, there is danger in using string resources in message boxes that are called in low-memory situations; loading a string resource in such situations could result in severe memory problems and cause an application to fail. One way to prevent this problem is to preload the string resource and make it nondiscardable so it will be available when the message box must be displayed.

Creating a System-Modal Standard Message Box

There are two levels of modality for system-modal message boxes-soft modal and hard modal. A soft-modal message box does not allow keystrokes or mouse input to reach any other window but does allow other messages, such as deactivation and timer messages, to reach other windows. A hard-modal message box does not allow any messages to reach other windows. A hard-model message box is appropriate for serious system warnings.

To create a hard-modal message box, combine the MB_ICONHAND style with the MB_SYSTEMMODAL style. To create a soft-modal message box, use the MB_SYSTEMMODAL style with any style other than MB_ICONHAND. The MB_SYSTEMMODAL icon always is in memory and is available even in low-memory situations.

Creating an Enhanced Message Box

WinMessageBox2 creates a message window that can be used to display error messages and ask questions. It is a more powerful version of WinMessageBox, including options for non-modality and customization of buttons with text and icons or mini-icons. Buttons included in the enhanced message box are specified in the button definition array MB2D, where custom text can be added.

To support the use of the MB_NONMODAL style, two notification messages are used:

WM_MSGBOXINIT
This message notifies the owner of the message when a non-modal message box is being displayed. It is the responsibility of the owner window to store the window handle returned by the function for later use when the message box is to be destroyed.
WM_MSGBOXDISMISS
This message notifies the owner of the message when a non-modal message box has been dismissed. It is the parent window's responsibility to destroy the message box.

The following example uses WinMessageBox2 to create a message box containing a customized icon:

    #define  INCL_WINDIALOGS          /* Window Dialog Manager Functions   */
    #define  INCL_WINPOINTERS         /* Window Pointer Functions          */

    #include <os2.h>
    #include <stdio.h>
    #include <string.h>

    CHAR      szMsg[100];         /* Message
    HWND      hwndClient;             /* Client-window handle                */
    MB2INFO   mb2info;                /* Message Box input structure         */

    MB2D mb2d[4] = {                  /* Array of button definitions*/
        { "AAAA", ID_BUTTON1, BS_DEFAULT},
        { "BBBB", ID_BUTTON2, 0},
        { "CCCC",  ID_BUTTON3, 0},
        { "DDDD", ID_BUTTON4, 0}
    };

     mb2info.hIcon = WinLoadPointer(HWND_DESKTOP, 0, ID_ICON1);
     mb2info.cButtons = 4;            /* Number of buttons   */
     mb2info.flStyle = MB_CUSTOMICON | MB_MOVEABLE;
                                      /* Icon style flags    */
     mb2info.hwndNotify = NULLHANDLE; /* Reserved            */
     mb2info.cb = sizeof(MB2INFO) + ((mb2info.cButons >1) ?
                  (mb2info.cButtons -1) * sizeof (MB2D) : 0);

     memcpy (&mb2info.mb2d, &mb2d, mb2info.cb);

     mb2info.pmb2d = mb2d;            /* Array of button definitions*/

     sprintf (&szMsg, %s, "Error condition exists");

     WinMessageBox2(HWND_DESKTOP,
                    hwndClient,       /* Client-window handle     */
                   &szMsg,            /* Body of the message
                   "Debugging Information",
                                      /* Title of the message     */
                   0,                 /* Message Box id           */
                   &mb2info);         /* Message Box input structure

Using a Dialog Window

When using a dialog window, an application must load the dialog window, process user input, and destroy the dialog window when the user finishes the task. The process for handling a dialog window varies, depending on whether the dialog window is modal or modeless.

Creating a Dialog Template

The following source-code fragment creates a dialog template. Notice that the WS_GROUP and WS_TABSTOP style designations are given for the first item in each group.

    DLGTEMPLATE IDD_ABOUT
    BEGIN
      DIALOG "", IDD_ABOUT2,
      10, 10, 150, 110, FS_DLGBORDER, 0
      BEGIN
        CONTROL "Attributes:",100,
          10, 30, 100, 70,
          WC_STATIC,
          SS_GROUPBOX | WS_VISIBLE
        CONTROL "Highlighted",101,
          20, 80, 58, 12,
          WC_BUTTON,
          WS_GROUP | WS_TABSTOP | BS_AUTOCHECKBOX | WS_VISIBLE
        CONTROL "Enabled",102,
          20, 60, 58, 12,
          WC_BUTTON,
          BS_AUTOCHECKBOX | WS_VISIBLE
        CONTROL "Checked",103,
          20, 40, 58, 12,
          WC_BUTTON,
          BS_AUTOCHECKBOX | WS_VISIBLE
        CONTROL "Okay", DID_OK,
          10, 10, 50, 14,
          WC_BUTTON,
          WS_GROUP | WS_TABSTOP | BS_PUSHBUTTON | BS_DEFAULT | WS_VISIBLE
        CONTROL "Cancel", DID_CANCEL,
          80, 10, 50, 14,
          WC_BUTTON,
          BS_PUSHBUTTON | WS_VISIBLE
      END
    END
Creating a Modal Dialog Window

The easiest way to use a modal dialog window is to define a dialog template in the resource file (as in the preceding section), and then, call the WinDlgBox function, specifying the dialog-window resource identifier and a pointer to the dialog procedure. WinDlgBox loads the dialog-window resource, displays the dialog window, and handles all user input until the user dismisses the dialog window. The dialog procedure receives messages when the dialog window is created (WM_INITDLG) and other messages each time the user interacts with a dialog item (enters text in entry fields or selects a button, for example).

You must specify both the parent and owner windows when loading a dialog window using the WinDlgBox function. Generally, the parent window will be HWND_DESKTOP and the owner will be a client window in your application.

Dialog windows typically contain buttons that send WM_COMMAND messages when selected by the user. WM_COMMAND messages passed to the WinDefDlgProc function result in the WinDismissDlg function's being called, with the window identifier of the source button as the return code (from WinDismissDlg). Dialog windows with either OK or Cancel as their only button can ignore WM_COMMAND messages, allowing them to be passed to WinDefDlgProc. WinDefDlgProc calls WinDismissDlg to dismiss the dialog window and returns the DID_OK or DID_CANCEL code.

Passing WM_COMMAND messages to WinDefDlgProc means that all button presses in the dialog window dismiss the dialog window. If you want certain buttons to initiate operations without closing the dialog window, or if you want to perform some processing without closing the dialog window, handle the WM_COMMAND messages in the dialog procedure.

If you handle WM_COMMAND messages in the dialog procedure, you must call WinDismissDlg to dismiss the dialog window. Your dialog procedure passes the DID_OK code to WinDismissDlg if the user selects the OK button or the DID_CANCEL code if the user selects the Cancel button.

When you call WinDismissDlg or pass the WM_COMMAND message to WinDefDlgProc, the dialog window is dismissed, and the WinDlgBox function returns the value passed to WinDismissDlg. This return value identifies the button selected.

An alternative to using WinDlgBox is to call the individual functions that duplicate its functionality, as shown in the following code fragment:

   HWND  hwndDlg;
   ULONG ulResult;

   hwndDlg = WinLoadDlg(...);
   ulResult = WinProcessDlg(hwndDlg);
   WinDestroyWindow(hwndDlg);

After calling the WinProcessDlg function, your dialog procedure must call WinDismissDlg to dismiss the dialog window. Although the dialog window is dismissed (hidden), it still exists. You must call the WinDestroyWindow function to destroy a dialog window if it was loaded using the WinLoadDlg function. WinDlgBox automatically destroys a dialog window before returning.

If you want to manipulate individual items in a dialog window, or add a menu after loading the dialog window (but before calling WinProcessDlg), it is better to make individual calls rather than call WinDlgBox. Individual calls also are useful for querying individual dialog items-to determine the contents of an entry-field control after a dialog window is closed but before it is destroyed, for example. Destroying a dialog window also destroys any dialog-item control windows that are child windows of the dialog window.

Creating a Modeless Dialog Window

To use a modeless dialog window in an application, create a dialog template in the resource file, just as for a modal dialog window. Modeless dialog windows share the screen equally with other frame windows. It is a good idea to give modeless dialog windows a title bar so they can be moved around the screen. The following Resource Compiler source-code fragment shows a dialog template for a dialog window with a title bar, system menu, and minimize button.

   DLGTEMPLATE IDD_SAMP
   BEGIN
       DIALOG "Modeless Dialog", IDD_SAMP, 80, 92, 126, 130,
           WS_VISIBLE | FS_DLGBORDER,
           FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON

       BEGIN

       /* Put control-window definitions here. */

       END
   END

The application loads the dialog resource from the resource file using the WinLoadDlg function, receiving in return a window handle to the dialog window. The application treats the dialog window as if it were an ordinary window. Messages for the dialog window are dispatched through the event loop the application uses for its other windows. In fact, an application can have a modeless dialog window as its only window.

The resource for a modeless dialog window is like the resource used for a modal dialog window. The difference between modal and modeless dialog windows is the way applications handle input to each. For a modal dialog, the WinDlgBox and WinProcessDlg functions handle all user input to the dialog window, preventing access to other windows in the application. For a modeless dialog window, the application does not call these functions, relying instead on a normal message loop to dispatch messages to the dialog procedure.

The primary difference between a modeless dialog window and a standard frame window with child control windows is that, for a modeless dialog window, an application can define child windows for the dialog window in a dialog template, automating the process of creating the window and its child windows. The same effect can be achieved by creating a standard frame window, but then, the child control windows must be created individually.

It is important that an application keep track of all open modeless dialog windows so that it can destroy all open windows before terminating.

Initializing a Dialog Window

Generally, an application defines a dialog template in its resource file and loads the dialog window by calling the WinLoadDlg function or the WinDlgBox function (which calls WinLoadDlg). The dialog window is created as an invisible window unless the window style WS_VISIBLE is specified in the dialog template. A WM_INITDLG message is sent to the dialog procedure before WinLoadDlg returns. As each control defined in the template is created, the dialog procedure might receive various control notifications before the function returns. WinLoadDlg returns a handle to the dialog window immediately after creating a dialog window.

In general, it is a good idea to define a dialog window as invisible, since this allows for optimization. For example, an experienced user might type ahead rapidly, anticipating the processing of a dialog-window command. In such a case, there is no need to display the dialog window, because the user has finished the interaction before the window can be displayed. This is how the WinProcessDlg function works-it does not display a dialog window while there still are WM_CHAR messages in the input queue; it processes the WM_CHAR messages before displaying the dialog window.

As control windows in a dialog window are created from the template, strings in the template are processed by the WinSubstituteStrings function. Any WM_SUBSTITUTESTRING messages are sent to the dialog procedure before WinLoadDlg returns.

When child windows of a dialog window are created, WinSubstituteStrings is used so child windows can make substitutions in their window text. If any child-window text string contains the percent sign (%) substitution character, the length of the text string is limited to 256 characters after it is returned from the substitution.

Adding a Menu in a Dialog Window

To create a menu bar and menus in a dialog window, an application first must load the dialog window to get a handle to the dialog-frame window. The dialog-frame window can be associated with a menu resource by calling the WinLoadMenu function. This function requires arguments that specify the menu identifier and the handle of the parent window for the menu. Finally, the dialog-frame window must incorporate the menu by sending a WM_UPDATEFRAME message to the dialog window. The following code fragment illustrates these operations:

   HWND hwndDialog, hwndMenu;

   /* Get the dialog resource. */
   hwndDialog = WinLoadDlg(...);

   / Get the menu resource and attach it to the dialog window. */
   hwndMenu = WinLoadMenu(hwndDialog, ...);

   /* Inform the dialog window that it has a new menu.         */
   WinSendMsg(hwndDialog, WM_UPDATEFRAME, (MPARAM) NULL, (MPARAM) NULL);

Applications can create menus in both modal and modeless dialog windows. The preceding code fragment can be used for either type of dialog window. For a modal dialog window, your application must call the WinProcessDlg function to handle user input until the dialog window is dismissed. For a modeless dialog window, your application must call the WinShowWindow function to display the dialog window, enabling the message loop to direct messages to the dialog window.

Creating a Dialog Procedure

In contrast to window procedures, which receive WM_CREATE messages, dialog procedures receive WM_INITDLG messages, which are sent after a dialog window is created, but before it is displayed. WM_INITDLG can do the same type of initialization tasks that WM_CREATE handles, but is not the first message that is received.

For example, if a dialog window contains a list box, use WM_INITDLG to fill the list box with items. Also use this procedure to enable or disable buttons in a dialog window, depending on your application.

You also can call the WinSetDlgItemText or WinSetDlgItemShort functions during dialog initialization, to set up text items that reflect the current conditions in your application.

Another typical task for the WM_INITDLG message handler is centering a dialog window on the screen or within its owner window. The following code fragment illustrates how to center a dialog window on the screen using WM_INITDLG:

    RECTL rclScreen,rclDialog;
    LONG  sWidth,sHeight,sBLCx,sBLCy;

    case WM_INITDLG:
        /* Center the dialog window and get the screen rectangle.   */
        WinQueryWindowRect(HWND_DESKTOP, &rclScreen);

        /* Get the dialog-window rectangle.                         */
        WinQueryWindowRect(hwnd, &rclDialog);

        /* Get the dialog-window width.                             */
        sWidth = (LONG) (rclDialog.xRight - rclDialog.xLeft);

        /* Get the dialog-window height.                            */
        sHeight = (LONG) (rclDialog.yTop - rclDialog.yBottom);

        /* Set the horizontal coordinate of the lower-left corner.  */
        sBLCx = ((LONG) rclScreen.xRight - sWidth) / 2;

        /* Set vertical coordinate of the lower-left corner.        */
        sBLCy = ((LONG) rclScreen.yTop - sHeight) / 2;

        /* Move, size, and show the window.                         */
        WinSetWindowPos(hwnd,
            HWND_TOP,
            sBLCx, sBLCy,
            0, 0,          /* Ignores size arguments                */
            SWP_MOVE);

        return 0;

The dialog procedure receives notification messages from each control-window item in a dialog window whenever a user clicks an item or enters text in an entry field. Most dialog procedures wait for the user to select one or more dialog-window buttons to signal being finished with the dialog window. When the dialog procedure receives one of these messages, it calls the WinDismissDlg function, as shown in the following code fragment. The second argument to WinDismissDlg is the value returned by the WinDlgBox or WinProcessDlg functions. Generally, these functions return the identifier of the button that was pressed.

    MRESULT EXPENTRY SampDialogProc(HWND hwnd,
                                    ULONG ulMessage,
                                    MPARAM mp1,
                                    MPARAM mp2)
    {
        switch (ulMessage) {
            case WM_COMMAND:
                switch (SHORT1FROMMP(mp1)) {
                    case DID_OK:

                       /*
                        * Final dialog-item queries,
                        * dismiss the dialog.
                        */

                       WinDismissDlg(hwnd, DID_OK);
                       return 0;
                }
                break;
        }
        return (WinDefDlgProc(hwnd, ulMessage, mp1, mp2));
    }

Other dialog-window items send notification messages specific to the type of control window. Your dialog procedure should respond to notification messages from any relevant or important dialog items, and pass the messages that your dialog procedure does not handle to the WinDefDlgProc function for default processing. The default dialog procedure is used similarly to the default frame-window procedure.

The WM_COMMAND message from the OK button indicates that the user has selected the OK button and is finished with the dialog window. If the dialog window has other controls, such as entry fields or check boxes, have your dialog procedure query the contents or state of each control upon receipt of a message from the OK button. Before dismissing a dialog window, have your dialog procedure collect input from each dialog-window control before closing the dialog window.

Manipulating Dialog Items

Dialog items are control windows and, as such, can be manipulated using standard window-management function calls. The window handle is obtained for each dialog item by calling the WinWindowFromID function and passing the window handle for the dialog window and the window identifier for the dialog item as defined in the dialog template. Include the following Resource Compiler source-code fragment in your dialog template:

    DLGTEMPLATE IDD_ABOUT
    BEGIN
        DIALOG "", IDD_ABOUT, 80, 92, 126, 130, FS_DLGBORDER, 0
        BEGIN
            PUSHBUTTON "My Button", ITEMID_MYBUTTON, 37, 107, 56, 12

            /* Other item definitions ... */

        END
    END

Based on this code fragment, your application will receive the button-item handle by initiating the following call to WinWindowFromID:

   hwndItem = WinWindowFromID(hwndDialog, ITEMID_MYBUTTON);

Applications often change the contents, enabled state, or position of dialog items at run time. For example, in a dialog window that contains a list box of file names and an Open button, the Open button should be disabled until the user selects a file from the list. To do this, define the button as disabled in the dialog resource so that it is disabled when the dialog window first is displayed. At run time, the dialog procedure receives a notification message from the list box when the user selects a file. At that time, the dialog procedure should call the WinEnableWindow function to enable the Open button.

Applications also can change the text in static dialog items and buttons by calling the WinSetWindowText function and using the window handle of a particular dialog item.