Introduction to Dialogs

Dialogs, known officially as dialog boxes, are popup windows which are created from dialog templates. The use of templates simplify the creation of windows containing controls. The predefined window procedure for a dialog also gives you a standard set of keyboard navigation functions. Back to Win95 ASM Page

Modal and modeless dialogs

Dialog boxes can be either modal or modeless.
    A modal dialog disables its owner window and, consequently, its owner's child windows. It also executes its own message loop, commandeering the thread, until the dialog is terminated. Although the dialog owner won't receive mouse- or keyboard-generated messages, it can accept and process messages sent to it by other means.
    A modeless dialog acts like any other popup window.

Creating a dialog box

A modal dialog box is created with either DialogBoxParam or DialogBoxIndirectParam. A modeless dialog box is created with either CreateDialogParam and CreateDialogIndirectParam. (If you've been writing Win32 in C or C++, surprise!--windows.h uses macros to convert the other dialog creation functions into these forms.)
    These functions load a dialog template, the "direct" version loads from the resource section of an EXE or DLL file, the indirect version from memory.

The dialog procedure

Each dialog is created with the dialog window class (it's called #32770). The window procedure of this class calls an application supplied dialog procedure to handle its messages. When a dialog is first being created, the window procedure creates the dialog and all of the controls, and then calls the dialog procedure with the WM_INITDIALOG message. In addition to further dialog initialization, the dialog procedure should respond to this message by returning nonzero (TRUE) if the default of setting the focus to the first control is desired.
    For most messages, the dialog procedure will return nonzero (TRUE) if the given message was processed. If a message requires a return value, SetWindowLong should be used to set the DWL_MSGRESULT field in the dialog's (internal) window structure.
    There are a few exceptions that were created before MS got wise. Instead of a "processed?" status, the following messages expect the dialog procedure to return values:

    WM_CTLCOLORxxxxx
    WM_COMPAREITEM
    WM_VKEYTOITEM
    WM_CHARTOITEM
    WM_QUERYDRAGICON

If the dialog box is modal, EndDialog will terminate the dialog.
If the dialog box is modeless, DestroyWindow will terminate the dialog.

Communicating with the dialog box

The dialog box procedure is where the dialog box communicates with its controls. But how do we get the data to and from the dialog box?
    One solution is to use global memory, that is, letting the dialog box directly access fixed locations (e.g., in the .data segment). Many people dislike this solution. This is bad if you want to have more than one instance of a particular dialog -- like the property pages that you can pop up all over Win95.
    The common dialogs use a different solution -- an information structure. The address of an information structure, which can be allocated anywhere in memory (global, stack, or heap), is passed to the dialog box when it is created. It can include starting values, which the dialog box can use to initialize its controls. The dialog box can fill in fields, in the information structure, by querying its controls or as a response to control notifications. After the dialog box is terminated, the application can use the captured information. The dialog box creation functions have a parameter argument that can be used for this purpose. This argument becomes the lParam of the WM_INITDIALOG message.

Keyboard navigation

A modal dialog will automatically handle keyboard navigation.
    To make a modeless dialog handle keyboard navigation, call IsDialogMessage in the message loop. If it processes a keyboard message, the function returns nonzero (TRUE), and the rest of the message loop should be skipped.

Creating a dialog template with a resource compiler

Dialog editors are the preferred way of creating dialog boxes. They simplify sizing and placement of controls. They may be part of a suite of resource editors. Resource editors, such as dialog editors, may produce text files that can be compiled by a resource compiler. The result of the resource compiler can then be included in an EXE or DLL file as a resource.
    The resource compiler will produce dialog templates for inclusion as resources. The dialog box functions can then access the dialog templates by name or by resource number.

Creating a dialog template in memory without a resource compiler

It's also possible to build a dialog template in memory and use the indirect dialog box functions to create dialogs.
    The dialog template is an "internal" format, and because the Win32 version was first implemented in NT, all strings that it uses must be in Unicode. This is in spite of the fact that there are two entry points (A and W) for the indirect functions.

The following is the extended Win95 dialog template. Check the SDK documentation for the old NT dialog template. (Win95 can handle the old dialog template.)
    The Win95 dialog template is divided into three parts:  the header, an optional font item, and a sequence of dialog items.
    The header contains a fixed-size section followed by three variable-sized fields.

DLGTEMPLATEEX STRUC        ; the header
dlttex_wDlgVer      DW 1        ; overlays old dltt_style
dlttex_Signature    DW 0FFFFh   ; overlays old dltt_style
dlttex_HelpID       DD ?
dlttex_ExStyle      DD ?
dlttex_style        DD ?
dlttex_cDlgItems    DW ?    ; number of dialog items
dlttex_x            DW ?    ; location of top left corner
dlttex_y            DW ?
dlttex_cx           DW ?    ; size
dlttex_cy           DW ?
DLGTEMPLATEEX ENDS
    The three variable-sized fields are the menu, class, and title. The first word of each field has special meaning. If it's not one of the special values, it's the first character of a zero terminated Unicode string.

Menu:     0000h = no menu, 0FFFFh = next word is menu id
Class:     0000h = standard dialog class, 0FFFFh = next word is window class atom
Title:       0000h = no title

The font item exists only if dlttex_style contains DS_SETFONT.
The font item has a fixed-size section followed by the font name in zero terminated Unicode.

FONTINFOEX STRUC
dfont_PointSize    DW ?
dfont_Weight       DW ?   ; FW_ constants
dfont_Italic       DW ?   ; TRUE or FALSE
FONTINFOEX ENDS
The final section is the sequence (list) of dialog items. Each dialog item has a fixed-size section followed by three variable-sized fields.
DLGITEMTEMPLATEEX STRUC
dlitex_HelpID    DD ?
dlitex_ExStyle   DD ?
dlitex_Style     DD ?
dlitex_x         DW ?    ; location of top left corner
dlitex_y         DW ?
dlitex_cx        DW ?    ; size
dlitex_cy        DW ?
dlitex_id        DD ?    ; control ID
DLGITEMTEMPLATEEX ENDS
    The three variable-sized fields are the class, title, and creation data. The first word of each field has special meaning. If it's not one of the special values, it's the first character of a zero terminated Unicode string.

Class:     0000h = standard dialog class, 0FFFFh = next word is window class atom
Title:       0000h = no title
Creation data:  the first word is byte count of actual creation data which follows immediately