
DLG provides a great variety of buttons, far beyond standard Windows. While occupying less screen space, they provide much more functionality than what you might expect of buttons.
The following sections will give you some insight into
After each section you will find a bookmark at the right edge of the screen (top). You can jump back to the top by clicking on it.
| Text Label Button (with some action) |
![]()
In the top-left corner of the sample dialog box you see the most frequently used type of button, a text-label button.
Buttons are created in DLG just like any other control, by a procedure CreateCtl:
| CreateCtl (.., psh1, "Button", DYN_BUTTON, .., .., .., .., "Action", ... ); |
| psh1 | identifier of this control (Windows system sends a message with this 'id' when user clicks the button) |
| "Button" | window class of this control |
| DYN_BUTTON | DLG-specific style combination |
| "Action" | text label to appear on the button's face |
| "Hotspots" with multimedia support |
|
|
These two buttons you might not recognize as buttons at first sight. They are not drawn with style 'PUSHLIKE' but seem to be an image painted on a plain surface. They are really buttons, though: You hear it when you click the left "hotspot". An audible signal is generated then (if you have a .wav-file in the MEDIA-subdirectory of your Windows system). The right "hotspot" generates a video clip (provided you have an .avi-file in the MEDIA-subdirectory of your Windows system).
In its source code you see something that is specific to DLG, an "option":
| CreateCtl (.., psh2, "Button", DYN_BUTTON, ..,..,..,.., "*%x", hIcon, "\bAudio=Chimes.wav", ... ); |
| or |
| CreateCtl (.., psh3, "Button", DYN_BUTTON, ..,..,..,.., "*%x", hIcon, "\bVideo=Clip.avi", ... ); |
| psh2 | identifier of this control (you can use this 'id' to receive the Windows-message when the button is clicked) |
| "Button" | window class of this control |
| DYN_BUTTON | DLG-specific style combination (with a graphic face this does not imply PUSHLIKE!) |
| "*%x", hIcon | this combination of a format specifier and an icon handle is printed to a hexadecimal number - by it DLG finds the graphic to paint by this number. |
| \b | DLG-specific separator to introduce options |
| Audio=Chimes.wav | an audible signal is activated by option "Audio=", followed by the name of .wav-file representing this audio |
| Video=Clip.avi | a video clip is activated by option "Audio=", followed by the name of .avi-file representing this video |
| 2-face button (with some action) |
|
|
In DLG you can declare a button to have not only one but two graphic faces: one when the button is "up", the other when it is "pressed". In this example it was done with a green and a red face. The action is activated by the message sent by the Windows system when the button is clicked.
Following is the source code of this example:
| CreateCtl (..., psh3, "Button", DYN_BUTTON, ..., ..., ..., ..., "*%x *%x", hIcon2, hIcon1, ... ); |
| psh3 | identifier of this control (you can use this 'id' to receive the Windows-message when the button is clicked) |
| "Button" | window class of this control |
| DYN_BUTTON | DLG-specific style combination (with a graphic face this does not imply PUSHLIKE!) |
| "*%x %x", hIcon1, hIcon2 | hIcon1 is the handle of the icon to be painted when the button is "up", hIcon2 is the handle of the icon that is painted when it is "pressed". |
| Checkbox / Radio button group |
|
|
For any reason in the early times of standard Windows also checkbox and radio button were subsumed under "buttons". So you can create them in DLG, too - just like push buttons. Only the style is different.
Note the notation for control groups. The individual controls are identified by their text label ("Option 1", "Option 2", etc.), separated by '|'. The whole "subgroup" (incl. the option "Vertical") is enclosed in curly brackets:
| CreateCtl (..., chx1, "Button", DYN_AUTOCHECK, ..., ..., ..., ..., "{Option 1|Option 2|Option 3\bVertical}", ... ); |
| chx1 | identifier of this control group (actually the identifier of the first group member) |
| "Button" | window class of this control |
| DYN_AUTOCHECK | one of the DLG-specific style combinations for a check box. (For radio buttons you could use e.g. DYN_AUTORADIO.) |
| Option 1|...|Option 3 | text labels of the check boxes, separated by '|' |
| \b | DLG-specific separator to introduce options |
| Vertical | option telling that this control group is to be arranged vertically |
| Group of bistable/multistable Buttons |
![]()
![]()
The '|'-notation for control groups is also good to create a group of push buttons in one line of code. Their behavior is determined by the combination of styles. (Don't be confused by the '|'-characters there. They are part of the C/C++ syntax, meaning a Boolean OR).
This example goes to show you also another useful DLG feature, "Notempty". By this option you can make sure that the dialog is checked for any user input. If it is empty, the button group is "blinked" and the dialog refuses to close.
This group has several options. Therefore it has curly brackets:
| CreateCtl ( ..., psh5, "Button", DYN_BUTTON | BS_PUSHLIKE | BS_BISTABLE, ..., ..., ..., ..., "{Bi1|Bi2|Bi3|Bi4|Bi5|Bi6\bGap=2 Images=*%x", hBmp, " Notempty}", ... ); |
| psh5 | identifier of this control group (actually the identifier of the first group member) |
| "Button" | window class of this control |
| DYN_BUTTON | ... | DLG-specific style combination: all
group members are push buttons that have a 'pushlike' frame. (When a
button is "up" the frame is drawn with a white top/left edge and
a black bottom/right edge; when being "pressed", the colors are
swapped.) The buttons behave as being 'bistable' (i.e. each one remains in both of its states, "up" as well as "pressed"). If the style is BS_MULTISTABLE instead, they behave similarly to bistable but each button in the group goes "up" when another group button is "pressed". |
| Bi1|Bi2| ... |Bi6 | text labels of the push buttons,
separated by '|' (In screen layout, these labels are painted over by the
graphic faces. Yet in debugging it is good to have "talking" labels.) |
| \b | DLG-specific separator to introduce options |
| Gap=2 | option telling that the buttons of this group are to be arranged with a 2-pixel gap |
| "Images=*%x", hBmp | option to make a series of bitmaps (identified by its handle hBmp) be painted as the graphic face of each button in the group. |
| Notempty | option to make this button group checked for any user input |
The bitmap series determining the graphic faces looks like this:
![]()
In this example some buttons are disabled. They look like this:
![]()
| Multi-state Button, with callback procedure |

In DLG you can create buttons of any number of states, not just two ("up" and "pressed"). You can use that for giving intuitive pictures of complicated relationships.
This example was also used to show you another feature of DLG, a "callback procedure". By it you can extend the functionality of a control beyond its standard functions. In this example a callback procedure was used to make the button react to a click with the right mouse button.
| CreateCtl ( ..., psh6, "Button", DYN_BUTTON, ..., ..., ..., ..., "MS-button\bImages=*%x", hBmp, "RClickProc=%p", RClickProc, ... ); |
| psh6 | identifier of this control |
| "Button" | window class of this control |
| DYN_BUTTON | DLG-specific button style. (A multi-state button has the same style as a push button.) |
| MS-button | text label of the multi-state
button. (In screen layout, these labels are painted over by the graphic faces. Yet in debugging it is good to have "telling" labels.) |
| \b | DLG-specific separator to introduce options |
| "Images=*%x", hBmp | option to make a series of bitmaps (identified by its handle hBmp) be painted as the graphic face of each button in the group. |
| "RClickProc=%p", RClickProc | DLG-option to give the name of the application-specific callback procedure (handling the right-click) |
The bitmap series determining the graphic faces looks like this:

| Xstep button / Ystep button |
|
|
DLG's multi-state button cyclically assumes the next state each time it is clicked (with state 0 following the highest state, determined by the length of the bitmap series).
An Xstep/Ystep button, however, can jump from one state to the other, ignoring the states in between. The new state of an Xstep button is determined by how far to the right it is clicked. Similarly, an Ystep button assumes the state determined by how far above its bottom line it was clicked.
| CreateCtl ( ..., psh7, "Button", DYN_BUTTON, ..., ..., ..., ..., "Xstep\bImages=*%x", hBmp, " Xstep", ... ); |
| psh7 | identifier of this control |
| "Button" | window class of this control |
| DYN_BUTTON | DLG-specific button style. (An Xstep/Ystep button has the same style as a push button.) |
| MS-button | text label of the Xstep button. (In screen layout, these labels are painted over by the graphic faces. Yet in debugging it is good to have "telling" labels.) |
| \b | DLG-specific separator to introduce options |
| "Images=*%x", hBmp | option to make a series of bitmaps (identified by its handle hBmp) be painted as the graphic face of each button in the group. |
| Xstep | DLG-option to make the button an Xstep button. (For an Ystep button it is Ystep). |
The bitmap series determining the graphic faces looks like this:
| Xstep: | |
| 4 bitmaps of 4 buttons each, with first button "1", then button "2", ... pressed. | |
| Ystep: | ![]() |
4 bitmaps of one vertical bar whose height is incremented in steps. |