# `DATETOSECS` — `dXINPUT`

## Contents

- `DATETOSECS` — Gets the number of seconds since 1/1/1970
- `DATIM$` — Current date and time
- `DAY` — Current day of the month
- `DAYNAME$` — Converts a number to a day name
- `DAYS` — Gets the number of days since 1/1/1900
- `DAYSTODATE` — Converts the number of days since 1/1/1900 to a date
- `dBUTTONS` — Defines exit keys
- `dCHECKBOX` — Defines a checkbox
- `dCHOICE` — Defines a choice list
- `dDATE` — Defines a date edit box
- `DECLARE EXTERNAL` — Forces error reporting if procedures are used before they are declared
- `DECLARE OPX` — Declares an OPX name
- `dEDIT` — Defines a string edit box
- `dEDITMULTI` — Defines a multi-line edit box
- `DEFAULTWIN` — Change the default window’s colour mode
- `DEG` — Converts from radians to degrees
- `DELETE` — Deletes files
- `DELETE` — Deletes a table from a database
- `dFILE` — Defines a filename edit box or selector
- `dFLOAT` — Defines an edit box for a floating-point number
- `DIALOG` — Presents a dialog
- `dINIT` — Initialises a dialog
- `DIR$` — Lists files that match a specification
- `dLONG` — Defines an edit box for a long integer
- `DO`...`UNTIL` — Conditional loop
- `DOW` — Gets the day of the week from a date
- `dPOSITION` — Positions a dialog
- `dTEXT` — Defines text to be displayed in a dialog
- `dTIME` — Define an exit box for a time
- `dXINPUT` — Define an exit box for a secret string

## `DATETOSECS` — Gets the number of seconds since 1/1/1970

Usage: `s&=DATETOSECS(yr%,mo%,dy%,hr%,mn%,sc%)`

Returns the number of seconds since 00:00 on 1/1/1970 at the date/time specified.

Raises an error for dates before 1/1/1970.

The value returned is an unsigned long integer. (Values up to +2147483647, which is 03:14:07 on 19/1/2038, are returned as expected. Those from +2147483648 upwards are returned as negative numbers, starting from -2147483648 and increasing towards zero.)

See also `SECSTODATE`, `HOUR`, `MINUTE`, `SECOND`.

## `DATIM$` — Current date and time

Usage: `d$=DATIM$`

Returns the current date and time from the system clock as a string — for example: `"Fri 16 Oct 1992 16:25:30"`. The string returned always has this format — 3 mixed-case characters for the day, then a space, then 2 digits for the day of the month, and so on.

The string returned by `DATIM$` can be parsed with `MID$` using the following values for offsets within the string:

`KDatimOffDayName%` | 1 | Offset of the day name (Fri).
`KDatimOffDay%` | 5 | Offset of the day of the month (16).
`KDatimOffMonth%` | 8 | Offset of the month name (Oct).
`KDatimOffYear%` | 12 | Offset of the year number (1992).
`KDatimOffHour%` | 17 | Offset of the hour (16).
`KDatimOffMinute%` | 20 | Offset of the minute (25).
`KDatimOffSecond%` | 23 | Offset of the second (30).

These constants are supplied in Const.oph.

`Date.opx` provides a large set of procedures for manipulating dates and for accurate timing. See `Date.opx` — Date and time manipulation for more details.

## `DAY` — Current day of the month

Usage: `d%=DAY`

Returns the current day of the month (1 to 31) from the system clock.

## `DAYNAME$` — Converts a number to a day name

Usage: `d$=DAYNAME$(x%)`

Converts `x%`, a number from 1 to 7, to the day of the week, expressed as a three letter string. E.g. `d$=DAYNAME$(1)` returns `MON`.

Example:

        PROC Birthday:
              LOCAL d&,m&,y&,dWk%
              DO
                    dINIT
                    dTEXT "","Date of birth",2
                    dTEXT "","eg 23 12 1963",$202
                    dLONG d&,"Day",1,31
                    dLONG m&,"Month",1,12
                    dLONG y&,"Year",1900,2155
                    IF DIALOG=0 :BREAK :ENDIF
                    dWk%=DOW(d&,m&,y&)
                    CLS :PRINT DAYNAME$(dWk%),
                    PRINT d&,m&,y&
                    dINIT dTEXT "","Again?",$202
                    dBUTTONS "No",%N,"Yes",%Y
              UNTIL DIALOG<>%y
        ENDP

See also `DOW`.

## `DAYS` — Gets the number of days since 1/1/1900

Usage: `d&=DAYS(day%,month%,year%)`

Returns the number of days since 1/1/1900.

Use this to find out the number of days between two dates.

Example:

        PROC deadline:
              LOCAL a%,b%,c%,deadlin&
              LOCAL today&,togo%
              PRINT "What day? (1-31)"
              INPUT a%
              PRINT "What month? (1-12)"
              INPUT b%
              PRINT "What year? (19??)"
              INPUT c%
              deadlin&=DAYS(a%,b%,1900+c%)
              today&=DAYS(DAY,MONTH,YEAR)
              togo%=deadlin&-today&
              PRINT togo%,"days to go"
              GET
        ENDP

See also `dDATE`, `SECSTODATE`.

`Date.opx` provides a large set of procedures for manipulating dates and for accurate timing. See `Date.opx` — Date and time manipulation for more details.

## `DAYSTODATE` — Converts the number of days since 1/1/1900 to a date

Usage: `DAYSTODATE days&,year%,month%,day%`

This converts `days&`, the number of days since 1/1/1900, to the corresponding date, returning the day of the month to `day%`, the month to `month%` and the year to `year%`. This is useful for converting the value set by `dDATE`, which also gives days since 1/1/1900.

## `dBUTTONS` — Defines exit keys

Usage: `dBUTTONS p1$,k1%, p2$,k2%, p3$,k3%`,...

Defines exit keys to go at the bottom or side of a dialog.

One or more exit keys can be defined with a `p$,k%` pair. Each pair specifies an exit key; `p$` is the text to be displayed on it, while `k%` is the keycode of the shortcut key. `DIALOG` returns the keycode of the key pressed (in lower case for letters).

For alphabetic keys, use the `%` sign - `%A` means ‘the code of `A`’, and so on. The shortcut key is then Ctrl+alphabetic_key. Character codes lists the codes for keys (such as Tab) which are not part of the character set. If you use the code for one of these keys, its name (e.g. `Tab`, or `Enter`) will be shown in the key.

The following option flags can be applied to a button by adding the appropriate constant to the shortcut’s keycode:

`KDButtonNoLabel%` | `$100` | Button is displayed with no shortcut key label.
`KDButtonPlainKey%` | `$200` | The key by itself — without the Ctrl modification — is used for the shortcut key.

There are also constants for some key values:

`KDButtonDel%` | 8 | Del
`KDButtonTab%` | 9 | Tab
`KDButtonEnter%` | 13 | Enter
`KDButtonEsc%` | 27 | Esc
`KDButtonSpace%` | 32 | Space

These constants are supplied in Const.oph.

If a `k%` argument is negative, then the key is a ‘Cancel’ key. The corresponding positive value is used for the key to display and the value for `DIALOG` to return, but if you do press this key to exit, the `var` variables used in the commands like dEDIT, dTIME etc. will not be set. You must negate the shortcut together with any added flags.

The Esc key will always cancel a dialog box, with `DIALOG` returning 0. If you want to show the Esc key as one of the exit keys, use `-KDButtonEsc%` as the `k%` argument so that the `var` variables will not be set if Esc is pressed.

There can be only one `dBUTTONS` item per dialog.

The buttons take up two lines on the screen. `dBUTTONS` may be used anywhere between `dINIT` and `DIALOG`; the position of its use does not affect the position of the buttons in the dialog.

This example presents a simple query, returning ‘False’ for `No`, or ‘True’ for `Yes`, providing shortcut keys of N and Y respectively and without labels beneath the keys.

        PROC query:
              dINIT
              dTEXT "","FORGET CHANGES",2
              dTEXT "","Sure?",$202
              dBUTTONS "No",-(%N OR $300),"Yes",%Y OR $300
              RETURN DIALOG=%y
        ENDP

See also `dINIT`.

## `dCHECKBOX` — Defines a checkbox

Usage: `dCHECKBOX chk%,prompt$`

Creates a dialog checkbox entry. This is similar to a choice list with two items, except that the list is replaced by a checkbox with the tick either on or off. The state of the checkbox is maintained across calls to the dialog.

Initially you should set the live variable `chk%` to 0 to set the tick symbol off and to any other value to set it on. `chk%` is then automatically set to 0 if the box is unchecked or -1 if it is checked when the dialog is closed.

See also `dINIT`.

## `dCHOICE` — Defines a choice list

Usage:

        dCHOICE var choice%,p$,list$

or:

        dCHOICE var choice%,p$,list1$+",..."
        dCHOICE var choice%,"",list2$+",..."
        ...
        dCHOICE var choice%,"",listN$

Defines a choice list to go in a dialog.

`p$` will be displayed on the left side of the line. `list$` should contain the possible choices, separated by commas - for example, `"No,Yes"`. One of these will be displayed on the right side of the line, and the left and right arrows can be used to move between the choices.

`choice%` must be a `LOCAL` or a `GLOBAL` variable. It specifies which choice should initially be shown — 1 for the first choice, 2 for the second, and so on. When you finish using the dialog, `choice%` is given a value indicating which choice was selected — again, 1 for the first choice, and so on.

`dCHOICE` supports an unrestricted number of items (up to memory limits). To extend a `dCHOICE` list, add a comma after the last item on the line followed by "`...`" (three full-stops), as shown in the usage above. `choice%` must be the same on all the lines, otherwise an error is raised. For example, the following specifies items i1, i2, i3, i4, i5, i6:

        dCHOICE ch%,prompt$,"i1,i2,..."
        dCHOICE ch%,"","i3,14,..."
        dCHOICE ch%,"","i5,i6"

See also `dINIT`.

## `dDATE` — Defines a date edit box

Usage: `dDATE var lg&,p$,min&,max&`

Defines an edit box for a date, to go in a dialog.

`p$` will be displayed on the left side of the line.

`lg&`, which must be a `LOCAL` or a `GLOBAL` variable, specifies the date to be shown initially. Although it will appear on the screen like a normal date, for example `15/03/92`, `lg&` must be specified as "days since 1/1/1900".

`min&` and `max&` give the minimum and maximum values which are to be allowed. Again, these are in days since 1/1/1900. An error is raised if `min&` is higher than `max&`.

When you finish using the dialog, the date you entered is returned in `lg&`, in days since 1/1/1900.

The system setting determines whether years, months or days are displayed first.

See also `DAYS`, `SECSTODATE`, `DAYSTODATE`, `dINIT`.

## `DECLARE EXTERNAL` — Forces error reporting if procedures are used before they are declared

Usage: `DECLARE EXTERNAL`

Causes the translator to report an error if any variables or procedures are used before they are declared. It should be used at the beginning of the module to which it applies, before the first procedure. It is useful for detecting ‘Undefined externals’ errors at translate-time rather than at runtime.

For example, with `DECLARE EXTERNAL` commented out, the following translates and raises the error `Undefined externals, i` at runtime. Adding the declaration causes the error to be detected at translate-time instead.

        REM DECLARE EXTERNAL
        PROC main:
              LOCAL i%
              i%=10
              PRINT i
              GET
        ENDP

If you use this declaration, you will need to declare all subsequent variables and procedures used in the module, using `EXTERNAL`.

See also `EXTERNAL`.

## `DECLARE OPX` — Declares an OPX name

Usage:

        DECLARE OPX opxname,opxUid&,opxVersion&
        ...
        END DECLARE

Declares an OPX. `opxname` is the name of the OPX, `opxUid&` its UID and `opxVersion&` its version number.

Declarations of the OPX’s procedures should be made inside this structure.

See About OPXs for more details.

## `dEDIT` — Defines a string edit box

Usage:

        dEDIT var str$,p$,len%

or:

        dEDIT var str$,p$

Defines a string edit box, to go in a dialog.

`p$` will be displayed on the left side of the line.

`str$` is the string variable to edit. Its initial contents will appear in the dialog. The length used when `str$` was defined is the maximum length you can type in.

`len%`, if supplied, gives the width of the edit box (allowing for widest possible character in the font). The string will scroll inside the edit box, if necessary. If `len%` is not supplied, the edit box is made wide enough for the maximum width `str$` could possibly be.

See also `dTEXT`.

## `dEDITMULTI` — Defines a multi-line edit box

Usage: `dEDITMULTI var pData&,p$,widthInChars%,numLines%,maxLen%`

Defines a multi-line edit box to go into a dialog. Normally the resulting text would be used in a subsequent dialog, saved to file or printed using the Printer OPX (see `Printer.opx` — Printer and text handling). It is also possible to paste text into the buffer from other applications and vice versa, although any formatting or embedded objects contained in text pasted in will be removed.

`pData&` is the address of a buffer to take the edited data. It could be the address of an array as returned by `ADDR`, or of a heap cell, as returned by `ALLOC` (see `ADDR` and `ALLOC`). The buffer may not be specified directly as a string and may not be read as such. Instead it should be peeked, byte by byte (see `PEEK`). The leading 4 bytes at `ptrData&` contain the initial number of bytes of data following. These bytes are also set by `dEDITMULTI` to the actual number of bytes edited. For this reason it is convenient to use a long integer array as the buffer, with at least 1+(`maxLen%`+3)/4 elements. The first element of the array then specifies the initial length.

If an allocated cell is used (probably because more than 64K is required), the first 4 bytes of the cell must be set to the initial length of the data. If this length is not set then an error will be raised. For example if a cell of 100000 bytes is allocated, you would need to poke a zero long integer in the start to specify that there is initially no text in the cell. For example:

        p&=ALLOC(100000)
        POKEL p&,0            REM Text starts at p&+4

Special characters such as line breaks and tab characters may appear in the buffer:

`KParagraphDelimiter%` | $06 | Paragraph delimiter.
`KLineBreak%` | $07 | Line break.
`KPageBreak%` | $08 | Page break.
`KTabCharacter%` | $09 | Horizontal tab.
`KNonBreakingTab%` | $0a | Non-breaking horizontal tab.
`KNonBreakingHyphen%` | $0b | Non-breaking hyphen.
`KPotentialHyphen%` | $0c | Words will break here with a hyphen at the end of the line, if necessary.
`KNonBreakingSpace%` | $10 | Non-breaking space.
`KPictureCharacter%` | $0e | A picture.
`KVisibleSpaceCharacter%` | $0f | Visible space.

These constants are supplied in Const.oph.

The prompt, `p$` will be displayed on the left side of the edit box. `widthInChars%` specifies the width of the edit box within which the text is wrapped, using a notional average character width. The actual number of characters that will fit depends on the character widths, with e.g. more ‘i’s fitting than ‘w’s. `numLines%` specifies the number of full lines displayed. Any more lines will be scrolled. `maxLen%` specifies the length in bytes of the buffer provided (excluding the bytes used to store the length).

The Enter key is used by a multi-line edit box which has the focus before being offered to any buttons. This means that Enter can’t be used to exit the dialog, unless another item is provided that can take the focus without using the Enter key. Normal practice is to provide a button that does not use the Enter key to exit a dialog whenever it contains a multi-line edit box. The Esc key will always cancel a dialog however, even when it contains a multi-line edit box.

The following example presents a three-line edit box which is about 10 characters wide and allows up to 399 characters:

        CONST KLenBuffer%=399
        PROC dEditM:
              LOCAL buffer&(101)
              REM 101=1+(399+3)/4 in integer arithmetic
              LOCAL pLen&,pText&
              LOCAL i%
              LOCAL c%
              pLen&=ADDR(buffer&(1))
              pText&=ADDR(buffer&(2))
              WHILE 1
                    dINIT "Try dEditMulti"
                    dEDITMULTI pLen&,"Prompt",10,3,KLenBuffer%
                    dBUTTONS "Done",%d      REM button needed to exit dialog
                    IF DIALOG=0 :BREAK :ENDIF
                    PRINT "Length:";buffer&(1)
                    PRINT "Text:"
                    i%=0
                    WHILE i%<buffer&(1)
                          c%=PEEKB(pText&+i%)
                          IF c%>=32
                                PRINT CHR$(c%);
                          ELSE
                                REM just print a dot for special characters
                                PRINT ".";
                          ENDIF
                          i%=i%+1
                    ENDWH
              ENDWH
        ENDP

See also `dINIT`.

## `DEFAULTWIN` — Change the default window’s colour mode

Usage: `DEFAULTWIN mode%`

Changes the default window’s colour mode. The default window has ID=1, and uses a mode specific to the hardware capabilities of the EPOC device it is running on. For example, a 4-grey window (2-bit, `KColorDefWinWin4GrayMode%`) is created on grey-scale machines, and a 256-color (8-bit, `KColorDefWin256ColorMode%`) window is created on colour screen machines.

The default can be overriden using `DEFAULTWIN`. `mode%` specifies the new colour mode.

`KColorDefWin2GrayMode%` | 0 | Two-grey mode.
`KColorDefWin4GrayMode%` | 1 | Four-grey mode.
`KColorDefWin16GrayMode%` | 2 | 16 grey mode.
`KColorDefWin256GrayMode%` | 3 | 256 grey mode.
`KColorDefWin16ColorMode%` | 4 | 16 colour mode.
`KColorDefWin256ColorMode%` | 5 | 256 colour mode.

N.B. the existing constants, `KDefWin4ColourMode%` and `KDefWin16ColourMode%` are retained for backwards compatibility (see below).

These constants are supplied in Const.oph.

Using high-colour mode uses more power than using modes with fewer colours. See the Graphics for more information.

You are advised to call `DEFAULTWIN` once near the start of your program an nowhere else if you need to change the colour mode of the default window. If it fails with an ‘Out of memory’ error, the program can then exit cleanly without losing vital information.

#### Compatibility

EPOC Release 3 supports only `KColorDefWin4ColourMode%` (=`1`) and `KDefWin16ColourMode%` (=`2`), actually displaying both in shades of grey. These correspond to the values of the new `KColorDefWin4GrayMode%` and `KColorDefWin16GrayMode%`, so code translated under ER5 which uses the new constants for 16-grey and 4-grey modes will run on older releases (although the source will not compile on them). This is because it is the value of a constant which is translated into an `opo` or an app, not the constant’s name.

Code translated under ER5 which uses anything other than 2-, 4- or 16-grey modes will fail when you try to run it on ER3.

See also `gGREY`, `gCOLOR`, `gCREATE`.

## `DEG` — Converts from radians to degrees

Usage: `d=DEG(x)`

Converts from radians to degrees.

Returns `x`, an angle in radians, as a number of degrees. The formula used is: `180*x/PI`

All the trigonometric functions (SIN,COS etc.) work in radians, not degrees. You can use DEG to convert an angle returned by a trigonometric function back to degrees:

Example:

        PROC xarctan:
              LOCAL arg,angle
              PRINT "Enter argument:";
              INPUT arg
              PRINT "ARCTAN of",arg,"is"
              angle=ATAN(arg)
              PRINT angle,"radians"
              PRINT DEG(angle),"degrees"
              GET
        ENDP

To convert from degrees to radians, use `RAD`.

## `DELETE` — Deletes files

Usage: `DELETE filename$`

Deletes any type of file.

You can use wildcards for example, to delete all the files in `D:\OPL`

        DELETE "D:\OPL\*"

See also `RMDIR`.

## `DELETE` — Deletes a table from a database

Usage: `DELETE dbase$,table$`

This deletes the table `table$` from the database `dbase$`. To do this all views of the database, and hence the database itself, must be closed.

## `dFILE` — Defines a filename edit box or selector

Section Contents

- Flags
- Restriction by UID

Usage:

        dFILE var file$,p$,f%

or:

        dFILE var file$,p$,f%, uid1&,uid2&,uid3&

Defines a filename edit box or selector, to go in a dialog. A ‘Folder’ and ‘Disk’ selector are automatically added on the following lines.

By default no prompts are displayed for the file, folder and disk selectors. A comma-separated prompt list should be supplied. For example, for a filename editor with the standard prompts use:

        dFILE f$,"File,Folder,Disk",1

#### Flags

`f%` controls the type of file editor or selector, and the kind of input allowed. You can add together any of the following values (from `Const.oph`):

| 0 | use a selector
`KDFileEditBox%` | 1 | use an edit box
`KDFileAllowFolders%` | 2 | allow directory names
`KDFileFoldersOnly%` | 4 | directory names only
`KDFileEditorDisallowExisting%` | 8 | disallow existing files
`KDFileQueryExisting%` | 16 | query existing files
`KDFileAllowNullStrings%` | 32 | allows null string input
`KDFileAllowWildCards%` | 128 | obey/allow wildcards
`KDFileSelectorWithRom%` | 256 | allow ROM files to be selected
`KDFileSelectorWithSystem%` | 512 | allow files in the System folder to be selected

The first of the list is the most crucial. If you add 1 into `f%`, you will see a file edit box, as when creating a new file. If you do not add 1, you will see the ‘matching file’ selector, used when choosing an existing file.

If performing a ‘copy to’ operation, you might use 1+2+16, to specify a file edit box, in which you can type the name of a directory to copy to, and which will produce a query if you type the name of an existing file.

If asking for the name of a directory to remove, you might use 4, to allow an existing directory name only.

‘Query existing’ is ignored if ‘disallow existing’ is set. These two, as well as ‘allow null string input’, only work with file edit boxes, not ‘matching file’ selectors.

#### Restriction by UID

For file selectors, `dFILE` supports file restriction by UID, or by type from the user’s point of view. Documents are identified by three UIDs which identify which application created the document and what kind of file it is. Specifying all three UIDs will restrict the files as much as is possible, and specifying fewer will provide less restriction. You can supply 0 for `uid1&` and u`id2&` if you only want to restrict the list to `uid3&`. This may be useful when dealing with documents from one of your own applications: you can easily find out the third UID as it will be the UID you specified in the APP statement. Note that UIDs are ignored for editors. For example, if your application has UID `KUidMyApp&`, then the following will list only your application-specific documents:

        dFILE f$,p$,f%,0,KUidOplDoc&,KUidMyApp&
        REM KUidOplDoc& for OPL docs

Some OPL-related UID values are given in `Const.oph`.

`KUidOplInterpreter&` | 268435575 | The OPL interpreter.
`KUidOplApp&` | 268435572 | An OPL app.
`KUidOplDoc&` | 268435573 | An OPL document.
`KUidOPO&` | 268435571 | An OPO.
`KUidOplFile&` | 268435594 | An OPL file.
`KUidOpxDll&` | 268435549 | An OPX.

You can always press Tab to produce the full file selector with a `dFILE` item.

`file$` must be declared to be `KDFileNameLen%` bytes long, since file names may be up to this length. If it is shorter an error will be raised.

`KDFileNameLen%` | 255 | Maximum file name length for `dFILE`.

See also `dINIT`.

## `dFLOAT` — Defines an edit box for a floating-point number

Usage: `dFLOAT var fp,p$,min,max`

Defines an edit box for a floating-point number, to go in a dialog.

`p$` will be displayed on the left side of the line.

`min` and `max` give the minimum and maximum values which are to be allowed. An error is raised if `min` is higher than `max`.

`fp` must be a `LOCAL` or a `GLOBAL` variable. It specifies the value to be shown initially. When you finish using the dialog, the value you entered is returned in `fp`.

See also `dINIT`.

## `DIALOG` — Presents a dialog

Usage: `n%=DIALOG`

Presents the dialog prepared by `dINIT` and commands such as `dTEXT` and `dCHOICE`. If you complete the dialog by pressing Enter, your settings are stored in the variables specified in `dLONG`, `dCHOICE` etc., although you can prevent this with `dBUTTONS`.

If you used `dBUTTONS` when preparing the dialog, the keycode which ended the dialog is returned. Otherwise, `DIALOG` returns the line number of the item which was current when Enter was pressed. The top item (or the title line, if present), has line number 1.

If you cancel the dialog by pressing Esc, the variables are not changed, and `KDlgCancel%` is returned:

`KDlgCancel%` | 0 | Return value: dialog was cancelled.

See also `dINIT`.

## `dINIT` — Initialises a dialog

Usage: any of

        dINIT
        dINIT title$
        dINIT title$,flags%

Prepares for definition of a dialog, cancelling any existing one. Use `dTEXT`, `dCHOICE` etc. to define each item in the dialog, then `DIALOG` to display the dialog.

If `title$` is supplied, it will be displayed at the top of the dialog. Any supplied `title$` will be positioned in a grey box at the top of the dialog. `flags%` can be any added combination of the following constants:

`KDlgButRight%` | Buttons on the right rather than at the bottom
`KDlgNoTitle%` | No title bar
`KDlgFillScreen%` | Use the full screen
`KDlgNoDrag%` | Don’t allow the dialog box to be dragged
`KDlgDensePack%` | Pack the dialog contents (not buttons) densely.

These constants are supplied in Const.oph.

It should be noted that dialogs without titles cannot be dragged regardless of the ‘No drag’ setting. Dense packing enables more lines to fit on the screen for larger dialogs.

If an error occurs when adding an item to a dialog, the dialog is deleted and `dINIT` needs calling again. This is necessary to avoid having partially specified dialog lines. The following code will raise a ‘Structure fault’ error:

        REM  ** Faulty OPL fragment **
              dINIT
              ONERR e1
              REM bad arg list gives argument error:
              dCHOICE ch%, "ChList", "a,b,,,,c"
        e1::
              ONERR OFF
              dLONG l&,"Long",0,12345
              DIALOG

## `DIR$` — Lists files that match a specification

Usage: `d$=DIR$(filespec$)
`then `d$=DIR$("")`

Lists filenames, including subdirectory names, matching a file specification. You can include wildcards in the file specification. If `filespec$` is just a directory name, include the final backslash on the end for example, `"\TEMP\"` . Use the function like this:

- `DIR$(filespec$)` returns the name of the first file matching the file specification.
- `DIR$("")` then returns the name of the second file in the directory.
- `DIR$("")` again returns the third, and so on.
- When there are no more matching files in the directory, `DIR$("")` returns a null string.

Example, listing all the files whose names begin with `A` in `C:\ME\`

        PROC dir:
              LOCAL d$(255)
              d$=DIR$("C:\ME\A*")
              WHILE d$<>""
                    PRINT d$
                    d$=DIR$("")
              ENDWH
              GET
        ENDP

## `dLONG` — Defines an edit box for a long integer

Usage: `dLONG var lg&,p$,min&,max&`

Defines an edit box for a long integer, to go in a dialog.

`p$` will be displayed on the left side of the line.

`min&` and `max&` give the minimum and maximum values which are to be allowed. An error is raised if `min&` is higher than `max&`.

`lg&` must be a `LOCAL` or a `GLOBAL` variable. It specifies the value to be shown initially. When you finish using the dialog, the value you entered is returned in `lg&`.

See also `dINIT`.

## `DO`...`UNTIL` — Conditional loop

Usage:

        DO
              statements...
              ...
        UNTIL condition

`DO` forces the set of statements which follow it to execute repeatedly until the `condition` specified by `UNTIL` is met.

This is the easiest way to repeat an operation a certain number of times.

- Every `DO` must have its matching `UNTIL` to end the loop.
- If you set a `condition` which is never met, the program will go round and round, locked in the loop forever.

You can escape by pressing Ctrl+Esc, provided you haven’t set `ESCAPE OFF`. If you have set `ESCAPE OFF`, you will have to return to go to the Task list, select your program in the list and tap ‘`Close file`’.

See also Control structures and `WHILE...ENDWH`.

## `DOW` — Gets the day of the week from a date

Usage: `d%=DOW(day%,month%,year%)`

Returns the day of the week from 1 (Monday) to 7 (Sunday) given the date.

`day%` must be between 1 and 31, `month%` from 1 to 12 and `year%` from 1900 to 2155.

For example, `D%=DOW(4,7,1992)` returns `KSaturday`. Values for `DOW` are supplied in `Const.oph`:

`KMonday%` | `1`
`KTuesday%` | `2`
`KWednesday%` | `3`
`KThursday%` | `4`
`KFriday%` | `5`
`KSaturday%` | `6`
`KSunday%` | `7`

These constants are supplied in Const.oph.

## `dPOSITION` — Positions a dialog

Usage: `dPOSITION x%,y%`

Positions a dialog. Use `dPOSITION` at any time between `dINIT` and `DIALOG`.

`dPOSITION` uses two integer values. The first specifies the horizontal position, and the second, the vertical. `dPOSITION -1,-1` positions to the top left of the screen; `dPOSITION 1,1` to the bottom right; `dPOSITION 0,0` to the centre, the usual position for dialogs.

`dPOSITION 1,0`, for example, positions to the right-hand edge of the screen, and centres the dialog half way up the screen.

Constants for these values are supplied in Const.oph.

See also `dINIT`.

## `dTEXT` — Defines text to be displayed in a dialog

Usage: `dTEXT p$,body$,t%
`or `dTEXT p$,body$`

Defines a line of text to be displayed in a dialog.

`p$` will be displayed on the left side of the line, and `body$` on the right side. If you only want to display a single string, use a null string (`""`) for `p$`, and pass the desired string in `body$`. It will then have the whole width of the dialog to itself. An error is raised if `body$` is a null string and the text line is not a separator (see below).

`body$` is normally displayed left aligned (although usually in the right column). You can override this by specifying `t%`:

`KDTextLeft%` | 0 | Left-align `body$`.
`KDTextRight%` | 1 | Right-align `body$`.
`KDTextCentre%` | 2 | Centre `body$`.

Alignment of `body$` is only supported when `p$` is null, with the body being left aligned otherwise. In addition, you can add any or all of the following three values to `t%`, for these effects:

`KDTextLineBelow%` | $200 | Draw a line below this item.
`KDTextAllowSelection%` | $400 | Allow this item’s prompt (not its body text) to be selected.
`KDTextSeparator%` | $800 | Specify this item as a text separator. p$ and body$ must both be the null string for this to take effect. The separator counts as an item in the value returned by `DIALOG`.

These constants are supplied in Const.oph.

See also `dEDIT`, `dINIT`.

## `dTIME` — Define an exit box for a time

Usage: `dTIME var lg&,p$,t%,min&,max&`

Defines an edit box for a time, to go in a dialog.

`p$` will be displayed on the left side of the line.

`lg&`, which must be a `LOCAL` or a `GLOBAL` variable, specifies the time to be shown initially. Although it will appear on the screen like a normal time, for example `18:27`, `lg&` must be specified as seconds after 00:00. A value of 60 means one minute past midnight; 3600 means one o’clock, and so on.

`min&` and `max&` give the minimum and maximum values which are to be allowed. Again, these are in seconds after 00:00. An error is raised if `min&` is higher than `max&`.

When you finish using the dialog, the time you entered is returned in `lg&`, in seconds after 00:00.

The display in the time editor can be controlled via the `t%` argument. Add together one or more of the following constants from `Const.oph` to form `t%`:

`KDTimeWithSeconds%` | 1 | Time editor shows seconds.
`KDTimeDuration%` | 2 | Editing a duration.
`KDTimeNoHours%` | 4 | Time editor does not show hours.
`KDTime24Hour%` | 8 | Time editor uses the 24 hour clock.

This can be bulky to specify however, so the following convenience constants are also defined.

`KDTimeAbsNoSecs%` | 0 | Absolute + no seconds.
`KDTimeAbsWithSecs%` | 1 | Absolute + seconds.
`KDTimeDurationNoSecs%` | 2 | Duration + no seconds.
`KDTimeDurationWithSecs%` | 3 | Duration + seconds.

For example, `03:45` represents an absolute time while 3 hours 45 minutes represents a duration.

Absolute times are displayed in 24-hour or a.m./p.m. format according to the current system setting. 8 displays the time in 24 hour clock, regardless of the system setting.

Absolute times always display a.m. or p.m. as appropriate, unless the 24 hour clock is being used. Durations never display a.m. or p.m. Note, however, that if you use the flag 4 (no hours) then the a.m./p.m. symbol will be displayed and the flag 2 must be added if you wish to hide it.

See also `dINIT`.

## `dXINPUT` — Define an exit box for a secret string

Usage: `dXINPUT var str$,p$`

Defines a secret string edit box, such as for a password, to go in a dialog.

`p$` will be displayed on the left side of the line.

`str$` is the string variable to take the string you type.

`KDXInputMaxLen%` | 16 | Maximum length of `str$`.

This constant is supplied in Const.oph.

Initially the dialog does not show any characters for the string; the initial contents of `str$` are ignored. A special symbol will be displayed for each character you type, to preserve the secrecy of the string.

See also `dINIT`.