SML PROGRAMMING

WIN Dialog Boxes

Message Boxes

Simple messages and "Yes/No" queries may be handled using the WIN MB command. Option 1 is used to display a message:

WIN MB 1 'This is a test'
Figure 1

Note that "OK" is always returned to variable 1. Option 2 is used for "Yes/No" queries:

WIN MB 2 'Do you really want to do this?'
Figure 2

Depending on which button the user clicks, either "YES" or "NO" will be returned to variable 1. Option 3 adds one more button:

WIN MB 3 'Save project changes?'
Figure 3

In this case, either "YES", "NO", or "CANCEL" will be returned to variable 1. Note also that the CLOSE widget and <Esc> key[1] are also enabled, returning "CANCEL" to variable 1.

Options 4-6 are equivalent to options 1-3 save that the contents of a file are used to populate the message box:

&value 10 WKSP
&sv 11 1
&sv 12 2
&cv 13 %11 / %12
&openw %10t$temp.lis
&lv 10 13
&closew
WIN MB 4 %10t$temp.lis
Figure 4

Note that these commands are not designed for displaying large files. In the next article I will show you how to use the list box widget to create a scrollable popup for handling files up to 5000 lines.

Dialog Boxes

Creating and handling a dialog box is very similar to creating and handling a menu. Let's build a simple routine to allow a user to enter a string via a WIN dialog box:

&routine input

&define winrtn 1 &var
&define wksp -1 &var
&define resp -2 &var

&rem **** create dialog definition file

&value [wksp] WKSP
&openw [wksp]t$inp.dlg
&write "BEGIN    0 10.00 10.00  4.50 34.00 v Input"
&write "EBOX   101  0.50  1.00  1.50 32.00 v"
&write "PBUT  -102  2.50  1.00  1.50 8.00 v OK"
&write "PBUT  -103  2.50  9.00  1.50 8.00 v Cancel"
&closew

WIN DB C [wksp]t$inp.dlg
& DEL [wksp]t$inp.dlg

&rem **** read dialog box and process response

WIN DB R

&if &eq [winrtn] 102 &or &eq [winrtn] 50 &do
   &value [resp] 101
&else
   &sv [resp] CANCEL
&end

&rem **** dismiss dialog box

WIN DB D

&return "[resp]"
When the routine is executed as follows:

&r input
&rv -1
Figure 5

and the user enters the indicated string in the edit box, then clicks the OK button or presses the <Enter> key, the value "Harry and Tonto" will be returned to variable -1. If the user presses the <Esc> key, clicks the CANCEL button, or closes the dialog box, the value "CANCEL" will be returned.

The first part of the example routine creates the dialog definition file which is used by the WIN DB C command to build the dialog box. Each line in the file specifies the widget type, ID, position, size, and optional pitch and text.

The WIN DB R command activates the dialog box until a return widget is triggered. Upon return to the application, a return value is passed to variable 1, indicating the return widget that was triggered. In the example, the possible return values are:

-1 = the CLOSE widget
49 = the <Esc> key
50 = the <Enter> key
102 = the OK button
103 = the CANCEL button

Since the edit box is assigned an ID of 101, its contents are assigned to variable 101 after return to the application. Finally, the WIN DB D command dismisses the dialog box.

Warning: Because a value of 0 is assigned to variable 1 when WIN DB D is executed, it is important to handle the return value from WIN DB R first or else assign it to another variable.

Dialog Definition Files

The first line in a dialog definition file is always the BEGIN statement, which defines the position of the dialog box (relative to the origin of the graphic display) and its size. Position and size are given in rows and columns, with the origin at the upper left corner. Note that the width of a column is roughly one half the height of a row.

The remaining lines contain widget definitions. Supported widget types are as follows:

CBOX     Check box
COORD    Coordinate
DROP     Drop-down box
EBOX     Edit box
GBOX     Group box
HSBAR    Horizontal scroll bar
LBOX     List box
PBUT     Push button
RBUT     Radio button
SDROP    Sorted drop-down box
SLBOX    Sorted list box
UBUT     User defined button
VSBAR    Vertical scroll bar
_FRM     Frame
_RECT    Rectangle
_TEXT    Text
Frame and rectangle widgets may be black (BFRM, BRECT), gray (GFRM, GRECT), or white (WFRM, WRECT). These color designations actually refer to Windows desktop color settings: window frame, background, and window, respectively. Text widgets may be centered (CTEXT), left justified (LTEXT), or right justified (RTEXT) within the region specified by the position and size.

The widget ID maps the widget to a global SML variable, 51-999, upon return to the application after a WIN DB R. The contents of the variable will indicate the state of the widget, as follows:

BEGIN: dialog box title text
CBOX, RBUT: 1 = checked, 0 = unchecked
COORD: six digit coordinate value
DROP, LBOX, SDROP, SLBOX: selected string
EBOX, HSBAR, VSBAR: current value
_FRM, _RECT, UBUT: blank or image filename
_TEXT, GBOX, PBUT: current text

A zero ID indicates that a widget is not to be associated with an SML variable. This is typical for widgets that don't change, such as BEGIN, GBOX, text, or frame widgets.

Negative IDs indicate a return widget[2]. Typically, PBUT, UBUT, and COORD widgets are used as return widgets. Other widgets, such as CBOX or RBUT, may also act as return widgets, especially in conjunction with dialog commands (see below) to update dialog boxes.

As stated earlier, return value of WIN DB R will generally be the ID of the return widget that was triggered. The situation is more complex when an edit box is used as a return widget, so much so that I advise avoiding it altogether.

Tip: If you want to update a dialog box based on the contents of an edit box, don't make the edit box a return widget. Instead, create a push button for the user to click after entering the string.

Dialog Commands

Widgets may be initialized or modified by means of dialog commands. These may be appended to the dialog definition file after an END statement (to initialize widgets) or may be bundled into a dialog command file which is read by the WIN DB R {dialog_command_file} command. Note that if a specified command file is not found, WIN DB R will simply ignore the reference.

Here is an ARCEDITW version of the coordinate dialog box example in V5N2:

&routine coo

&define wksp -1 &var
&define temp -2 &var
&define winrtn 1 &var

&rem **** create and initialize dialog box

&value [wksp] WKSP
&openw [wksp]t$coo.dlg
&write "BEGIN     0  5  5 13.0 18 v Coordinate"
&write "GBOX      0  0  1  3.5 14 v"
&write "RBUT   -101  1  2  1.0 12 v CURSOR"
&write "RBUT   -102  2  2  1.0 12 v DIGITIZER"
&write "LTEXT     0  4  1  1.0 10 v Options:"
&write "GBOX      0  5  1  5.0 14 v"
&write "RBUT    103  6  2  1.0 12 v None"
&write "RBUT    104  7  2  1.0 12 v Default"
&write "RBUT    105  8  2  1.0 12 v Coverage"
&write "PBUT   -106 11  1  1.5  8 v OK"
&write "PBUT   -107 11  9  1.5  8 v Cancel"
&write "END"
SHOW COORDINATE [temp]
&if &eq [temp] CURSOR &do
   &write "C 101"
   &write "G 103"
   &write "G 104"
   &write "G 105"
&else
   &write "C 102"
   &write "C 103"
&end
&closew
WIN DB C [wksp]t$coo.dlg
& DEL [wksp]t$coo.dlg

&rem **** process response(s)

&while &do
   WIN DB R [wksp]t$coo.cmd
   &if &fn [wksp]t$coo.cmd &do
      & DEL [wksp]t$coo.cmd
   &end
   &if &eq [winrtn] 101 &do
      &openw [wksp]t$coo.cmd
      &write "C 101"
      &write "U 103"
      &write "U 104"
      &write "U 105"
      &write "G 103"
      &write "G 104"
      &write "G 105"
      &closew
   &elseif &eq [winrtn] 102 &do
      &openw [wksp]t$coo.cmd
      &write "C 102"
      &write "E 103"
      &write "C 103"
      &write "E 104"
      &write "E 105"
      &closew
   &else
      &sv [temp] [winrtn]
      WIN DB D
      &if &eq [temp] 106 &or &eq [temp] 50 &do
         &if &eq %101 1 &do
            COO CURS
         &elseif &eq %103 1 &do
            COO DIG
         &elseif &eq %104 1 &do
            COO DIG DEF
         &else
            &r retrieve EXIST C NONE
            &rv [temp]
            &if &ne [temp] CANCEL &do
               COO DIG [temp]
            &end
         &end
      &end
      &return
   &end
&end
&return
The first part of the routine creates and initializes the dialog box. Note the use of GBOX widgets to group radio buttons. The initial dialog commands depend on the current COORDINATE setting; the commands used are as follows:

C = check widget
U = uncheck widget
G = gray (disable) widget
E = enable widget

If the current COORDINATE setting is CURSOR, the dialog box will appear as follows:

Figure 6

When the user clicks the DIGITIZER radio button, the DIGITIZER options will be enabled:

Figure 7

Other supported dialog commands are as follows:

B = set allowable text format for an edit box
F = send focus to a widget
L = populate a list box or drop-down box
R = set scroll bar range and intervals
S = set the value of a widget

These commands will be discussed as appropriate for each widget in the next article(s).

EDITDLG

EDITDLG[3] is a convenient SML application included with PC ARC/INFO for creating and modifying dialog box definition files.

One dialog box lists the contents of the working definition file and allows you to add, delete, or replace widget entries:

Figure 8

The other allows you to build or modify a widget entry:

Figure 9

Let's use EDITDLG to modify itself! EDITDLG.R may be found in the %ARC%\UTOOL directory (keep a backup copy!!). Copy the text in routine INIT which defines the Widget Editor dialog box to a new file called EDITW.DLG and remove the &write statements and quotes:

BEGIN   0  0.00 40 16.0 33 v Widget Editor
LTEXT   0  0.50  1  1.0  6 v Widget
DROP -975  0.50  8 14.0 25 f
GBOX    0  2.00  0  3.5 33 v Control ID
DROP  976  3.50  1  5.0 10
HSBAR 977  4.00 12  1.0 20
RTEXT 978  3.00 29  1.0  3 f
GBOX    0  5.50  0  4.0 33 v Position
LTEXT   0  7.00  1  1.0  4 f Row
HSBAR 979  7.00 12  1.0 20
LTEXT 980  7.00  6  1.0  6 f
LTEXT   0  8.00  1  1.0  4 f Col
HSBAR 981  8.00 12  1.0 20
LTEXT 982  8.00  6  1.0  6 f
GBOX    0  9.50  0  4.0 33 v Size
LTEXT   0 11.00  1  1.0  4 f Row
HSBAR 983 11.00 12  1.0 20
LTEXT 984 11.00  6  1.0  6 f
LTEXT   0 12.00  1  1.0  4 f Col
HSBAR 985 12.00 12  1.0 20
LTEXT 986 12.00  6  1.0  6 f
LTEXT   0 14.25  1  1.0  4 f Text
EBOX  987 14.00  6  1.5 20 v
DROP  988 14.00 27  4.0  5 v
Before running EDITDLG, you will need to renumber the widgets. This may be accomplished using the RENUMWID utility:

RENUMWID [in_dlg] [out_dlg] [start_num]
RENUMWID not only renumbers widgets but also formats the text nicely so that columns line up.

Tip: If you want the output of RENUMWID to be the same file as the input, you can create a batch file RENUM.BAT:

@echo off
if "%1" == "" goto usage
if "%2" == "" goto usage
REN %1 t$temp.dlg
RENUMWID t$temp.dlg %1 %2
DEL t$temp.dlg
goto end
:usage
echo Usage:  RENUM [dlg_file] [start_id]
:end
After renumbering EDITW.DLG to start at 101, run EDITDLG and open the dialog file:

Before...
Figure 10

Double-click RTEXT widget 104 in the widget list to load it into the widget editor. Change the type to EBOX, the position to row 2.75 column 26, and the size to 6 columns. Then click the REPLACE button to update the entry.

Similarly, change LTEXT widgets 106, 108, 110, and 112 to EBOX widgets, adjusting the size to 5.5 columns.

After!
Figure 11

Save the changes, exit EDITDLG, renumber the widgets again to start at 975, copy the text from EDITW.DLG back into EDITDLG.R, and add the appropriate &write statements and quotes. Then compile and link:

COMPSML EDITDLG R EDITDLG
LINKSML
CML file:EDITDLG
Main routine:EDITDLG
Report file:
LML file:EDITDLG
LML file:
Presto! Now when you run EDITDLG, you'll be able to enter values directly as well as use the slider bars.

Some additional modifications you can make to EDITDLG are as follows:

If you have a 1024x768 monitor, you can modify the BEGIN statements of the dialog boxes so they don't overlap:

&write "BEGIN  0  1.0   2.0 15.00 40 v Widget List"
...
&write "BEGIN   0  1.00 44 16.0 33 v Widget Editor"
...
&write "BEGIN 0 1 80 10 20 v New"
Finally, if you are in the habit of running EDITDLG from the ARCW prompt, it is convenient to set the WIN PATH to the current directory. The following lines may be added to the beginning of routine EDITDLG:

&value -1 WKSP
& CD >%-1t$curdir
&open %-1t$curdir done
&read -2 done
&label done
&close
& DEL %-1t$curdir
WIN PATH %-2

Next: Fun with Widgets


[1]Version 3.5 introduces the <Esc> key as a widget and alters the handling of the <Enter> key; 3.4.2 users should be aware of these differences when trying out the examples in this and future articles.

[2]Push buttons (PBUT) and user defined buttons (UBUT) are always return widgets, and do not require a negative ID.

[3]Its predecessor, EDITD, is available in version 3.4.2.


Return to ArcTips page