home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxdlg11.zip
/
rx.INF
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1995-09-22
|
129KB
|
4,358 lines
ΓòÉΓòÉΓòÉ 1. Introduction ΓòÉΓòÉΓòÉ
As an interpreted, high level language, REXX is supposed to be one of the
easiest languages to use. This means that a programmer can write useful
programs with a minimal investment of time and effort. Unfortunately, REXX has
one very big drawback; its facilities to get input and output from an enduser
are positively primitive. It can do little more than poll the command line
(ie, the enduser has to type in his input, one line at a time), and display
text messages to that same command line. REXX certainly doesn't support any of
the features that OS/2's Presentation Manager makes possible, such as using the
mouse and keyboard to manipulate scrolling lists of text, menus, sliders,
buttons, etc, as well as being able to arrange all of these in multiple windows
that also can be manipulated with the mouse and keyboard. With such PM
controls and dialogs, a programmer can create a much easier to use, and more
sophisticated, interface. Wouldn't it be nice to be able to combine PM's
flexibility with REXX's simplicity? Sure it would, and that's why there are a
few products that "extend" REXX to give it a PM interface (ie, add new REXX
commands that interface to PM, by having the REXX interpreter call C compiled
code in custom Dynamic Link Libraries which implements those new commands).
Rexx Dialog is one more such product; except that it's free, and it's small and
memory efficient because it doesn't try to do too much. It's sort of my
version of VREXX and PMREXX, but a lot more flexible in the way that it lets
you create and manage a PM interface for your REXX script. Using Rexx Dialog,
you can quickly create a PM program in REXX.
It is hoped that, by making a tool such as Rexx Dialog freely available (and
some of the other freebies that I've created such as FILEREXX.DLL), other
programmers will continue that spirit and create even more OS/2 native software
(which is very much needed right now) and freely distribute such.
Some of the words in this manual are highlighted in bold text, such as Group
Type. These are words that refer to something that you have to setup in your
REXX script to use Rexx Dialog to create and manage a PM interface. Other
words are in colored text such as RXVAL. These refer to actual REXX variables
in your script (ie, the names of variables). Underlined words, such as RXSAY,
refer to actual REXX commands created by Rexx Dialog, which your REXX script
calls to create and manage a PM interface. Some words are in colored text such
as Read This are meant to be emphasized. Words in italics refer to aspects of
OS/2.
ΓòÉΓòÉΓòÉ 2. Copyright ΓòÉΓòÉΓòÉ
Rexx Dialog (comprised of the files RXDLG.DLL, RX.EXE, RX.INF, RXCAPP.INF and
all example REXX scripts written by Jeff Glatt) are all copyright 1995 by Jeff
Glatt. These files are freely redistributable, and may be used by and
distributed along with any software, be it commercial or otherwise, provided
that these files are not internally modified, nor specifically sold as a
complete product by themselves. The only price that you have to pay is the one
that you're already paying by spending all of your time in front of a computer
instead of developing healthier outlets.
NOT SO STANDARD DISCLAIMER:
These programs are provided "as is" without warranty of any kind either
expressed or implied or tatooed in a place that only a few people have ever
seen, including but not limited to the implied warranties of merchantability,
fitness for a particular purpose, and the dubious assumption that the software
has been created by a sane individual who would never do anything that may hurt
you. The entire risk as to the results and performance of the programs is
assumed by you or someone who looks exactly like you. Jeff Glatt does not
guarantee that the functions in these programs will meet your requirements,
especially if your requirements involve lots of latex and some docile,
domesticated animal. Nor does Jeff Glatt warranty the programs to be
uninterruptable or error-free, although mercifully free of "General Protection
Faults". If you use said programs, you can not say anything nasty about the
author, even if the programs inadvertently cause the erasure of your collection
of X-rated GIFs of a conservative, overweight and overrated TV "personality"
plooking himself vigorously with his royalty checks from some rancid paperback.
Jeff Glatt is not responsible for any damages as a result of anything that he
has done, or hasn't done, or was supposed to do but never got around to it, and
furthermore, he doesn't even care so leave him alone, ratface. You may have
more or less protections in certain states of the union, depending upon how far
your local politician is willing to bend over for some bribe from a business
lobbyist. Just remember that Jeff Glatt has no money, so don't bother suing
him as a result of any damages caused by this OS/2 program. Tell your greasy
lawyer to go after IBM, and make sure that you pick 12 really stupid pinheads
for the jury. If swallowed, induce vomiting immediately by contemplating the
asthetics of Microsoft Windows.
OS/2 is a trademark of International Business Machines Corporation.
Windows is a trademark of Microsoft Incorporated, and furthermore, Bill Gates
is to blame for it.
If you have unreasonably presumptuous suggestions (ie, an enduser who expects
outrageous amounts of free support), snide comments, criticisms, and anything
else other than dollar bills, then send them to someone else because you got it
for free, and you know what you get for nothing? On the other hand, any type
of positive contribution from other programmers is very much welcome and
encouraged as these are the only folks who can made things happen for OS/2.
IBM ain't gonna do it. If you do need to contact the author, then either phone
some of the more prominent psychiatrict clinics in central New York state, or
try this:
Jeff Glatt
6 Sycamore Drive East
New Hartford, NY 13413
(315) 735-5350
Sure, this copyright notice has attitude. Get used to it, or kill yourself.
ΓòÉΓòÉΓòÉ 3. Version Errata ΓòÉΓòÉΓòÉ
This is version 1.1. This corrects a bug in which, when numerous groups of
Radio buttons were placed within a single window, clicking upon one radio
button group caused all other groups to lose their visual highlighting
(although not the actual selection within the group). It also adds the main
window to Presentation Manager's Window List.
ΓòÉΓòÉΓòÉ 4. Initial Setup and Requirements ΓòÉΓòÉΓòÉ
There are 2 files that comprise the Rexx Dialog facility; RX.EXE and RXDLG.DLL.
These must be present upon any system that runs scripts which utilize Rexx
Dialog's new commands to create and manage a PM interface. Of course, the OS/2
REXX Interpreter must also be installed upon the system (although PMREXX does
not need to be -- especially now that you have Rexx Dialog).
RX.EXE is an executable that you use to start up your REXX script. At an OS/2
command prompt, you type RX, followed by the name of your REXX script (with
full path if necessary). For example, to start the REXX script "blort.cmd",
you would type:
rx blort
and then press ENTER.
Note: It's not necessary to type the .exe extension on rx.exe, nor the cmd
extension on the script name.
You must use RX.EXE to start (and run) your REXX script, or the REXX
interpreter won't understand the special, new commands that Rexx Dialog makes
available to your script, and you'll get an error message saying that "The name
specified is not recognized as an internal or external command, operable
program, or batch file". RX.EXE takes care of all of the details of telling
the REXX interpreter what the new commands are (so that your script can use
them) and also runs your script.
RX.DLL is a Dynamic Link Library used by RX.EXE. RX.EXE must be able to find
this DLL, so you should copy it to some place that is specified on the LIBPATH
statement of your config.sys file. A good place is C:\OS2\DLL. Also, it's
recommended that RX.EXE be copied to some place that is specified by the PATH
statement. A good place is C:\OS2.
If you would like to setup your script so that it runs by clicking upon a
Desktop icon (ie, object), that's easy to do. Open the Templates folder on the
Desktop. Drag the Program object to whichever place you want to put the icon
for your script, and release the mouse button (ie, drop the icon there). A
Notebook should pop up, with the Settings page displayed. In the Path and
Filename entry, type RX.EXE. If you didn't copy RX.EXE to some place specified
in your config.sys PATH, then you'll need to specify the complete path, for
example, C:\OS2\RX.EXE. Make sure that RXDLG.DLL is copied to some place
specified in your config.sys LIBPATH (or you can usually place it in the same
directory as the scripts that use Rexx Dialog). In the Parameters field of the
Notebook, type the name of your REXX script. Again, you may need to specify
the full path. Now whenever you click upon that icon, your script will run,
and be able to use Rexx Dialog's new commands.
Repeat the above process with every REXX script for which you'd like to setup a
Desktop icon, and which will use Rexx Dialog.
Note: It doesn't matter whether you launch your REXX script from the OS/2
command prompt (as described above) or a Desktop icon. Your script will
run as if it were a real PM program regardless.
ΓòÉΓòÉΓòÉ 5. Rexx ΓòÉΓòÉΓòÉ
REXX is a computer language. It's interpreted, like BASIC, which means that
you simply write your program as an ordinary text file, and some interpreter
runs that text file directly. There's no need for you to compile and link your
source code into an executable program. Your text file *IS* your program (and
can be created with any text editor such as the OS/2 System Editor, or the
Enhanced Editor). So, REXX is a script language. But, it has lots of
features, including variables, string processing, looping, etc. Consult the
"Rexx User's Guide" on the OS/2 PDK, or the "Rexx Procedures/2" online book for
a description of fundamental things that can be done with REXX.
The REXX interpreter is built into OS/2. That's why you can run a REXX script
(ie, text file containing REXX instructions) just by typing its name from an
OS/2 Command Prompt window.
OS/2 programs may be written to also start up REXX scripts. RX.EXE is one such
program. It is used to start your REXX script so that your script has 9
special commands to call in order to create and manage a PM interface.
There's a very important difference between running a REXX script using RX.EXE,
and running a script from a Command Prompt window. When you run a REXX script
using RX.EXE, RX.EXE takes care of all of the details of letting the REXX
interpreter know what the new commands are. Your REXX script can immediately
use those new commands. RX.EXE also helps your script create and manage the PM
interface that your script specifies.
RX.EXE does not pass any args to your REXX script.
Note: It's advisable to first read the OS/2 documentation on REXX, and
experiment with the standard commands and features. The REXX examples
here may use some standard features without explaining them. Mostly,
the examples will illustrate the 9, special commands that Rexx Dialog
makes available to create and manage a PM interface.
ΓòÉΓòÉΓòÉ 6. Rexx Dialog Commands ΓòÉΓòÉΓòÉ
The 9 special Rexx Dialog commands that your script can call to create and
manage a PM interface all begin with the 2 letters RX. Here are the 4
commands:
RXACTIVE
RXDLG
RXERR
RXFILE
RXHELP
RXQUERY
RXSAY
RXSET
RXVERS
You can begin a line in your REXX script with one of these commands. Then,
when the script is run, the REXX interpreter executes the command when it gets
to that line.
Most of the commands will have arguments. This is just additional text that
you place after the command, on the same line. Arguments modify the way that a
Rexx Dialog command works, or provide necessary additional information for the
command to use.
Note: It's OK to put blank spaces before and after commands, and inbetween
arguments. This makes your script easier for you to read.
All Rexx Dialog commands return either a string or number (depending upon which
you specify via RXERR, but some commands always return strings). The return is
stored in the special REXX symbol RC. As each command is issued, RC reflects
what that command returns. The return usually tells you whether a command
worked or failed (although sometimes the return provides other info instead
such as which button was used to dismiss a RXSAY box). In the case of a
command that could fail as a result of something that goes wrong within the
command, you should always check RC after issuing that command. Alternately,
since all Rexx Dialog commands set the REXX FAILURE or ERROR flags for any
possible errors, you can SIGNAL ON ERROR or SIGNAL ON FAILURE to an appropriate
place in your REXX script to handle such an error situation. An RC of 0 (for
error numbers) or an empty string, ie "" (for error strings) is considered to
be a successful return.
The following descriptions of each command tell what the template for the
command is (ie, how you notate it in your script), what the command does, what
the arguments are, what it returns to your REXX script, and examples of using
the command.
ΓòÉΓòÉΓòÉ 6.1. RXACTIVE ΓòÉΓòÉΓòÉ
Template RXACTIVE
Description This command determines which open window is the active one, and
sets the REXX variable RXWIND to that window's title. It also
sets the REXX variables RXID and RXSUBID to the Group # and
Control # that have the focus. For example, if the user
happened to be using the first control of the first Group in a
window titled "Window 1", then RXWIND is 'Window 1', RXID is 1,
and RXSUBID is 1. If the window itself has the focus (ie, the
window is active but the user has not activated any particular
control inside of that window), then RXID and RXSUBID are set to
0.
If none of the open windows are active, this indicates that the
user has made some other application's window active. In this
case, RXWIND is set to a NULL string (ie, '').
Args
None.
Returns
Sets RXWIND, RXID, and RXSUBID.
Examples
/* This gets and displays RXWIND, RXID and RXSUBID for the active window */
RXACTIVE
RXSAY 'Active Window = "'RXWIND'"'
RXSAY 'Active Group = 'RXID
RXSAY 'Active Control = 'RXSUBID
ΓòÉΓòÉΓòÉ 6.2. RXDEV ΓòÉΓòÉΓòÉ
Template RXDEV DeviceTitle Operation Value
Description This command is used to setup for reading from devices or pipes.
The input will be returned when your script calls RXDLG.
Note: You must have a Main Window open before calling RXDEV.
Closing the Main Window also performs RXDEV's CLOSE
Operation upon any opened and initialized devices.
PM applications (including REXX scripts written for Rexx Dialog)
must approach reading from devices differently than non-PM apps
(ie, REXX scripts launched like they normally are; without a PM
interface). This is due to 2 design limitations of OS/2. First
of all, PM has a single system queue which requires a PM app's
window procedure to complete its work in 1/10 of a second. If a
PM app doesn't do this, it will appear to "lock up" the desktop.
The other design limitation of OS/2 is its very awful 16-bit
Physical Device Driver model, which is essentially a more
convoluted version of MS-DOS 2.0's driver model. This model
lacks standardized approaches to such things as querying if any
input is available for reading, or setting a time-out for reads
(ie, if no input is received within a certain amount of time,
the read is aborted). As might be expected, communication
between an archaic 16-bit driver model and modern 32-bit
application software is grotesquely crude and inflexible, and
therefore, driver programmers have resorted to all manner of
proprietary schemes to implement these features that IBM never
wrote into OS/2's PDD model. Worse, many drivers don't even
bother to implement the features at all. So, a call to DosRead
input from a device may result in the app being "blocked" (ie,
halted) until input is available for reading, and this may take
much longer than 1/10 of a second. Therefore, a PM app must
have a separate thread to read input from a device. Its main
thread must not call any function that ultimately calls DosRead
when reading from a device. (ie, Standard functions such as
STREAM, CHARIN, and LINEIN must not be used when reading from a
device. Neither can you use FileRexx's FileRead, FileGets, or
FileReadValue, nor any other function library's input routines
that call DosRead, such as RXASYNC. Hey, if you don't like it,
tell IBM to fix PM's single system queue, and implement a more
modern PDD model, preferably 32-bit). In lieu of these
functions, you'll use RXDEV to setup a device for reading, and
then retrieve input from the device via RXDLG. To make things
easier, Rexx Dialog's device reading has such features as being
able to read whole blocks of data (ie, more than 1 character at
a time), and discard input that doesn't begin or end with
certain patterns, parse input into several REXX variables, and
perform binary to REXX variable conversion. So, it's sort of
like a combination of FileGets, FileRead, and FileReadValue,
which should handle the bulk of your needs.
Args
DeviceTitle The title (ie, string) of the device, which can be any title of
your choosing. If there are blank spaces in the title, then
enclose the string with two pairs of quotes '"' (or "'") if the
title is a variable, or '" and "' (or "' and '") if a literal
string. For example, these are legal titles:
'"'title'"' /* title would be some variable that you
initialized earlier, for example, title='My Device Title' */
'"My Device Title"'
This is used to identify the device in the same way that the
WindowTitle arg to RXDLG identifies a window. The DeviceTitle
should be unique from any other device that you have setup for
reading with RXDEV. If you specify a DeviceTitle of '""', then
this refers to the first device that has been initialized (and
is not yet closed) with RXDEV.
Value The meaning of the Value arg depends upon the Operation arg (and
may not need to be supplied for some Operations).
Operation Operation is one of the following:
INIT This operation must be performed before any other operations.
It sets up a device for reading (and will begin the reading
unless the PAUSE Flag is set). Prior to performing this
operation, you must setup several REXX variables to desired
values. After the INIT operation, these variables can be
discarded.
First, you must open the device for reading using FILEREXX's
(ie, my REXX function library for doing device I/O, available
separately) FileOpen. If you're going to also be doing writes
to the device (ie, using FILEREXX's FileWrite, FilePuts, or
FileWriteValue), you can open the device for both reading and
writing, and use this one handle for both FILEREXX and Rexx
Dialog. You must store the handle returned by FileOpen in the
REXX variable RXINFO before doing the INIT operation.
The REXX variable RXCOUNT contains the size of the input buffer,
and a count limit. Rexx Dialog can return blocks of data (ie,
more than 1 character or 8-bit byte) to your script. For
example, you can ask Rexx Dialog to return the next 64 bytes of
data read from the device, when you call RXDLG once. The count
limit is how many bytes to input before they are returned to
your script. For example, a count of limit of 64 would mean
that after reading 64 bytes, a call to RXDLG returns those 64
bytes to your script. The input buffer must be at least 4 bytes
larger than the count limit. Rexx Dialog implements a circular
buffer. This helps to speed up device reads, but unless your
script can receive and process input faster than Rexx Dialog
reads it, further device input may overwrite previous input.
You can work around this either by using the PAUSE Flag, or by
setting the size of the input buffer to be at least twice your
count limit (plus 4 bytes that Rexx Dialog uses for
bookkeeping). So, if your count limit is 64, and you want
double-buffering, then set the input buffer size to (64+4)*2.
If you need triple buffering, set the buffer size to (count
limit + 4)*3. Etc. If you specify a buffer size of 0, then
4096 bytes is used. This corresponds to a page of memory. It's
best to round up your buffer size to a multiple of 4096 (or use
a default of 0 if you don't need more than 4096 bytes), as that
won't use any more memory, due to OS/2's paging system. If you
don't specify the count limit, it defaults to a setting
appropriate for double buffering. The buffer size and count
limit are restricted to 65,535 or less.
RXLABEL is set to the name of the REXX stem variable where the
device input is returned. The variable name should be limited
to 22 characters. All of the returned bytes are stored in that
variable name with a .0 extension. For example, if you specify
RXLABEL = 'MYINPUT', and a count limit of 3, then a call to
RXDLG returns those 3 characters in MYINPUT.0. If the NUM flag
is set, then each byte is expressed as an ascii numeric value
(in decimal, a range of 0 to 255), with a space inbetween each
value. For example, if a line feed and carriage return were
returned, MYINPUT.0 would be '13 10'. If the SIGN Flag is set
(in addition to NUM), then the ascii numeric values are
expressed as signed (instead of unsigned) values (ie, a range of
-128 to 127). The returned string is limited to 255 characters.
If the PARSE Flag is set, then each byte is returned in a
different stem variable (and the 255 character limit is not
applicable). For example, the first byte is returned in
MYINPUT.0, the second byte is returned in MYINPUT.1, and the
third byte is returned in MYINPUT.2. Both the NUM and PARSE
flags can be set.
RXSTARTPAT is set to a string containing various patterns, one
of which must be matched before device input is saved. This
makes it possible to discard device input until a certain
pattern is spotted, and then start collecting all data at that
point. Each pattern in the start string must be separated by a
| character. If RXSTARTPAT is a null string, then all device
input is saved (ie, start pattern match is disabled).
Each pattern can contain one or more characters or values. A
pattern begins with a "Format" letter. This is an 'H' if you're
expressing the values in hexadecimal, a 'B' if you're expressing
the values in binary, a 'D' if you're expressing the values in
decimal, or an 'L' if the characters are not to be translated in
any way (ie, a literal string). For 'H', 'B', or 'D', Rexx
Dialog translates each value to its binary equivalent when used
in a start pattern. For example, if you want to set a start
pattern that looks for a line feed and a carriage return
characters, you could express the LF and CR in decimal as so:
'D 13 10'
Or, you could express them each in hexidecimal:
'H D A'
Or, you could even express them in binary:
'B 1101 1010'
If the "Format" is 'L', then the value string is used verbatim
without any translation to binary values. For example, to set a
start pattern that looks for the string 'hello':
'L hello'
The Format can have an extension, which I'll refer to as the
"Count". This will be how many values of that type follow. If
the Count arg is omitted, then the field's size is ultimately
determined by however many values follow. For example, if you
had a field that consisted of 32 decimal values, you could
define the Format and Count as D.32 and then list the 32 values
after that. If you don't supply as many values as "Count", then
null bytes are used to pad out to Count. There can be an
additional extension after the Count, which I'll refer to as an
"Initialization". This will be either a numeric value that it
is to be duplicated for Count times, or a (non-numeric)
character that it is to be duplicated Count times. For example,
if you wanted to specify 32 decimal values and set them all to
the value 16, the Format, Count, and Initialization would be
D.32.16 with no need to specify any values after that. If you
wanted to specify 4 'A' chars, the Format, Count, and
Initialization would be L.4.A with no need to specify any chars
after that.
It's also permissible to have more than one Format, Count, and
values (or Initialization) per field. But, all of the Formats
must also have a Count, except for the last Format (which may or
may not have a Count). For example, say that you want to set a
start pattern of 'hello' followed by a line feed and carriage
return:
'L.5 hello D 13 10'
Here's an example of setting 2 start patterns. One pattern is
'OK', and the other pattern is 'NO'. So, device input is
ignored until either string is detected.
'L OK | L NO'
The returned input starts with the matching start pattern (ie,
it's part of the returned input) unless the TRIM Flag is set (in
which case the start pattern is trimmed from the returned
input).
If the WATCH Flag is set, then the device input is returned as
soon as a start pattern is matched (ie, the returned input
consists only of the matching start pattern). This is useful if
you need to throw away all device input except for a particular
set of patterns.
RXENDPAT is also set to a string containing various patterns.
If one of these patterns is matched, then the device input is
returned to the script at that point, regardless of whether the
count limit has been met. This makes it possible to force
device input to be returned as soon as a certain pattern is
spotted. Each pattern in the end string must be separated by a
| character. The format of the string is the same as per
RXSTARTPAT. If RXENDPAT is a null string, then device input
isn't returned until the count limit is reached (ie, end pattern
match is disabled).
The returned input ends with the matching end pattern (ie, it's
part of the returned input) unless the TRIM Flag is set (in
which case the end pattern is trimmed from the returned input).
RXFLAGS is any or all of the following, with each flag separated
by a | character.
TRIM Trim any matching start and/or end pattern from the
returned input.
NUM Translate each returned byte to an ascii numeric value.
SIGN Return ascii numeric values as signed. The NUM Flag
must be also set.
PARSE Return each byte in its own REXX stem variable.
PAUSE Rexx Dialog's device reading pauses after returning each
block to the script. It will not read the next block until the
script performs a RESUME operation. This allows the script to
start/stop the device reads at will, thereby preventing Rexx
Dialog from reading input faster than the script can handle it.
WATCH Return input as soon as one of the start patterns is
matched. End patterns are ignored (as is all input except for
an exact match to one of the start patterns).
PARTIAL Some drivers do not block reads. That is to say that
if there is no more input to be read, the driver indicates that
to Rexx Dialog. For example, COM drivers support setting up
reads to have a time-out (via an IOCTL interface), in which case
if there is no more data to be read, control is returned to Rexx
Dialog. In this case, setting the PARTIAL Flag will cause Rexx
Dialog to return (to your script) whatever data it has collected
up to the point when no more data is available, even though an
end pattern may not be matched (ie, RXENDPAT=0) or the count
limit has not been met. In other words, Rexx Dialog always ends
up returning input data back to your script as soon as that data
is available from the device, rather than waiting to fulfill the
count limit or finding a matching end pattern before returning a
data block.
COUNT This operation sets a new count limit for the specified device.
The input buffer size can't be altered after INIT. The Value
arg is the new count limit (which should be at least 4 bytes
less than the input buffer size).
VAR This operation sets a new REXX stem variable name to return
input for the specified device. The Value arg is the new
variable name.
START This operation sets a new start string for the specified device.
The Value arg is the new start string (expressed in the same
format as per the INIT operation).
END This operation sets a new end string for the specified device.
The Value arg is the new end string (expressed in the same
format as per the INIT operation).
FLAGS This operation sets the new Flags for the specified device. The
Value arg is the new Flags (expressed in the same manner as per
the INIT operation).
RESUME This operation tells Rexx Dialog to read another block of data
for the specified device. There is no Value arg. You must do a
RESUME Operation each time after RXDLG returns device input if
you wish to receive another block of data upon the next RXDLG
call. Otherwise, device reading is paused.
CLOSE This operation closes the file handle for the specified device,
and frees any resources allocated for it. There is no Value
arg. After a CLOSE operation, you do not need to FILEREXX
FileClose any handle that was setup on the INIT operation.
Neither can you subsequently use that same handle with other
FILEREXX routines. (You'd have to FileOpen the device again).
Returns
A large variety of error messages or numbers could be returned by RXDLG. See
Errors for details.
The actual device input is returned upon a call to RXDLG. RXDLG will setup the
REXX stem variable you specified during INIT (or VAR) with the device input.
RXWIND will be set to the DeviceName of the device whose input is being
returned. RXID will be 1000 + the device number (where the first device
initialized is 0, the second device initialized is 1, etc). So, you can either
use RXWIND or RXID to differentiate between RXDLG returning device input, or
some user input. RXSUBID will be set to how many input bytes are being
returned. RXSTARTPAT will be set to the number of whichever start pattern
matched the input (where the first start pattern is 1, the second pattern is 2,
etc). RXSTARTPAT is 0 if no pattern was matched (ie, there was no start string
specified). RXENDPAT will be set to the number of whichever end pattern
matched the input. RXENDPAT is 0 if no pattern was matched (ie, there was no
end string specified or the count limit was reached before a matching end
pattern could be detected).
ΓòÉΓòÉΓòÉ 6.3. RXDLG ΓòÉΓòÉΓòÉ
Template RXDLG NumGroups WindowTitle Dimensions Flags
RXDLG WindowTitle Operation
Description This command is the major function that is used to create and
manage the PM Interface. It creates, manages, and finally
destroys a window which can contain many different kinds of PM
controls such as push buttons, radio buttons, checkmark buttons,
result buttons, list boxes, drop boxes, entry boxes, sliders,
menus, etc) that the user manipulates in order to enter data, or
which your script uses to display data. RXDLG has 2 different
calling templates. The first is used when you want to create a
window. The second template is used when you want to perform
user input or output with, or perform some other operation such
as destroying, a window. RXDLG also returns device input (if
you've opened a device for reading). RXDLG can be called many
times to create multiple windows, each with their own (perhaps
unique) Groups of controls; all managed by a collaborative
communication between Rexx Dialog and your script (mostly using
RXDLG).
RXDLG requires that you set up various REXX Variables to
describe all of the controls/menus/etc that you want within a
particular window prior to issuing a RXDLG command to create a
window. Rexx Dialog then queries the state of those REXX
variables on its own, and creates your window. Subsequent calls
to RXDLG can perform some other operation upon an open window
that your script specifies.
RXDLG is a very complex command, so the next sections deal with
various topics that concern RXDLG. This page simply gives a
brief, reference summary. You may wish to skip to the next page
now, and use this page simply as a reference after becoming
familiar with RXDLG.
Note: Rexx Dialog assumes that the system font has a point size
of 10 (ie, as does the default System Proportional).
Args
NumGroups How many Groups of controls are described. For example, if you
specify 2 Groups, then you need to set up two sets of variables
for 2 Groups (ie, RXVAL.1, RXINFO.1, RXLABEL.1, etc, for the
first Group, and RXVAL.2, RXINFO.2, RXLABEL.2, etc, for the
second Group) or RXDLG will fail to create the window and return
an error message. Note that if you were to describe two Groups,
but only passed a NumGroups of 1 to RXDLG, then a window would
be created with only 1 Group in it. You'd never see that second
Group that you specified. Make sure that NumGroups is set
respective to how many sets of variables (ie, Groups of
controls) that you've described, and vice versa.
Only the first 127 Groups in a window can have groupboxes
automatically created around them (if desired). For subsequent
Groups, you'll have to use separate GROUP Types to encompass the
desired controls.
Note: If you don't supply a NumGroups arg, then Rexx Dialog
automatically knows that you're using the second template
of RXDLG (ie, where the WindowTitle comes first). In
this case, you're not creating a window, but rather,
performing an operation upon an already open Window.
In order to create a window, NumGroups must not be 0 (ie, you
always have to specify at least 1 Group of controls). If you
truly want an "empty" window, then specify an empty MENU Group.
WindowTitle The title (ie, string) of the window. If there are blank spaces
in the title, then enclose the string with two pairs of quotes
'"' (or "'") if the title is a variable, or '" and "' (or "' and
'") if a literal string. For example, these are legal titles:
'"'title'"' /* title would be some variable that you
initialized earlier, for example, title='My Window Title' */
'"My Window Title"'
Note: You must not name a window where the first character is a
numeric digit (ie, 0 to 9) although numeric digits can
appear later in the title.
If you're using the first RXDLG template, then a window will be
created with this title.
If you're using the second RXDLG template, then WindowTitle is
the title of the window upon which you wish to perform an
operation. In the second template, the WindowTitle can be an
empty string, ie '""', in which case, the Main Window is used
for Operations 2, 3, and 4, and for Operations 0 and 1, an empty
string allows user interaction to resume with the window that
was active upon the previous call to RXDLG. The WindowTitle
that you pass must match the title of some open window, or RXDLG
will return a "Can't find Rexx Dialog" error message. (If you
pass an empty string, then the Main Window must be open).
Note: If you specify a particular window title for Operations 0
or 1, that window will be brought to the front and made active.
Operation This arg is for the second template of RXDLG. Operation will be
one of the following:
0 Perform user interaction (only upon the specified window if its
MODAL flag is set). Note that if there are multiple windows
open and the specified window is not MODAL, then the user may
choose to interact with a different window which may cause RXDLG
to return. In such a case, you should always check the RXWIND
variable after a call to RXDLG.
1 Perform user interaction (only upon the specified window if its
MODAL flag is set), and also tell Rexx Dialog that it's OK to
close that window when RXDLG returns. Note that if there are
multiple windows open and the specified window is not MODAL,
then the user may choose to interact with a different window
which causes RXDLG to return. In such a case, the specified
window will not be closed, and you should always check the
RXWIND variable after a call to RXDLG.
2 Set up the REXX return values as per the state of the specified
window and return immediately without performing any user
interaction nor window closing. This operation does not set up
the RXID, RXSUBID, and RXWIND variables.
3 Set up the REXX return values as per the state of the specified
window, close that window, and return immediately without
performing any user interaction. This operation does not set up
the RXID, RXSUBID, and RXWIND variables.
4 Close the specified window, and return immediately without
performing any user interaction. Do not set up the REXX return
values as per the state of that window. If you want to close
all open windows, including the Main Window, then pass a
WindowTitle arg of '""' (ie, two double quotes inside of two
single quotes).
255 Clear out the PM message queue without performing any user
interaction nor closing any windows nor setting up any REXX
variables. This is just to prevent PM lockups if you have
windows open, and your script is not "sleeping" (ie, doing some
call to RXDLG that performs user interaction).
Dimensions The name of a REXX variable that is a string containing the
desired Width, Height, X Position, and Y Position of the window.
These are measured in screen pixels. X and Y positions are
referenced to the bottom left corner of the Desktop if the
window is a Main Window (ie, the very first window that you
create upon the Desktop). For example, specifying X and Y of 0
means that the Main Window opens at the bottom left corner of
the Desktop. All other windows that you create after the Main
Window are Child Dialogs, and their X and Y positions are
referenced to the bottom left corner of the Main Window (as
opposed to the Desktop itself). For example, specifying X and Y
of 0 means that the Child Dialog opens at the bottom left corner
of the Main Window (ie, inside of the Main Window itself).
Specifying a Width of 0 means that you want Rexx Dialog to
determine a default size and position for the window (and the
Height, X, and Y are ignored). In this case, you also get a
window that can be resized and maximized, and so the SIZE flag
is redundant. For example, if you wanted a window with
Width=300, Height=200, X=10, and Y=10, then setup a variable
with these values enclosed in quotes, and pass the name of that
variable as the Dimensions arg:
Note: Whenever Rexx Dialog closes a window, it updates the
Dimensions string for that window. This is handy if you
want to reopen the window later. If you pass the same
Dimensions string to RXDLG (without reinitializing it),
then the window will open with the same size and position
as it had when it was closed. Rexx Dialog also updates a
window's Dimensions string if you specify that window in
Operations 2, 3, or 4.
MyWinDimensions = '300 200 10 10'
RXDLG 1 '"My Window Title"' 'MyWinDimensions'
The variable containing the dimensions can be any legal variable
name that you wish.
Flags A string that describes the various display and management
options for the window. You can specify any or all of these
Flags, and each one must be separated by a | character, enclosed
in quotes. The various Flags are:
SIZE You want a window that can be resized by the user (ie, has a
border that he can grab with the mouse and move to resize the
window). The window will also have a maximize/restore button in
the titlebar.
MIN You want a window that can be minimized by the user. Main
Windows are always created with a minimize button in the
titlebar, and this flag need not be specified. A Main Window
minimizes into an icon on the bottom of the Desktop. If a Child
Dialog has a minimize control, it doesn't minimize to the bottom
of the Desktop, but rather, the bottom left of the Main Window.
(Be careful to not place controls there in the Main Window, or
the child window will fall behind them).
SMALL When a window is first created, it starts out minimized. The
MIN Flag must also be set.
MODAL When the window is created or when performing an operation upon
it, all other Child Dialogs and controls in the Main Window are
disabled.
Note: A Main Window cannot be created MODAL. The MODAL Flag is
ignored in this case.
NOCLOSE When a call to RXDLG returns as a result of the user doing
something with this window, Rexx Dialog automatically closes
this window. NOCLOSE simply is a way of telling Rexx Dialog to
close a window when it causes RXDLG to return, so that your
script doesn't have to perform that extra operation (which would
be done if the window was a one-shot type of deal, ie, where you
wanted to get a set of data from the user once, and then dismiss
the window).
Whenever the Main Window is closed, either automatically due to
not specifying NOCLOSE, or by doing an operation upon the Main
Window which causes it to close, all Child Dialogs are also
automatically closed.
Note: All windows have a CLOSE ICON (ie, on the left side of
the titlebar). RXDLG always returns when a user clicks
upon a CLOSE ICON (with RXID = -98). But a window is not
closed if the NOCLOSE Flag is specified. If you specify
NOCLOSE, your script always has to eventually perform an
END operation upon a particular window in order to close
it (although if your script exits with any windows still
open, those windows are automatically closed).
RESULT When the window has the focus, and the user presses the ESC or
ENTER key, RXDLG returns control to your script (ie, your script
"wakes up" from a call to RXDLG). See ESC and ENTER Keys.
KEYS When the window has the focus, and the user presses some key
combination, RXDLG returns control to your script (ie, your
script "wakes up" from a call to RXDLG). The RESULT Flag has
precedence over KEYS (for ESC and ENTER), although both Flags
can be set. See Keyboard Input.
ONCE After the timer for the window times out, the timer is
automatically disabled. See Time-out.
NEWSIZE After the user resizes a window, the REXX script is notified of
the new size. See Resizing a window.
Here's an example of a Flags arg that might be passed to RXDLG:
'SIZE|MODAL|MIN'
Of course, you could also use a variable:
myflags = 'SIZE|MODAL|MIN'
RXDLG 1 '"My Window Title"' 'DIMENSIONS' myflags
If you don't specify a Flags arg, then none of the above flags
are enabled (ie, you get a window that can't be sized, nor
minimized if not a Main Window, nor maximized, is not modal,
won't recognize the ESC and ENTER keys when that window is
active to return from RXDLG, and when it does cause RXDLG to
return, Rexx Dialog automatically closes the window.
Note: It doesn't matter in what order you specify the Flags,
but each must be separated from another using a | character.
Returns
A large variety of error messages or numbers could be returned by RXDLG. See
Errors for details.
Examples
See the following sections.
ΓòÉΓòÉΓòÉ 6.3.1. Groups ΓòÉΓòÉΓòÉ
A PM control is some graphical object (inside of a window) which the user can
manipulate with the mouse or keyboard in order to enter data. Controls can
also be used to display data to the user.
Rexx Dialog arranges controls into Groups. A Group is simply one or more
instances of the same type of PM control. For example, you can have a Group of
3 sliders. Or you can have a Group of 2 list boxes. Or you can have a Group
of 16 push buttons. Etc. Arranging similiar controls into Groups makes it
easier for your script to define many instances of the same type of control.
That's why I defined a Group. Of course, you could have only 1 control per
each Group, but that sort of defeats the purpose of a Group. How does Rexx
Dialog make it easier to define a Group of controls rather than 1 control at a
time? One thing that Rexx Dialog does is intelligently arrange and space
controls in the window. So, if you have a Group of 32 push buttons, you don't
have to specify the width, height, X and Y positions of each one (as well as
where to place and size the label of each button). You simply tell Rexx Dialog
where the first button is located, how many buttons there are, how many buttons
should appear upon each line, and what the width of a button is. Rexx Dialog
will take care of positioning and spacing the other 31 push buttons, and will
arrange them symmetrically. Secondly, if you desire a group box (ie, a
rectangular border that surrounds all of the controls in the group, and which
has its own label), Rexx Dialog intelligently figures out how to size and
position that group box. You merely have to specify the label for that group
box. Also, you typically may want the same kind of behavior for all of the
same type of controls. For example, maybe you want 10 list boxes, and you want
them all to be able to select multiple items in their lists. You don't have to
specify that you want multiple select for each list box. You simply define all
the list boxes within one group, and say that you want the group to be multiple
select. Finally, Rexx Dialog allows you to apply certain types of editing or
initializing to an entire group. For example, if you have 32 push buttons and
you want to clear the checkmarks of all of them, you simply say that you want
to clear the Group.
Rexx Dialog doesn't limit you to only one Group within a window, nor one Group
Type within a window. For example, you can have a Group of 3 sliders, and then
above them, in the same window, have a Group of list boxes. As another
example, you can have a Group of list boxes that are multiple select, and in
the same window, have another Group of list boxes that are single select.
Defining controls in Groups is an easy way to define lots of similiar controls.
But, because a Group can be merely 1 control, you can also have plenty of
flexibility on an individual control basis if need be. Also, because you only
need specify the X and Y position of the entire Group (and Rexx Dialog does
positioning of individual controls), it's easy to change the position of
Grouped controls.
There are several Types of Groups. They are:
Push Button (PUSH)
Radio Button (RADIO)
Checkmark Button (CHECK)
Result Button (RESULT)
Entry (ENTRY)
List Box (LIST)
Drop Box (DROP)
Spin Button (SPIN)
Slider (SLIDER)
Text (TEXT)
Group Box (GROUP)
Menu (MENU)
Each Type has its own options (ie, Flags) and a particular way in which you
must setup REXX variables to define that Group.
You must use particular REXX stem variables when you define the Groups in a
window. These stem variables are:
RXTYPE
RXX
RXY
RXFLAGS
RXLABEL
RXINFO
RXVAL
RXTYPE The Group Type. If you look at the above list of Types, you'll
see the values for Type in parentheses. So, to define a Spin
Button Group, you would set RXTYPE to 'SPIN'.
RXFLAGS May be interpreted differently for various Types. It describes
particular behavior and display options you want for this Group.
For example, a Group of list boxes may have RXFLAGS set to
'INDEX|MULTIPLE'. Each Group Type's Flags will be described
further in later sections.
RXLABEL May also be interpreted a little differently for various Types,
but for most Types, it is simply the Text Labels for all of the
controls within the Group, and the Label for any group box which
surrounds this Group. It will be set to one string that
contains the label for each control, starting with the first
control, and each label is separated from the next by a |
character. The group box label will be last (if it is specified
at all. If not specified, then no group box is created around
the controls). For example, if you have 3 list boxes named
"Fruits", "Vegetables", and "Meats" respectively, plus a
surrounding group box labeled "Food Groups", then RXLABEL would
be set to 'Fruits | Vegetables | Meats | Food Groups'.
Note: You can omit or add blank spaces between the labels and |
character. The above example could also be:
'Fruits|Vegetables|Meats|Food Groups'
or
' Fruits | Vegetables | Meats | Food Groups'
with the same results. Rexx Dialog trims leading and
trailing spaces off of each label.
If a particular control is not to be labeled, then simply leave
a blank space where its label would go. For example, to create
the "Meats" list box unlabeled, set RXLABEL to 'Fruits |
Vegetables | | Food Groups". You can omit the spaces and it
becomes 'Fruits|Vegetables||Food Groups'. If you don't want the
group box, simply omit its label, ie, 'Fruits|Vegetable|Meats'.
In fact, if you specify less labels than there are controls
within a Group, then the remaining controls are unlabeled. For
example, to only label the first 2 list boxes, not label the
third one, and omit the group box, set RXINFO to
'Fruits|Vegetables'.
Placing a ~ character before any letter in the label causes that
letter to be underlined. This is handy for identifying
"keyboard shortcuts" to the user (which your script will
implement using the window's KEYS Flag, and processing Keyboard
Input).
The first control in the group appears closest to the lower left
corner of the Desktop or Main Window. This is how OS/2 defines
coordinates. (I would have preferred a top-down approach).
RXINFO A string that may be interpreted differently for various Types,
but in some way, it describes how many controls are contained in
the Group. It may also describe things like how wide (in
pixels) a control should be, how many controls should be placed
upon each line, and also any other information particular to a
certain Group Type. For most all Group Types, the first 3
components in the RXINFO string are the number of controls in
the Group (ie, which I'll refer to as TotalControls), how many
controls appear per line (ControlsPerLine), and how wide a
control should be (WidthOfControl). (You only have to describe
the control height for certain Types. Most Types have a standard
height). For some controls, such as PUSH, RESULT, CHECK, RADIO,
and TEXT, a width of 0 tells Rexx Dialog to calculate the best
fit. How each Group Type utilizes RXINFO will be described
further in later sections.
RXVAL A string that may be interpreted differently for various Types,
but in some way, it initializes the values of the controls (ie,
it's either a string that contains the value of each control, or
contains the names of stem variables where Rexx Dialog finds the
values for the controls). Rexx Dialog also uses the same RXVAL
to return the data that the user enters via the controls in that
Group. How each Group Type utilizes RXVAL will be described
further in later sections.
RXX The X position of the Group (ie, where along the X axis the
first control within the Group should be positioned in a
window). This is measured relative to the lower left corner of
the Desktop (if a Main Window) or the Main Window's lower left
corner (if a Child Dialog). In other words, this is how far
away from the left border of the Desktop or Main Window, you
want the Group of controls to be displayed. If a group box is
to be included, move the group farther to the right in order to
make room for the box.
RXY The Y position of the Group (ie, where along the Y axis the
first control within the Group should be positioned in a
window). This is measured relative to the lower left corner of
the Desktop (if a Main Window) or the Main Window's lower left
corner (if a Child Dialog). In other words, this is how far up,
from the bottom border of the Desktop or Main Window, you want
the Group of controls to be displayed. If a group box is to be
included, move the group up higher in order to make room for the
box.
The stem on these variable names pertains to which Group you're defining.
Don't get nervous. I'm going to explain this. Haven't I done OK so far?
For example, let's say that you want a Group of 3 sliders, a Group of 2 spin
buttons, and a Group of 4 push buttons in a window. That's 3 Groups. Let's
say that you want the sliders to be Group 1, the spin buttons are Group 2, and
the push buttons are Group 3. That means that, when you describe the slider
group, the variables names that you use are RXTYPE.1, RXX.1, RXY.1, RXFLAGS.1,
RXLABEL.1, RXINFO.1, and RXVAL.1. When you describe the spin button group, the
variables names that you use are RXTYPE.2, RXX.2, RXY.2, RXFLAGS.2, RXLABEL.2,
RXINFO.2, and RXVAL.2. When you describe the push button group, the variables
names that you use are RXTYPE.3, RXX.3, RXY.3, RXFLAGS.3, RXLABEL.3, RXINFO.3,
and RXVAL.3. What variables would you use to describe a fourth Group of
controls in the window? Yep. RXVAL.4, etc. See, that wasn't so bad, was it?
OK, now it's time for an example. Let's implement the above example. Don't
worry about what the particular strings for RXVAL, RXINFO, and RXFLAGS mean for
each Type. Just note how I define the 3 Groups (which can be done in any
order, or at any time as long as this is done before the call to RXDLG). Pay
attention to the commented lines.
/* First Group (ie, the 3 sliders) */
RXTYPE.1 = 'SLIDER' /* SLIDER Type */
RXFLAGS.1 = ' '
RXLABEL.1 = '128 255 Slider 1: | 64 0 Slider 2: | 128 0 Slider 3: | Slide Us'
RXVAL.1 = '64 32'
RXINFO.1 = '3 1 142' /* TotalControls, ControlsPerLine, WidthOfControl */
RXX.1 = 80 /* X position of first control (ie, the Group) */
RXY.1 = 18 /* X position of first control (ie, the Group) */
/* Second Group (ie, the 2 spin buttons) */
RXTYPE.2 = 'SPIN' /* SPIN Type */
RXFLAGS.2 = ' '
RXLABEL.2 = '128 0 Spin 1: | 64 0 Spin 2: | Spin Us'
RXVAL.2 = '10 20'
RXINFO.2 = '2 1 90' /* TotalControls, ControlsPerLine, WidthOfControl */
RXX.2 = 320 /* X position of first control (ie, the Group) */
RXY.2 = 18 /* X position of first control (ie, the Group) */
/* Third Group (ie, the 4 push buttons) */
RXTYPE.3 = 'PUSH' /* PUSH Type */
RXFLAGS.3 = ' '
RXLABEL.3 = 'Push 1 | Push 2 | Push 3 | Push Us'
RXVAL.3 = ''
RXINFO.3 = '3 3 0' /* TotalControls, ControlsPerLine, WidthOfControl (best
fit) */
RXX.3 = 90 /* X position of first control (ie, the Group) */
RXY.3 = 100 /* X position of first control (ie, the Group) */
/* Now that you've defined the 3 Groups, you can create a window containing
them. Let's call it "Main Window" (since it will be the first window that we
open, and therefore, the Main Window). Note that I specify NumGroups arg as 3
*/
windowSize = '' /* Default */
RXDLG 3 '"Main Window"' 'windowSize' 'RESULT'
/* After the window is created, you can DROP those REXX variables used for such
if desired, in order to conserve memory. It's recommended that you leave RXVAL
and all windows Dimensions strings. */
DROP RXTYPE. RXFLAGS. RXLABEL. RXINFO. RXX. RXY.
/* Perform user interaction, such as wait for him to click the window CLOSE
ICON */
RXDLG
Copy the above example to a file and run it with RX.EXE.
Note: It doesn't matter in what order you assign the variables. For example,
you can setup the variable RXINFO.1 before you setup RXTYPE.1. The only
important consideration is setting up all variables before the call to RXDLG.
ΓòÉΓòÉΓòÉ 6.3.2. Managing a PM Interface ΓòÉΓòÉΓòÉ
In order to interact with the user (ie, get input from him and display output
to him), your script will need to use one or more PM windows (with PM controls
inside of them).
To create a window, you use the first template of RXDLG. Call RXDLG with the
NumGroups parameter greater than 0 (ie, you always have to specify at least 1
Group of controls). This tells RXDLG that you wish to create a window with
that many Groups of controls inside of it. RXDLG will query all of the
variables that your script setup in order to create, initialize, and display
that window and its controls. If this is the first window to be displayed, it
becomes the Main Window and all other windows (ie, Child Dialogs) open inside
of this window. The window is given the title that you specified to RXDLG.
Note: Each window should have a distinct title.
After RXDLG creates the window, it will return immediately. Although the
window is displayed, the user will not be able to interact with it yet. At
that point, you can do further initialization if desired. One thing that you
can do is call RXDLG again, using its first template, to create another window.
You can have as many windows simultaneously open as desired (PM resources
permitting), each containing its own (perhaps unique) Groups of controls.
Then, you'll make one or more calls to RXDLG using the second template to
manage the PM interface. In the second template of RXDLG, you specify what
operation you wish to perform on the PM interface, where such operations
include allowing the user to interact with one or all open windows and perhaps
return user input to the script, and eventually closing down windows.
The following discussion is for RXDLG Operations that perform user interaction
(ie, 0 and 1), and may not pertain to other RXDLG Operations.
When you perform an RXDLG Operation that allows the user to interact with the
windows (and the PM controls within them), RXDLG does not return immediately.
Instead, your script "goes to sleep" while Rexx Dialog manages the user's
interaction and all of the PM processing associated with that. In other words,
while the user is interacting with the windows\controls, your script is locked
inside of that call to RXDLG. (The exception to this is RXDLG Operations that
don't perform user interaction, such as operations 2, 3, 4, and 255). When
RXDLG returns control to your script, then the user can't interact with the
windows anymore (until you again call RXDLG to perform an Operation that allows
the user to interact with the windows\controls). So, think of RXDLG as a way
for you to pass control to Rexx Dialog (and the user). When RXDLG returns, it
is passing control back to your script (and away from the user).
While Rexx Dialog has control, the user is free to manipulate the windows (and
controls within them) in any order that he wishes. (The exception to this is
for a window with its MODAL Flag set). For example, if there are 3 windows
open, the user can click upon any one of them to make it the active window, and
then activate any control inside of that window. Therefore, your script can
never make any assumptions about which window and control the user has
manipulated. Instead, Rexx Dialog will keep track of that information, and
sets some REXX variables in your script which you can then examine (after RXDLG
returns) to determine which window and control has been manipulated.
There are a number of actions the user could do which would cause RXDLG to
return (ie, and therefore return control to your script). They are:
1. If the script is launched by some application other than RX.EXE, and that
app wants the script to abort (ie, EXIT).
2. He clicks upon the CLOSE ICON of a window.
3. If the window's RESULT Flag is set, and the window itself has the focus
(ie, the window is active, but no control within it is activated), he
presses the ESC key.
4. If the window's RESULT Flag is set, and the window itself has the focus, he
presses the ENTER key.
5. The window's timeout is enabled, and the timeout expires.
6. If the window's KEYS Flag is set, and the window itself has the focus, he
presses some key on the computer's keyboard.
7. He clicks upon some button in a RESULT Group.
8. He finishes using some control that is in a Group with its END Flag set.
Before RXDLG returns control to your script, it sets up all returned variables
(ie, RXVAL, RXWIND, RXID, RXSUBID, the window's Dimensions string, etc) per the
state of this window (and its Groups). (The exception to this is RXDLG
Operations that specifically don't want the return values setup, such as
operation 4). RXDLG will also close the window that caused the return unless
the window's NOCLOSE Flag is set. (The exception to this is with KEYS
processing. Although RXDLG returns control to your script when the user
presses a key, the window is not closed, and only the variables RXID, RXSUBID,
and RXWIND are setup. Another exception is for action #1, an app indicating to
abort. In this case, only RXWIND, RXID, and RXSUBID are setup).
If the user was able to interact with more than one window during the call to
RXDLG, then your script needs to examine the RXWIND variable. This is set to
the title of the window which caused RXDLG to return. Typically, each window
would be associated with some operation that your script performs. You'd do a
SELECT on RXWIND, comparing it to the titles of all of your windows, and when
you found the match, you'd carry out the operation associated with that window.
There are 2 variables that let you determine exactly what the user did to cause
RXDLG to return (from the above list). Those variables are RXID and RXSUBID.
First, you examine RXID. If the user manipulated some control in the window,
then RXID is set to the Group number that control is within (where the first
Group is number 1). For example, if the first Group in the window contains 5
PUSH buttons, and the user pressed one of those buttons, then RXID will be 1 to
indicate that he used a control in Group 1. (This assumes that the Group has
its END Flag set so that it causes RXDLG to return). RXSUBID is set to the
control number that was manipulated in that Group (where the first control is
number 1). Let's say that he pushed the third button in that Group. RXSUBID
will be 3.
If RXID is 0 or some negative number, this indicates that what caused RXDLG to
return wasn't due to the user manipulating some control within a Group, but
rather, one of the first 6 actions listed above occurred. Both RXID and
RXSUBID are 0 if a timeout occurred (ie, the window timer timed out before any
of the other 6 actions could occur). RXID will be -98 if the window's CLOSE
ICON was clicked. RXID will be -12 if the ESC key was pressed. RXID will be
-20 if the window was resized (and you specified the NEWSIZE Flag). If the
script is launched by some application other than RX.EXE (the app must be
written to specifically use RXDLG.DLL), and that app wants the script to abort
(ie, EXIT), then RXID will be -99. If the user pressed some other key on the
keyboard, RXID will be between 0 and -11 (depending upon whether the ALT,
SHIFT, and\or CTRL keys were held down too, and whether the key is a printable
character such as "s" or unprintable such as the HOME key), and RXSUBID will
identify that particular key (as described in Keyboard Input).
Based upon RXWIND, RXID, and RXSUBID, your script will decide what operation it
wishes to perform (perhaps using the other REXX variables which were setup to
the "values" of all of the controls in the window specified by RXWIND). It's
possible that this operation could involve opening more windows and getting
even more user input. After this operation is complete, the script will either
terminate, or loop back to calling RXDLG to do some more user interaction (ie,
if you want to give the user an opportunity to repeat an operation with a new
set of input).
If the script does continually loop around, getting new sets of user input,
you'll need a method of breaking out of the loop and exiting from your REXX
script. Typical ways include checking if the user has clicked upon the Main
Window's CLOSE ICON, checking if the user has selected a "Quit" menu label (if
you add such to the window), or checking if the user has pressed the ESC key
(or pressed some key combo, or manipulated some control, that you have deemed
will be interpreted as a signal to quit the program). If your script is
launched by some app other than RX.EXE, you'll also want to check for a signal
to abort.
Refer to the RXDLG section for details on the args passed to RXDLG.
ΓòÉΓòÉΓòÉ 6.3.3. Group Types ΓòÉΓòÉΓòÉ
The next sections explain the details about each Group Type (ie, and offer a
detailed explanation of some of the variables mentioned in Groups, which can be
interpreted differently for each Group).
ΓòÉΓòÉΓòÉ 6.3.3.1. Push Button ΓòÉΓòÉΓòÉ
Type PUSH
Description A push button is a graphical, square button with the label
inside of the button itself.
A user can move the mouse pointer over the button and press (and
hold down) the mouse button. The button will visually depress
as if the mouse pointer were a finger pushing down upon the
button. When the user releases the mouse button, so too does
the mouse release the push button, and that's when it becomes
activated (ie, like a "momentary switch"). Alternately,
pressing the SPACE BAR will activate the button which currently
has the focus (ie, is highlighted).
When the user activates a push button, RXDLG returns if the END
Flag for its Group is specified.
There are a maximum of 32 buttons per Group.
Uses Push buttons are usually used to launch operations, such as to
begin a file save or load, or initiate an action such as to
create another window.
REXX Setup
RXINFO is a string specifying the TotalControls, ControlsPerLine, and
WidthOfControl. If WidthOfControl is 0, then Rexx Dialog calculates a "best
fit". If you specify a non-zero width, make sure that it is large enough or
the button's label will be visually clipped.
RXLABEL is as described in Groups. But, if a Label for a particular button is
omitted, then that button is not placed upon the display, and its number is
skipped. In this way, you can determine how you want to number the buttons
upon the display. For example, let's say that you want 3 buttons on the
display. But, you want the first button (which we'll label as "One") to be #1,
the second button ("Two") to actually count itself as #3, and the third button
("Three") to count itself as #5 (ie, you want to skip #2 and #4). You would
omit labels for buttons 2 and 4. Therefore, RXLABEL would be 'One | | Two | |
Three'. In this way, the "values" of the second and third buttons are 3 and 5.
Note that if you skip buttons, you still have to count them in RXINFO's
TotalControls. For example, here TotalControls would be 5 (ie, TotalControls
reflects how many labels you supply, not how many buttons are displayed).
Note: OS/2 REXX appears to have a bug in it regarding null strings. A null
string is supposed to simply be quotes without any characters in
between, but OS/2 REXX doesn't like this in assignments (ie, when you
assign a variable to be a null string). It likes to see at least 1
character between the quotes. So instead of myvar = '', use myvar = ' '
whenever assigning a null string to a label variable (or any other
variable that specifies a string rather than a numeric value).
RXVAL is a string specifying which button is initially selected by default.
For example, if the first button is to be selected, then RXVAL = '1'. If you
don't want any default selection, then set RXVAL to a null string (ie, ''). By
doing the latter, you can examine the return that Rexx Dialog gives for this
Group, and determine whether the user selected any button at all. Note that
you must consider any skipped values when specifying button numbers in the
RXVAL string.
RXFLAGS can be any, all, or none of the following:
'NUMBERED' Rexx Dialog automatically labels the buttons with numbers, (ie,
the first button has a label of '1', the second button is '2',
etc). Therefore, you don't have to specify any of the button
labels in RXLABEL. RXLABEL will simply be the group box label
(or a null string if no group box is desired).
'END' Causes RXDLG to return (with all RXVALs set for all Groups in
the active dialog window, including this button group) when the
user selects one of the buttons in this group.
REXX Return
Rexx Dialog returns this Group's RXVAL variable set to which button was pushed.
For example, if the second button was pushed, then RXVAL is set to '2'. Note
that if buttons were skipped, the numbering reflects that. In the above
example, if the user pushed the third button, it really has a value of 5
(because 2 and 4 were skipped), and so RXVAL is set to '5'. If you initially
specified no default, and the user never pushed any button before the dialog
window containing this group caused RXDLG to return, then RXVAL would be a null
string.
Examples
/* This creates a window called "Push Stuff" containing 1 Group of 3 push
buttons labeled "High", "Mid", "Low", with a group box labeled "Tone". Each
button appears upon its own line (ie, they are stacked in a column), ie,
ControlsPerLine=1. Rexx Dialog calculates a best fit for width of each button.
Selecting one of the buttons in this Group causes RXDLG to return (and also
causes the dialog containing these buttons to be destroyed if the dialog isn't
NOCLOSE). There is no initial default selection. */
RXTYPE.1 = 'PUSH'
/* Cause RXDLG to return */
RXFLAGS.1 = 'END'
/* NumOfControls, ControlsPerLine, WidthOfControl */
RXINFO.1 = '3 1 0'
/* Labels for buttons, and group box */
RXLABEL.1 = 'High|Mid|Low|Tone'
/* No default */
RXVAL.1 = ''
/* Position */
RXX.1 = 10
RXY.1 = 10
/* Create "Push Stuff" window */
RXDIM = '80 160 50 50'
RXDLG 1 '"Push Stuff"' 'RXDIM' 'RESULT'
/* Display the selection */
RXSAY 'Chose button #'RXVAL.1
ΓòÉΓòÉΓòÉ 6.3.3.2. Radio Button ΓòÉΓòÉΓòÉ
Type RADIO
Description A radio button is a graphical, round button that is filled in
with a different color depending upon whether the button is "on"
or "off". The label is immediately to the right of the button.
A radio button's state turns "on", and stays "on", when the user
activates it. Like the push button, the user activates a radio
button when he clicks the mouse upon it. Alternately, pressing
the SPACE BAR will activate the button which currently has the
focus (ie, is highlighted). But, only one radio button in a
group can be activated (ie, turned "on") at any given moment.
When a particular radio button is activated, any other button
that was "on" is automatically turned off, and only the newly
activated button is turned "on". In other words, only one
button is ever "on" at any given moment, and all others in the
Group are "off".
When the user activates a radio button, RXDLG returns if the END
Flag for its Group is specified.
There are a maximum of 32 buttons per Group.
Uses Radio buttons are used to allow the user to choose one (and only
one) item from several available choices. For example, there may
several radio buttons, each offering a different "paper size"
for a printing job, and the user must choose one size.
REXX Setup
Setup is exactly the same as per the Push Button Group.
REXX Return
Return is exactly the same as per the Push Button Group.
Examples
/* This creates a window called "Radio" containing 1 Group of 4 radio buttons.
Rexx Dialog labels them with numbers (ie, 'NUMBERED' Flag), so RXLABEL is the
group box label only. There are 2 buttons per line. We specify a width of 30.
Selecting a button in this Group DOESN'T cause RXDLG to return because we
didn't specify 'END' Flag. When the Group first appears, button 3 is selected
*/
RXTYPE.1 = 'RADIO'
/* Let Rexx Dialog label all of the buttons with numbers */
RXFLAGS.1 = 'NUMBERED'
/* NumOfControls, ControlsPerLine, WidthOfControl */
RXINFO.1 = '4 2 30'
/* Group box label */
RXLABEL.1 = 'Numbers'
/* Default is button 3 */
RXVAL.1 = '3'
/* Position */
RXX.1 = 10
RXY.1 = 7
/* Create "Radio" window */
RXDIM = '100 110 50 50'
RXDLG 1 '"Radio"' 'RXDIM' 'RESULT'
/* Display the selection */
RXSAY 'Chose button #'RXVAL.1
ΓòÉΓòÉΓòÉ 6.3.3.3. Checkmark Button ΓòÉΓòÉΓòÉ
Type CHECK
Description A checkmark button is a graphical, square button that is filled
in with a graphical checkmark depending upon whether the button
is "on" or "off". The label is immediately to the right of the
button.
A checkmark button's state toggles between "on" and "off" each
time that the user activates it. (ie, If it's currently "off"
when he activates it, it turns "on" and stays "on", and vice
versa). Like the push button, the user activates a checkmark
button when he clicks the mouse upon it. Alternately, pressing
the SPACE BAR will activate the button which currently has the
focus (ie, is highlighted). But, unlike radio buttons, each
checkmark's state is independent of the others in the Group.
So, all of them can be turned "on", or all of them can be turned
"off", or any combination inbetween.
When the user activates a checkmark button, RXDLG returns if the
END Flag for its Group is specified.
There are a maximum of 32 buttons per Group.
Uses Checkmark buttons are used to allow the user to choose any, all,
or no items from several available choices. For example, there
may several checkmark buttons, each offering a different style
for a font (ie, underlined, italic, boldface), and the user can
choose any/all/none of those choices to be applied to the font
simultaneously.
REXX Setup
Setup is exactly the same as per the Push Button Group, except that more than
one button can be specified for the RXVAL string. For example, if you want
checkmark buttons 1, 4, and 6 checked initially, then set RXVAL to '1 4 6'. It
doesn't matter in which order you specify the selected buttons, so '6 4 1'
would be the same as '1 6 4'.
Also, RXFLAGS has one more option:
ALLNONE Two push buttons are displayed above all of the checkmark
buttons. One push button is labeled "All". If this is pushed,
it automatically forces all of the checkmark buttons to be
selected (ie, checked). The other button is "None", and forces
all checkmark buttons to be deselected (ie, clears the checks).
REXX Return
Rexx Dialog returns this Group's RXVAL variable set to only those buttons that
are checked (ie, selected). For example, if the user selected buttons 4 and 5,
then RXVAL is '4 5'. The buttons are always ordered from lowest to highest
numbers.
Examples
/* This creates a window called "Checks" containing a Group of 3 checkmarks
labeled "Bold", "Italic", and "Underline", with no group box. There are 3
buttons per line (so all 3 are on one line). We let Rexx Dialog calculate a
best fit. Selecting a button in this Group DOESN'T cause RXDLG to return
because we didn't specify 'END' Flag. When the Group first appears, buttons 1
and 3 are selected. There are also "All" and "None" push buttons */
RXTYPE.1 = 'CHECK'
/* Add ALL\NONE push buttons */
RXFLAGS.1 = 'ALLNONE'
/* NumOfControls, ControlsPerLine, WidthOfControl (best fit) */
RXINFO.1 = '3 3 0'
/* Label for checkmarks, and group box */
RXLABEL.1 = 'Bold|Italic|Underline'
/* Check buttons 1 and 3 */
RXVAL.1 = '1 3'
/* Position */
RXX.1 = 7
RXY.1 = 7
/* Create "Checks" window */
RXDIM = '260 80 40 40'
RXDLG 1 '"Checks"' 'RXDIM' 'RESULT'
/* Display the selections (ie, more than 1 button can be selected. We need to
parse the RXVAL string to remove each selected button number, and then we
simply display its respective label */
DO UNTIL RXVAL.1 <= ''
PARSE VAR RXVAL.1 button RXVAL.1
IF button = 1 THEN RXSAY 'Chose Bold'
IF button = 2 THEN RXSAY 'Chose Italic'
IF button = 3 THEN RXSAY 'Chose Underline'
END
ΓòÉΓòÉΓòÉ 6.3.3.4. Result Button ΓòÉΓòÉΓòÉ
Type RESULT
Description A result button is a special, preset collection of push buttons.
You have a choice of labeled buttons, including OK, CANCEL, YES,
NO, RETRY, IGNORE, ON, OFF, START, or STOP. Any or all of these
buttons can be specified, and they are created upon one line.
When the user activates a result button, it always causes RXDLG
to return.
Uses Used mostly to end a dialog, after the user has set up all other
controls in the dialog window to desired values. Depending upon
which one of the result buttons was selected, the script can
then perform an operation using the values of the dialog's
controls, or abort a pending operation.
REXX Setup
RXINFO is a string containing which preset buttons to display. Here are the
values for the available buttons:
CANCEL 1
OK 2
NO 3
YES 4
ABORT 5
RETRY 6
IGNORE 7
ENTER 8
OFF 9
ON 10
STOP 11
START 12
For example, if you want the OK, CANCEL, and ABORT buttons, specify RXINFO is
set to '1 2 5'. It doesn't matter in what order you specify the button
numbers.
Note: All of the buttons normally associated with "positive" responses are
even numbers. All of the buttons normally associated with "negative"
response are odd numbers. I refer to the positive buttons as SUCCESS
buttons, and the negative buttons as FAILURE buttons.
RXLABEL is the simply the group box label (or a null string if none).
RXVAL need not be initialized.
RXFLAGS can be any, all, or none of the following:
'BOOL' Only return a 0 or 1. If the user clicks upon one of the
SUCCESS buttons, return a 1. If the user clicks upon one of the
FAILURE buttons, return a 0.
Note: It's not necessary to specify the 'END' Flag for a RESULT Group. A
RESULT Group always causes RXDLG to return.
REXX Return
Rexx Dialog returns this Group's RXVAL variable set to which button was pushed.
For example, if the NO button was pushed, then RXVAL is set to '3' (unless BOOL
Flag is specified, in which case RXVAL would be set to '0').
Note: If a dialog is created with its RESULT Flag specified, when the user
presses ESC (while the dialog has the focus), any RESULTBUTTON has its
RXVAL return set to the lowest numbered FAILURE button in the Group.
For example, if you have a NO button in the Group, RXVAL is set to '3'
(unless BOOL Flag is specified). When the user presses ENTER (while the
dialog has the focus), any RESULTBUTTON has its RXVAL return set to the
lowest numbered SUCCESS button in the Group. For example, if you have
an OK button in the Group, RXVAL is set to '2' (unless BOOL Flag is
specified, in which case RXVAL is 1).
Examples
/* This creates a window called "Result" containing a Result button Group with
OK, CANCEL, and ABORT. There is no group box */
RXTYPE.1 = 'RESULT'
/* Default */
RXFLAGS.1 = ' '
/* 1=OK, 2=CANCEL, 5=ABORT */
RXINFO.1 = '1 2 5'
/* Group box label */
RXLABEL.1 = ' ' /* Leave a space. See note on REXX bug in "Groups" */
/* Position */
RXX.1 = 7
RXY.1 = 7
/* Create "Result" window */
RXDIM = '226 60 40 40'
RXDLG 1 '"Result"' 'RXDIM' 'RESULT'
/* Display the selection */
IF RXVAL.1 = 2 THEN RXSAY 'Pressed OK'
IF RXVAL.1 = 1 THEN RXSAY 'Pressed CANCEL'
IF RXVAL.1 = 5 THEN RXSAY 'Pressed ABORT'
ΓòÉΓòÉΓòÉ 6.3.3.5. Entry ΓòÉΓòÉΓòÉ
Type ENTRY
Description A box into which the user can type and edit (using the left and
right cursor, Delete, Insert, and Backspace keys) text, or which
can display text for the user to edit.
The user clicks inside of the box, and a cursor appears (ie, the
entry gets the focus). He can then type keys and text will be
entered into the box. When he presses the ENTER key, the text
is "accepted", and the entry will cause RXDLG to return if the
END Flag is set for this Group. He can press the ESC key to
stop entering text into the entry (and return focus to the
dialog window).
Uses To obtain a line of text from the user, or present a line of
text to be edited by the user. It could be used in the same way
that a REXX PULL statement would be used, except that a dialog
can contain many entries, so that the user can choose which ones
he wants to interact with, and which he doesn't.
REXX Setup
RXINFO is a string specifying the TotalControls, ControlsPerLine, and
WidthOfControl. WidthOfControl specifies only the size of the entry box (not
any label for it too), and therefore will determine how many characters can be
displayed in the entry box simultaneously. If there are more characters in the
line than can fit into the box, the user can press the right or left cursor
keys to scroll other characters into view.
RXLABEL is as described in Groups.
RXVAL is a string specifying the name of a REXX stem variable where all of the
initial contents of the entries are stored. The variable name should be
limited to 22 characters. For example, if you set RXVAL to 'STRS', then the
first entry in the Group will be initialized to whatever the value of STRS.1 is
(ie, the string assigned to STRS.1 will be placed into the entry box when it is
created, for the user to edit). The second entry will be initialized to
whatever the value of STRS.2 is. Etc. If you don't want any text initially
placed into a particular entry (ie, you want it created empty), set its
variable to a null string. For example, if you wanted the second entry to be
blank, assign STRS.2 = ' '.
Note: OS/2 REXX appears to have a bug in it regarding null strings. A null
string is supposed to simply be quotes without any characters in
between, but OS/2 REXX doesn't like this in assignments (ie, when you
assign a variable to be a null string). It likes to see at least 1
character between the quotes. So instead of '', use ' ' whenever
assigning a null string to any variable that specifies a string rather
than a numeric value).
RXFLAGS can be any, all, or none of the following:
'END' Causes RXDLG to return (with all RXVALs set for all Groups in
the active dialog window, including this entry group) when the
ENTER key is pressed while one of the entries in this group has
the focus.
RXX reflects the position of the first entry box, not its label (which needs
room to the left of the entry in order to be displayed). Therefore, set RXX
far enough to the left to leave room for the label.
REXX Return
Rexx Dialog returns each entry's text in the same variable that was used to
fetch its text. In other words, if you specified RXVAL as 'STRS' when the
Group was created, then the first entry's text is returned in STRS.1.
Note: Currently, an entry is limited to entering 31 characters maximum. There
is a limit of 256 entries per Group, or if Labels are specified, 128
entries per Group.
Examples
/* This creates a window called "Enter Stuff" containing a group of 3 entries
with labels of "One", "Two", and "Three", and a groupbox of "All". The first
is initialized to contain "Hello", and the second and third are blank */
RXTYPE.1 = 'ENTRY'
/* Default */
RXFLAGS.1 = ' '
/* Labels for each entry, and Groupbox */
RXLABEL.1 = 'One:|Two:|Three:|All'
/* Variable name where the text "typed into" the entries is stored */
RXVAL.1 = 'TEXT'
/* TotalControls, ControlsPerLine, WidthOfControls */
RXINFO.1 = '3 3 45'
/* Position of Group */
RXX.1 = 60
RXY.1 = 16
/* The text for the 3 entries */
TEXT.1 = 'Hello'
TEXT.2 = ' '
TEXT.3 = ' '
/* Create "Enter Stuff" window */
RXDIM = '256 106 20 20'
RXDLG 1 '"Enter Stuff"' 'RXDIM' 'RESULT'
/* Display the selection for each entry */
RXSAY 'Entry One is "'TEXT.1'"'
RXSAY 'Entry Two is "'TEXT.2'"'
RXSAY 'Entry Three is "'TEXT.3'"'
ΓòÉΓòÉΓòÉ 6.3.3.6. List Box ΓòÉΓòÉΓòÉ
Type LIST
Description A box containing numerous lines of text. Each line is an "item"
that the user can select (ie, highlight). There is a scroll bar
immediately to the right which, if there are more items than can
be simultaneously displayed in the box, can be used to scroll
those other items into view. (The scroll bar is inoperable if
all of the items in the list can be simultaneously displayed in
the box). The user can select an item by clicking upon it with
the mouse. By holding the mouse button down, and moving the
mouse up and down, he can also scroll the list. Alternately,
the up and down cursor keys can be used to cursor through the
list, and the ENTER key will select an item. For multiple
select list boxes, more than one item can be selected
simultaneously. When an item is selected, its state toggles.
(ie, If the item was not selected, selecting it highlights it.
If the item was highlighted, selecting it unhighlights, or
deselects it).
Clicking the mouse twice on an item very fast (ie,
double-clicking) causes RXDLG to return if the END Flag is set
for this control's group. Alternately, pressing the ENTER key
does the same.
Uses List boxes are used to present items that a user can choose
from, much like checkmark or radio buttons, except that list
boxes use up less area if you have lots of items from which the
user can choose. Multiple select lists function like
checkmarks, and single select lists function like radio buttons.
REXX Setup
RXINFO is a string specifying the TotalControls, ControlsPerLine,
WidthOfControl, and NumVisibleItems. WidthOfControl specifies the width of the
list box, and therefore will determine how many characters of an item can be
displayed in the list box. NumVisibleItems determines how many items can be
displayed simultaneously in the list box, and therefore this determines the
height of the box.
RXLABEL is as described in Groups.
RXVAL is a string specifying the name of the REXX stem variables where all of
the initial items of each list box are stored. Each variable name should be
limited to 22 characters. Each list box has its own stem variable associated
with it. That stem variable contains all of the items that get added to that
list box. RXVAL specifies the REXX variable name for the first list box, then
the REXX variable name for the second list box, then the REXX variable name for
the third list box, etc. Each list box's variable name is separated from the
next by a | character. For example, if you set RXVAL to 'ONE|TWO|THREE', then
the first list box in the Group will be initialized to contain all of the items
starting with ONE.1, the second list box will be initialized to contain all of
the items starting with TWO.1, and the third list box will be initialized to
contain all of the items starting with THREE.1. Rexx Dialog reads items until
it comes to an item that is a null string. That marks the end of a list box's
item. For example, if you wanted to put 3 strings into the first list box;
"Hello", "Hi", and 'Goodbye", then you would set ONE.1 to 'Hello', ONE.2 to
'Hi', and ONE.3 to to 'Goodbye'. ONE.4 would be set to ' ' to mark the end of
the list.
Note: OS/2 REXX appears to have a bug in it regarding null strings. A null
string is supposed to simply be quotes without any characters in
between, but OS/2 REXX doesn't like this in assignments (ie, when you
assign a variable to be a null string). It likes to see at least 1
character between the quotes. So instead of '', use ' ' whenever
assigning a null string to any variable that specifies a string rather
than a numeric value).
RXFLAGS can be any, all, or none of the following:
'MULTIPLE' Allows more than one item to be selected simultaneously (ie,
multiple select), rather than single select.
ALLNONE This is only applicable to a multiple select list box. Two push
buttons are displayed above the list box. One push button is
labeled "All". If this is pushed, it automatically forces all
of the items in the list to be selected (ie, highlighted). The
other button is "None", and forces all items to be deselected.
If the END Flag is also set for this Group, then RXDLG returns.
There is a limit of 40 list boxes per Group if the ALLNONE Flag
is used.
INDEX Instead of returning the actual text of an item when it is
selected, Rexx Dialog returns its index number (ie, where it
appears in the list). The first item in the list has an index
of 0.
'END' Causes RXDLG to return (with all RXVALs set for all Groups in
the active dialog window, including this list box group) when an
item from a list is selected (or also unselected for multiple
select lists).
REXX Return
For single select list boxes, Rexx Dialog returns each list box's selected item
in the same variable that was used to fetch its items, but with a .0 extension.
Using the above example, the selected item for the first list box would be
returned in ONE.0, the selected item for the second list box would be returned
in TWO.0, and the selected item for the third list box would be returned in
THREE.0.
For multiple select list boxes, Rexx Dialog returns a count of how many items
were selected in the list in the same variable that was used to fetch its
items, but with a .0 extension. Using the above example, the count for the
first list box would be returned in ONE.0, the count for the second list box
would be returned in TWO.0, and the count for the third list box would be
returned in THREE.0. The selections for each list box are then returned in
compound variables (ie, a second extension is added to the variable name). For
example, the first selected item in the first list is returned in ONE.0.1, the
second selected item in the first list is returned in ONE.0.2, etc. The first
selected item in the second list is returned in TWO.0.1, the second selected
item in the second list is returned in TWO.0.2, etc.
Note: Currently, a list box item is limited to 31 characters maximum. There
is a limit of 256 list boxes per group, or if Labels are specified, 128
list boxes per Group, or if ALL\NONE push buttons are included, 40 list
boxes per Group.
Examples
/* This creates a window called "List Me" containing a Group of 1 single select
list box with a label of "One", and a groupbox of "Choices". The list box's 6
items are stored in the ONE variable. Those 6 items are "This is one", "This
is two", "This is three", "This is four", "This is five", and "This is six". */
RXTYPE.1 = 'LIST'
/* Default */
RXFLAGS.1 = ' '
/* Labels for each list box, and Groupbox */
RXLABEL.1 = 'One:|Choices'
/* Variable names where the items are stored */
RXVAL.1 = 'ONE'
/* TotalControls, ControlsPerLine, WidthOfControls, NumVisibleItems */
RXINFO.1 = '1 1 110 4'
/* Position of Group */
RXX.1 = 10
RXY.1 = 10
/* The items for list 1 */
ONE.1 = 'This is one'
ONE.2 = 'This is two'
ONE.3 = 'This is three'
ONE.4 = 'This is four'
ONE.5 = 'This is five'
ONE.6 = 'This is six'
ONE.7 = ' ' /* End of List */
/* Create "List Me" window */
RXDIM = '140 146 30 30'
RXDLG 1 '"List Me"' 'RXDIM' 'RESULT'
/* Display the selection */
RXSAY 'Selection is "'ONE.0'"'
ΓòÉΓòÉΓòÉ 6.3.3.7. Drop Box ΓòÉΓòÉΓòÉ
Type DROP
Description A combination of an ENTRY and LIST. The list is not visible
until you click the mouse upon a small arrow immediately to the
right of the entry. Then, the list drops down, and the user can
manipulate it like a list. Otherwise, if he clicks inside of
the entry box, he can then manipulate that part of it just like
an entry. Whenever an item in the list is selected, it is
automatically copied to the entry.
Clicking the mouse on an item in the list causes RXDLG to return
if the END Flag is set for this control's group. Also, pressing
the ENTER key does the same.
Uses Like a list box, this displays many choices to the user, but the
entry also gives him the opportunity to type in some text that
isn't currently in the list. So, it might be used for a
situation where you want to present some default choices to the
user, but then allow him to reject those and specify his own
choice.
REXX Setup
RXINFO is a string specifying the TotalControls, ControlsPerLine, and
WidthOfControl. WidthOfControl specifies the width of the drop box, and
therefore will determine how many characters of an item can be displayed in the
drop box.
RXVAL is exactly as in a List Box Group.
RXLABEL is as described in Groups.
RXFLAGS can be any, all, or none of the following:
SHOWLIST Instead of list box that drops down, the list box is always
visible. In this case, the RXINFO must be setup like a list box
(ie, with a NumVisibleItems parameter too).
READONLY The user cannot type anything into the entry, but must select an
item for the list. If READONLY is set, then SHOWLIST should not
be set (ie, if you don't want a drop down list and want it
readonly, just use a LIST Group). The real difference between a
READONLY DROP and a LIST is that the former takes up less area
because its list is only displayed when dropped down.
INDEX Instead of returning the actual text of a drop box item when it
is selected, Rexx Dialog returns its index number (ie, where it
appears in the list). The first item in the list has an index
of 0.
'END' Causes RXDLG to return (with all RXVALs set for all Groups in
the active dialog window, including this drop box group) when an
item from a list is selected or user types into the entry and
presses ENTER.
RXX and RXY reflect the position of the entry box of the first drop box, not
its drop down list (which needs room beneath the entry in order to "drop
down"), nor the drop box's label (which needs room to the left of the entry in
order to be displayed). Therefore, set RXX far enough to the left to leave
room for the label, and set RXY far enough above the bottom border of the
window in which the Group is placed in order for the drop boxes to have room to
drop down. The RXY variable should be 30 or more.
REXX Return
The return is exactly as in a single select List Box Group.
Note: Currently, a drop box is limited to 31 characters maximum. There is a
limit of 256 drop boxes per Group, or if Labels are specified, 128 drop
boxes per Group.
Examples
/* This creates a window called "Drop Me" containing a Group of 1 drop box with
a label of "One" and no groupbox. The drop box's list items are stored in the
ONE variable. Those 3 items are "Hello", "Hi", and "Goodbye" */
RXTYPE.1 = 'DROP'
/* Default */
RXFLAGS.1 = ' '
/* Labels for each drop box, and Groupbox */
RXLABEL.1 = 'One:'
/* Variable names where the items are stored */
RXVAL.1 = 'ONE'
/* TotalControls, ControlsPerLine, WidthOfControls */
RXINFO.1 = '1 1 90'
/* Position of Group */
RXX.1 = 40
RXY.1 = 60
/* The items for list 1 */
ONE.1 = 'Hello'
ONE.2 = 'Hi'
ONE.3 = 'Goodbye'
ONE.4 = ' ' /* End of List */
/* Create "Drop Me" window */
RXDIM = '140 104 30 30'
RXDLG 1 '"Drop Me"' 'RXDIM' 'RESULT'
/* Display the selection */
RXSAY 'Selection is "'ONE.0'"'
ΓòÉΓòÉΓòÉ 6.3.3.8. Spin Button ΓòÉΓòÉΓòÉ
Type SPIN
Description A spin button is an entry that deals with numeric values. It
consists of an entry, plus two up and down arrows immediately to
the right of the entry. The up and down arrows will cycle the
spin through its numeric range (and roll over when a lower or
upper numeric limit is surpassed). Alternately, the user can
click inside of the entry box, and type a number in just as he
would manipulate an entry. His input is checked against the
spin's upper and lower limit, and forced to fall within that
range. When the entry is activated, he can also use the up and
down cursor keys to cycle through the range.
If the user changes the numeric value of a spin (either by using
the arrow buttons, or typing a new value, or using the cursor
keys), RXDLG will return if the END Flag is set for this
control's Group.
There is a limit of 256 spin buttons per Group, or if Labels are
specified, 128 spin buttons per Group.
Uses Useful for allowing the user to specify some numeric parameter
such as how many copies of a document he would like printed.
Because the user can type a specific value into the entry, this
offers an easy way to pick out one particular value (ie, it's
easy to make fine adjustments with a spin).
REXX Setup
RXINFO is a string specifying the TotalControls, ControlsPerLine, and
WidthOfControl.
The string for RXLABEL has some extra information in addition to the labels for
all of the spin buttons in the Group, as well as the Group box label. Every
spin button has a minimum and maximum value that restricts the numeric range of
the spin. For example, you could have a spin that did not allow numbers
greater than 100 nor less than 10. The maximum and minimum limits for a
particular spin must be specified, in that order, before the spin's label. One
spin's parameters must be separated from the next spin's parameters by a |
character. So, the order of the parameters in the RXLABEL string is:
First spin's maximum limit
First spin's minimum limit
First spin's label
|
Second spin's maximum limit
Second spin's minimum limit
Second spin's label
|
etc.
Group box label
If you desire no groupbox label, simply omit it. If you desire a spin with no
label, then omit that spin's label (although you still must specify a maximum
and minimum limit).
Note: The maximum limit of a spin is limited to 255 (ie, it can span 256
different values). The low limit is 0. The limits are inclusive. That
is, if you set the low limit to 10 and the high limit to 20, then the
spin can be set to the value 10 or 20, as well as any number inbetween.
RXVAL is a string containing the initial values of all the spin buttons in the
group starting with the first. You must specify an initial value for each
spin. For example, if you have 3 spin buttons, and you want to set the first
spin initially to 30, the second spin to 5, and the third spin to 0, set RXVAL
to '30 5 0'.
Note: Don't forget to put quotes around the numeric values in the RXVAL
string. You need to specify all of numbers as one string.
RXFLAGS can be any, all, or none of the following:
'END' Causes RXDLG to return (with all RXVALs set for all Groups in
the active dialog window, including this drop box group) when an
item from a list is selected or user types into the entry and
presses ENTER.
RXX reflects the position of the entry box of the first spin, not its label
(which needs room to the left of the entry in order to be displayed).
Therefore, set RXX far enough to the left to leave room for the label.
REXX Return
Rexx Dialog sets the Group's RXVAL string to contain the current values of all
the spin buttons in the group, starting with the first.
Examples
/* This creates a window called "Spin Me" containing a Group of 1 spin button,
labeled "Range:" with a group box labeled "Value". The spin has a max limit
of 20 and a min limit of 10, and is initially set to 19. */
RXTYPE.1 = 'SPIN'
/* Default */
RXFLAGS.1 = ' '
/* Max, Min, Label for each slider, and groupbox */
RXLABEL.1 = '20 10 Range:|Value'
/* Values for each spin */
RXVAL.1 = '19'
/* TotalControls, ControlsPerLine, WidthOfControls */
RXINFO.1 = '1 1 70'
/* Position */
RXX.1 = 80
RXY.1 = 18
/* Create "Spin Me" window */
RXDIM = '190 86 30 30'
RXDLG 1 '"Spin Me"' 'RXDIM' 'RESULT'
/* Now display the value the spin. Since there's only 1 in this Group, we
don't need to parse the RXVAL string for the Group to extract the spin's value
*/
RXSAY 'value =' RXVAL.1
ΓòÉΓòÉΓòÉ 6.3.3.9. Slider ΓòÉΓòÉΓòÉ
Type SLIDER
Description Like a spin, the slider also deals with numeric values. A
slider has a shaft, and a knob that can be "grabbed" with the
mouse (ie, place the mouse pointer over the knob, and press and
hold down the mouse button) and moved along the shaft. The
numeric value of the slider will change as the knob moves, with
the far left position being 0 and the far right position being
the maximum range of the slider. Alternately, when a slider has
the focus (ie, its knob has a black dot on it), the knob can be
moved with the left and right cursor keys. There are also two
arrows immediately to the right of the shaft, which can be used
to adjust the value in fine amounts (ie, single steps).
Alternately, if the mouse is clicked to either side of the knob
(but not on the knob itself), the value will increment or
decrement (depending upon which side of the knob the mouse was
clicked). The slider may also have a "detent", which is a small
black marker above the shaft, which if the user clicks upon,
forces the knob to jump to that position.
If the user changes the value of a slider (either by moving and
releasing the knob, pressing the ENTER key when the knob is
highlighted, clicking upon the arrows, clicking to either side
of the knob, or clicking upon a detent), RXDLG will return if
the END Flag is set for this control's group.
There is a limit of 256 sliders per Group. If Labels are
specified, there is a limit of 128 sliders per Group. If values
are printed out, then there is a limit of 64 sliders per Group.
Uses Allows the user to cycle through a wide range of numeric values
very quickly, albeit hard to pinpoint specific settings, and
therefore is more appropriate to use for setting parameters
where very fine adjustments aren't as important as being able to
quickly cycle through a large range.
REXX Setup
RXINFO is a string specifying the TotalControls, ControlsPerLine, and
WidthOfControl. The WidthOfControl must be wide enough for OS/2 to have enough
pixel resolution to display the range of values (ie, steps) that you want the
slider to encompass. If the width is not wide enough to accomodate the range
of values, then OS/2 will not display the slider shaft. Only the knob may be
visible, and subsequent updating of the slider display will be bizarre to say
the least. PM's slider needs fixing.
The string for RXLABEL has some extra information in addition to the labels for
all of the sliders in the Group, as well as the Group box label. Every slider
button has a value that determines how many steps the slider can move (ie, its
range of values). For example, you could have a slider that could be set to
one of 20 different steps. Also, a slider may have a detent. The NumOfSteps
and Detent for a particular slider must be specified, in that order, before the
slider's label. One slider's parameters must be separated from the next
slider's parameters by a | character. So, the order of the parameters in the
RXLABEL string is:
First slider's NumOfSteps
First slider's Detent
First slider's label
|
Second slider's NumOfSteps
Second slider's Detent
Second slider's label
|
etc.
Group box label
If you desire no groupbox label, simply omit it. If you desire a slider with
no label, then omit that slider's label (although you still must specify
NumOfSteps and Detent). If you desire no Detent, then set Detent to 255.
The Detent value is not in terms of steps, but rather pixels from the left of
the slider shaft. Therefore, if the slider WidthOfControl is 128, and you wish
to place a Detent halfway across the slider, then set Detent to 64.
Note: The maximum range of a slider is 0 to 254 (ie, 255 steps). The
NumOfSteps setting is exclusive. That is, if you set NumOfSteps to 20,
then the slider can be set to a value from 0 to 19 (ie, a total of 20 steps).
RXVAL is a string containing the initial values of all the sliders in the group
starting with the first. You must specify an initial value for each slider.
For example, if you have 3 sliders, and you want to set the first slider
initially to 30, the second slider to 5, and the third slider to 0, set RXVAL
to '30 5 0'.
Note: Don't forget to put quotes around the numeric values in the RXVAL
string. You need to specify all of numbers as one string.
RXFLAGS can be any, all, or none of the following:
'VALUE' Automatically prints out the current value of the slider to the
right of the shaft.
'END' Causes RXDLG to return (with all RXVALs set for all Groups in
the active dialog window, including this drop box group) when an
item from a list is selected or user types into the entry and
presses ENTER.
RXX reflects the position of the shaft of the first slider, not its label
(which needs room to the left of the shaft in order to be displayed).
Therefore, set RXX far enough to the left to leave room for the label.
REXX Return
Rexx Dialog sets the Group's RXVAL string to contain the current values of all
the sliders buttons in the group, starting with the first.
Examples
/* This creates a window called "Slide Me" containing a Group of 1 slide
button, labeled "Range:" with a group box labeled "Value". The slider has 20
steps, a detect at 45 (ie, in the center), and is initially set to 12 */
RXTYPE.1 = 'SLIDER'
/* Print value as slider moves */
RXFLAGS.1 = 'VALUE'
/* NumOfSteps, Detent, Label for each slider, and groupbox */
RXLABEL.1 = '20 45 Range:|Value'
/* Values for each slider */
RXVAL.1 = '12'
/* TotalControls, ControlsPerLine, WidthOfControls */
RXINFO.1 = '1 1 90'
/* Position */
RXX.1 = 80
RXY.1 = 18
/* Create "Slide Me" window */
RXDIM = '230 86 30 30'
RXDLG 1 '"Slide Me"' 'RXDIM' 'RESULT'
/* Now display the value of the slider. Since there's only 1 in this Group, we
don't need to parse the RXVAL string for the Group to extract the slider's
value */
RXSAY 'value =' RXVAL.1
ΓòÉΓòÉΓòÉ 6.3.3.10. Text ΓòÉΓòÉΓòÉ
Type TEXT
Description This merely displays phrases of text. A phrase is any number of
words and punctuation that is not broken by a line feed. The
user can't edit nor select the text in any way. It's simply for
the purpose of displaying text in a window.
There is a limit of 256 phrases per Group.
A TEXT Group can't cause RXDLG to return.
Uses Can be used to display instructions, or label things in a
window, or display some message to the user.
REXX Setup
RXINFO is a string specifying the TotalPhrases, PhrasesPerLine, and
WidthOfPhrase, and SpaceBetweenPhrases. SpaceBetweenPhrases is only effective
if PhrasesPerLine is greater than 1 (ie, you're putting more than one phrase on
a line). In this case, SpaceBetweenPhrases allows you to evenly space out the
phrases, which is handy if you need to make columns of data (where
SpaceBetweenPhrases would be the space between columns). If you're going to
place more than one phrase upon a line, then SpaceBetweenPhrases should be 8 or
more. If WidthOfPhrase is 0, then Rexx Dialog automatically sets up all of the
phrases to be as wide as the longest phrase, which ensures that no phrase will
be visually clipped. Otherwise, if you specify a WidthOfPhrase, make sure that
is wide enough to accomodate the widest phrase. WidthOfPhrase is limited to
255 pels maximum. (If you need to set a wider default, use RXSET's SIZE
command after creating the Group). If you're going to be changing a phrase
later with the RXSET command, then either make sure that you aren't going to
change it to some phrase that is wider than the widest original phrase in the
group, or specify a WidthOfPhrase to accomodate any changes that will be made
to the phrase, or use RXSET's SIZE command to size a particular phrase as
desired (the 255 pel limit does not apply to RXSET's SIZE command).
The string for RXLABEL contains all of the phrases in the Group, as well as the
Group box label. Each phrase is separated from the next by a | character. The
group box label is last (or omitted if no group box is desired). If you want a
blank area where a phrase would go (this would be a blank line if
PhrasesPerLine=0), then simply put a space where that phrase would be
specified.
RXVAL is not used, and need not be initialized.
RXFLAGS can be any, all, or none of the following:
'CENTER' Each phrase is centered relative to the other phrases on lines
above or below.
'RIGHT' All phrases are aligned along the right margin.
Note: If neither RIGHT nor CENTER flags are specified, then all
phrases are aligned along the left margin.
REXX Return
None. A TEXT Group doesn't interact with the user in any way, nor does it
cause RXDLG to return.
Examples
/* This creates a window called "Text" containing 1 TEXT Group with 3 lines of
centered text with a groupbox */
RXTYPE.1 = 'TEXT'
/* Center the text */
RXFLAGS.1 = 'CENTER'
/* Text lines */
RXLABEL.1 = 'PLEASE READ!|This is a REXX example of|centered text.|Text Stuff'
/* TotalPhrases, PhrasesPerLine, WidthOfPhrase, BetweenPhrases. Note: because
we want WidthOfPhrase and BetweenPhrases to be 0, then we can omit both args.
Rexx Dialog sets omitted args to 0 */
RXINFO.1 = '3 1'
/* Position */
RXX.1 = 10
RXY.1 = 10
RXDIM = ' '
RXDLG 1 '"Text"' 'RXDIM' 'SIZE|RESULT'
ΓòÉΓòÉΓòÉ 6.3.3.11. Group Box ΓòÉΓòÉΓòÉ
Type GROUP
Description This is a rectangular box, within which other controls can be
placed. The box can have its own label, which usually pertains
to whatever is the purpose of the controls within the box.
A group box can't cause RXDLG to return.
Uses Identifies controls that "belong together" usually because they
are all related to one operation.
REXX Setup
A GROUP Type only describes one group box. In other words, it isn't a group of
group boxes. You can have more than 1 GROUP in a window, but of course, you'll
have to specify each separately.
RXINFO is a string specifying the Width and Height of the group box (in
pixels).
RXLABEL is the label for the group box (or a null string if no label desired,
ie, the group box is simply a rectangular box).
RXVAL is not used, and need not be initialized.
RXFLAGS is not used, and should be set to a null string.
Note: A GROUP must be specified before any of the controls that will be
displayed inside of it, otherwise the group box will draw over those
controls and visually wipe them from the display.
REXX Return
None. A GROUP doesn't interact with the user in any way, nor does it cause
RXDLG to return.
Examples
/* This creates a window called "Group" that contains a GROUP box */
RXTYPE.1 = 'GROUP'
/* Default */
RXFLAGS.1 = ' '
/* Label */
RXLABEL.1 = 'Everything'
/* Width, Height */
RXINFO.1 = '240 220'
/* Position */
RXX.1 = 6
RXY.1 = 6
RXDIM = ' '
RXDLG 1 '"Group"' 'RXDIM' 'SIZE|RESULT'
ΓòÉΓòÉΓòÉ 6.3.3.12. Menu ΓòÉΓòÉΓòÉ
Type MENU
Description A menu attaches to the titlebar of the window, and will drop
down when the user clicks the mouse on a Menu Heading in the
titlebar (ie, the menu attached to that Menu Heading drops
down). The user can then make selections with the mouse.
Alternately, if the menus have "mnemonic keys", those keys can
be used to open and select menu items.
Note: There must only be 1 MENU Group per window, and there is
a limit of 256 Labels in a menu.
Uses Operations that can be arranged into groups lend themselves well
to being put into a menu. For example, all file load and save
operations may be placed into a menu with a heading of "File".
REXX Setup
RXINFO is a string specifying the TotalMenus (ie, total Menu Headings), and
then the REXX stem variable names (where the menu labels are fetched) for all
of the menus (headings). Each variable name is separated from the next by a |
character. If TotalMenus is 0, then an "empty" menu is created, and the
variable names do not need to be supplied. This is more memory efficient if
you plan upon using the RXSET ADD Operation to later create a new menu bar.
Note: Placing a ~ character before some letter in a Label, means that, when
the menu is displayed, pressing that letter on the keyboard activates
the menu item\subitem associated with that label. This is a mnemonic.
RXLABEL need not be initialized.
RXVAL need not be initialized.
RXFLAGS can be any, all, or none of the following:
'HELP' A "Help" menu is automatically added to the end of the menu bar,
containing 4 Help Items labeled "Help index", "General Help",
"Using Help", and "Keys Help". Whenever the user selects one of
these Items, Rexx Dialog automatically handles this (ie, and
RXDLG doesn't return) by displaying an appropriate panel in any
help file attached to the window. See RXHELP. The Help File
that you write should have a panel with the name KEYS that lists
any keyboard commands for the program. If there are no such
keyboard commands, then do not name any panel KEYS.
REXX Return
RXID is the Group number for this MENU Group (ie, if the MENU Group is the
First Group in the window, then RXID is 1). RXSUBID is the menu label number.
This will depend upon which item or subitem was chosen. The menu labels are
numbered from top to bottom, and left to right. For example, assume that you
have w Menu Headings labeled "File" and "Edit". "File" has 2 items labeled
"Open" and "Save". The first item ("Open") has 2 subitems labeled "All" and
"Excerpt". Here's how the menu would look displayed:
ΓòÆΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòò ΓòÆΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòò
Γöé File Γöé Γöé Edit Γöé
Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñΓòÆΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòò
Γöé Open->ΓöéΓöéAll Γöé
Γöé Save ΓöéΓöéExcerptΓöé
ΓòÿΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓò¢ΓòÿΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓò¢
"File" is label 1. "Open" is label 2. But, since "Open" has two subitems, we
count those before moving on to "Save". So, "All" is label 3, and "Excerpt" is
label 4. "Save" is label 5. That's all of the items\subitems in the first
menu, so moving on to the next menu, "Edit" is label 6. The first item in the
"Edit" menu would be label 7. Etc.
If you specify the HELP Flag, then the first 5 label numbers correspond to the
Help Heading, and the 4 Help Items, "Help index", "General Help", "Using Help",
and "Keys Help", even though the Help menu appears last on the menu bar.
Therefore, the menu label that actually appears on the left side of the menu
bar is label number 6. So, if we had a HELP menu in the above example, then
the label numbering would be changed to be "File" = 6, "Open" = 7, "All" = 8,
"Excerpt" = 9, "Save" = 10, and "Edit" = 11.
Examples
The REXX stem variable for a particular menu is setup such that a stem of 0 is
assigned the heading of the menu. Subsequent stems starting at 1 are the item
labels. A null string must mark the end of the items. For example, if you
have a menu with a heading of "File" and 2 items labeled "Item 1" and "Item 2",
and the REXX variable name you supplied in the RXINFO string is 'MENU', then
here is the setup:
/* Menu Structure */
MENU.0 = 'File' /* Heading */
MENU.1 = 'Item 1' /* First Item */
MENU.2 = 'Item 2' /* Second Item */
MENU.3 = ' ' /* End of Items */
If an item has any subitems, the number of subitems should be placed after that
item's label, separated by a | character. The labels for those subitems are
assigned to compound variables where an extra stem is added to the item's
variable name. The extra stem is the subitem number, starting with 1.
For example, if "Item 1" had 2 subitems labeled "Sub 1" and "Sub 2":
/* Menu Structure */
MENU.0 = 'File' /* Heading */
MENU.1 = 'Item 1|2' /* First Item, # of subitems */
MENU.2 = 'Item 2' /* Second Item */
MENU.3 = ' ' /* End of Items */
MENU.1.1 = 'Sub 1' /* First SubItem for Item 1 */
MENU.1.2 = 'Sub 2' /* Second SubItem for Item 1 */
As a further example, assume "Item 2" had 1 subitem labeled "hello":
/* Menu Structure */
MENU.0 = 'File' /* Heading */
MENU.1 = 'Item 1|2' /* First Item, # of subitems */
MENU.2 = 'Item 2|1' /* Second Item, # of subitems */
MENU.3 = ' ' /* End of Items */
MENU.1.1 = 'Sub 1' /* First SubItem for Item 1 */
MENU.1.2 = 'Sub 2' /* Second SubItem for Item 1 */
MENU.2.1 = 'hello' /* First SubItem for Item 2 */
ΓòÉΓòÉΓòÉ 6.3.4. The TAB key ΓòÉΓòÉΓòÉ
Pressing the TAB key causes the focus (ie, which control is active) to switch
to the next control in the window (regardless of whether the next control is
within the same Group as the control that currently has the focus). This
allows using the computer keyboard to select which control is active. In
conjunction with the ENTER and SPACE BAR (for buttons and multiple select
lists), any control can be activated, manipulated, and then selected without
requiring a mouse.
Holding down the CTRL key while pressing TAB causes the focus to jump to the
first control of the next Group within a window. This allows quickly jumping
from Group to Group.
If no control has the focus (ie, the window itself has the focus), then
pressing the TAB key causes the focus to jump to the first control of the first
Group.
Even if the END flag is set for a Group, when the user switches the focus from
a control in that Group, RXDLG does not return. Therefore, it's possible for
the user to select various controls via the TAB key, changing their values, and
never having to cause RXDLG to return. In order to have a control (in a Group
with its END Flag set) cause RXDLG to return, the user must explicitly indicate
that he is done manipulating the control (for example, he has to press the
ENTER key when he's done entering text into an ENTRY. If he instead presses
TAB to switch to another control, RXDLG doesn't return for that ENTRY).
ΓòÉΓòÉΓòÉ 6.3.5. NOCLOSE Flag ΓòÉΓòÉΓòÉ
There are a few reasons why you may want to specify NOCLOSE when creating a
window.
Let's assume that you want to get input from the user, perform some operation
using that input, and then get some more of the same type of input from the
user. You could open a window without NOCLOSE, and when RXDLG returns, it will
have returned the user input and closed the window. You could then perform the
operation, and subsequently call RXDLG to reopen the same window. Here's an
example of that approach:
/* =============== Create "Main Window" ================= */
/* Just put 1 Group of checkmark buttons in it */
RXTYPE.1 = 'CHECK'
RXFLAGS.1 = 'NUMBERED'
RXLABEL.1 = 'Pick one'
RXINFO.1 = '16 4 0'
RXVAL.1 = '1'
RXX.1 = 10
RXY.1 = 10
RXWIN1 = ' '
here:
/* Don't specify NOCLOSE */
RXDLG 1 '"Main Window"' 'RXWIN1' /* No Flags arg needed, as there's nothing to
specify */
/* Now we use RXDLG's second template to perform user interaction. No window or
operation arg means "Use Main Window" and "Operation 0" (ie, perform user
interaction, but don't clear any NOCLOSE Flag -- not applicable here since we
never set that flag anyway) */
RXDLG
/* The window is now closed */
/* At this point, we examine the REXX return values, and perform some
operation. Then we jump back to "here" */
SIGNAL here
In the above example, the window would be opening and closing for each
iteration. What if you wanted the window to stay open until you had completed
as many iterations as desired? Well, that's where NOCLOSE comes in. Here's
the revamped version (from the label "here" -- everything up to that point
remains the same):
here:
/* Specify NOCLOSE, so RXDLG doesn't close the window when it returns */
RXDLG 1 '"Main Window"' 'RXWIN1' 'NOCLOSE'
more:
/* Now we need to use RXDLG's second template to perform user interaction. No
window or operation arg means "Use Main Window" and "Operation 0" (ie, perform
user interaction, but don't tell Rexx Dialog that it's OK to close the window)
*/
RXDLG
/* The window is still open */
/* At this point, we examine the REXX return values, and perform some
operation. Then, we can jump back to the label "more" to do more user
interaction. We don't jump back to "here" because we don't need to open the
window again */
SIGNAL more
Another reason to use NOCLOSE is if you have a Group which you want to cause
RXDLG to return (ie, you specified the 'END' Flag for the Group), but you don't
want that to cause the window to be closed. For example, maybe each checkmark
button in the above group causes the REXX script to turn on/off something, and
you want this action to be performed in realtime. (ie, As soon as the user
selects a checkmark, turning it on or off, you want control to return to the
REXX script so that you can carry out that operation immediately. Therefore,
you have to specify the END Flag for the Group, because otherwise, RXDLG
wouldn't return after each click on a checkmark -- it would only return when
the user clicked on the CLOSE ICON for the window). But, you don't want the
window to close down everytime that he clicks on a checkmark in that Group
either. So, you need to specify NOCLOSE too.
ΓòÉΓòÉΓòÉ 6.3.6. MODAL Flag ΓòÉΓòÉΓòÉ
Normally, the WindowTitle arg for the second template of RXDLG will either be
omitted (if also doing an Operation of 0), or specified as a pair of double
quotes inside of single quotes (ie, '""') meaning that you wish Rexx Dialog to
initiate user interaction upon the window that was active during the previous
call to RXDLG.
There may be times when you have multiple windows open, but you want to force
the user to interact with only one of the windows (ie, disable interaction with
the other windows). You do this by specifying the MODAL Flag when you create
the window, and then passing that window's title to RXDLG when doing an
Operation that performs user interaction (ie, 0 or 1). Rexx Dialog will
disable all other windows (and any controls in the Main Window). The user must
interact with only that window (although he is allowed to minimize or resize
the Main Window, and perhaps switch to another app). Only when that window is
destroyed will this "Modal State" also be ended.
Note: The Main Window can't be made MODAL.
By making Child Dialogs modal, and then passing the title of the specific
window that you wish to be the "active" window to RXDLG, you can control the
user's interaction with multiple open windows.
ΓòÉΓòÉΓòÉ 6.3.7. Opening windows within a message loop ΓòÉΓòÉΓòÉ
For windows that are going to be open during the life of your script, you
normally will make a series of calls to RXDLG, using the first template, to
create all of those windows. Then, after all windows are open, you'll drop
into a "message loop" around a call to RXDLG using its second template to do
user interaction upon the windows.
But, you can call RXDLG, using the first template, to create new windows at any
time, including within that message loop. For example, you could have a button
in the Main Window which causes RXDLG to return. When your message loop
detects that this button in Main Window has been pressed, you could call RXDLG
to create a new window. But, your message loop should also contain
instructions to specifically handle any situation where RXWIND is returned as
the name of that new window. After all, that will be one more open window that
the user can choose to interact with.
ΓòÉΓòÉΓòÉ 6.3.8. A message loop within a message loop ΓòÉΓòÉΓòÉ
Let's assume that you have a button in the Main Window labeled "Players names"
which causes RXDLG to return. When your message loop detects that this button
in Main Window has been pressed, you want to call RXDLG to create a new window
with an ENTRY for the user to type in some person's name. Each time that the
person types in a name, you want to add this to a stem variable, clear the
ENTRY, and let him type in another player's name. During this entire process,
you want to prevent him from interacting with other windows. When he finally
enters a blank name, or clicks upon the window's CLOSE ICON, then you'll close
the window, and return to allowing the user to interact with whatever other
windows are open at his discretion. For that ENTRY window, you'll make it
MODAL, and then do what appears to be a message loop (on that MODAL window)
inside of the larger message loop.
/* =============== Create "Main Window" ================= */
/* Just put 1 Push button in it */
RXTYPE.1 = 'PUSH'
RXFLAGS.1 = 'END'
RXLABEL.1 = 'Players names'
RXINFO.1 = '1 1 0'
RXVAL.1 = '1'
RXX.1 = 10
RXY.1 = 10
RXWIN1 = ' '
RXDLG 1 '"Main Window"' 'RXWIN1' 'NOCLOSE'
/* Perhaps open more windows now... */
/* Put any window's Dimensions strings outside of the message loop so it only
gets initialized once */
RXWIN2 = '150 70 50 50'
more:
/* Do user interaction upon main (and any other open) windows */
RXDLG
/* Did the user click on the Main Window's CLOSE ICON? If so, end the program
*/
IF RXID < 0 THEN DO
IF RXWIND = 'Main Window' THEN EXIT
END
ELSE SELECT
WHEN RXWIND = 'Main Window' THEN DO
/* There's only 1 button in Main, so don't bother checking RXID and RXSUBID
*/
/* Open that Child Dialog with the ENTRY. NOCLOSE and MODAL */
RXTYPE.1 = 'ENTRY'
RXFLAGS.1 = 'END'
RXLABEL.1 = 'Name:'
RXINFO.1 = '1 1 60'
RXVAL.1 = 'TEXT'
RXX.1 = 50
RXY.1 = 10
TEXT.1 = ' '
RXDLG 1 '"Player Name"' 'RXWIN2' 'NOCLOSE|MODAL'
/* Get the next name */
name = 1
DO WHILE name > 0
RXDLG '"Player Name"'
/* Did the user click on window's CLOSE ICON? If so, return to main loop
*/
IF RXID < 0 | TEXT.1 = 0 THEN DO
RXDLG '"Player Name"' 4
name = 0
END
ELSE DO
NAMES.name = TEXT.1
name = name + 1
RXSET '"Player Name"' 1 1 'VAL'
END
END
END
END
/* Go back to the "main" message loop */
SIGNAL more
ΓòÉΓòÉΓòÉ 6.4. RXERR ΓòÉΓòÉΓòÉ
Template RXERR Flags
Description This command controls whether Rexx Dialog automatically displays
error message boxes when an error occurs (as a result of calling
some Rexx Dialog command). It also controls whether error
messages or error numbers are returned to a script. Sometimes,
it's easier for a script to deal with error numbers rather than
messages when trying to recover from some error situation. If
Rexx Dialog is allowed to automatically display, this also
controls whether just the error message is displayed, or whether
the line number and REXX source where the error occurred is also
displayed in a message box.
RXERR can be called at any time. (ie, You can change the error
behavior at any time via a call to RXERR).
Args
Flags A string that describes the various display and control options
for error returns. You can specify any or all of these Flags,
and each one must be separated by a | character, enclosed in
quotes. The various Flags are:
NUM Return error numbers instead of error messages. For example, if
you pass the title of a window that isn't open to RXDLG (ie,
using its second template), then RXDLG will return, setting the
special variable RC to error number 10011 rather than the
message "Can't find Rexx Dialog.".
FULL If Rexx Dialog is automatically displaying error messages for a
particular error number, then you want the line number and REXX
source where the error occurred to also be displayed. (Without
this flag, Rexx Dialog displays only the error message).
A display level (ie, numeric arg) can also be specified. Rexx Dialog displays
error messages for all errors that have a display level less than or equal the
specified level. If display level is 0, then Rexx Dialog never displays error
messages (having to do with calls to Rexx Dialog functions -- the REXX
Interpreter may still present message boxes for such things as syntax errors,
etc). If display level is not specified, then Rexx Dialog will display any
error message having to do with a Rexx Dialog function.
Note: A particular error's display level is simply the rightmost two digits of
the error number. For example, the "Can't find Rexx Dialog" error has
an error number of 10011. It's display level is therefore 11. If you
specify a display level of 10 to RXERR, then Rexx Dialog will not
automatically display the "Can't find Rexx Dialog" error message (nor
any error messages with higher display levels). See Errors for details
on the error number for all Rexx Dialog error messages.
It doesn't matter in which order flags are specified.
When you specify FULL, any Rexx Dialog errors that are to be automatically
displayed generate a REXX FAILURE condition. Otherwise, Rexx Dialog errors
generate a REXX ERROR condition.
Returns
None
Examples
/* This specifies that Rexx Dialog is not to display any error messages (ie,
display level is 0), and is to return error numbers for RC */
RXERR 'NUM|0'
ΓòÉΓòÉΓòÉ 6.5. RXFILE ΓòÉΓòÉΓòÉ
Template RXFILE Type FilenameVar ButtonLabel '|' Title
Description This command presents the OS/2 File Dialog, whereby the user can
pick out a filename (complete with path), which is returned to
the script.
The File Dialog will open on the Desktop if there are no windows
open. Otherwise, it will open in the Main Window, and will be a
modal dialog (ie, user can't interact with any windows until the
File Dialog is dismissed).
Args
Type is either 'LOAD' or 'SAVE'. If 'LOAD', then the user is allowed to click
upon a filename in the list of files in the displayed directory, and that
selection is copied to the filename entry. If 'SAVE', the user can't click
upon a filename in the list. The list is just for reference, and the user must
manually type in the desired name. The latter scheme makes it more difficult
to accidentally click on an existing file, which would be dangerous for a save
operation.
FilenameVar is the name of the REXX variable where the filename will be
returned. Before the call to RXFILE, this must be initialized with a file or
path name in order to bring up the File Dialog displaying the contents of that
directory. For example, assume that FilenameVar will be RXNAME. Setting
RXNAME to 'C:\OS2\*.exe' will display all of the files in the 'C:\OS2'
directory that end in an '.exe' extension. If you want to display all files in
a directory then use '*.*', for example 'C:\OS2\*.*'. If you want to display
the current directory, with no filtering, then set the variable to a null
string (ie, ' ').
ButtonLabel is a string that you want displayed in the "OK" button of the File
Dialog. If omitted, the default string is "OK".
Title is the string that you want displayed in the titlebar of the File Dialog.
If omitted, then the titlebar is blank. If this is specified, you must place a
| character in quotes inbetween the ButtonLabel and Title. (It's ok to omit
any ButtonLabel before the | character, if desired).
Returns
If Rexx Dialog is returning strings (ie, the NUM flag has not been specified to
RXERR), then a null string '' is returned if the user clicked upon the "OK"
button to end the dialog. "Cancel" is returned if the user clicked upon the
CANCEL button to end the dialog. (The CANCEL button does not raise a REXX
FAILURE or ERROR, nor does it automatically display an error message, so you
must explicitly check the RC return of RXFILE in order to determine if the user
cancelled the filename selection. If Rexx Dialog is returning numbers, then 0
is OK, and 350 is CANCEL.
This may return other errors as described in Errors, which raise a REXX FAILURE
or ERROR.
If an OK selection, the filename is returned in the REXX variable specified by
the FilenameVar arg. This will be a fully qualified filename (ie, with the
drive and directory too).
Examples
/* This gets a filename selection and checks for 'OK' selection */
/* Store the filename in the variable FN. Initialize it to '*.cmd' in order to
initially display all filenames in the current directory that end in '.cmd' */
FN = '*.cmd'
RXFILE 'LOAD' 'FN' 'Load Me|' 'This is the title'
IF RC = '' THEN DO /* check for 0 if Rexx Dialog returning numbers */
/* Do some operation with the filename in FN */
END
ΓòÉΓòÉΓòÉ 6.6. RXHELP ΓòÉΓòÉΓòÉ
Template RXHELP 'CREATE' WindowTitle HelpFilename
RXHELP 'FREE' WindowTitle
RXHELP Panel WindowTitle
Description This command attaches or detaches an OS/2 Help file to a window,
and then can to be used to display a help "panel" from that help
file (ie, page within the book). It has 3 templates depending
upon whether you want to attach a help file, detach a help file,
or display a panel within a help file.
RXHELP uses OS/2's Information Presentation Manager Facility.
For example, this book that you're reading is an example of IPF.
You use OS/2's Information Presentation Facility Compiler,
IPFC.EXE, to create a .HLP file (ie, write a script with the
imbedded IPF "tags" and compile it into a HLP file). Then, you
can attach such a file to a window using RXHELP.
Each window can have a different HLP file attached to it. Only
one help file can be attached to a given window.
Note: You can attach a help file to a window, and then later
attach a different help file to that same window. But,
if there are any Child Dialogs that share the same help
file as the Main Window (ie, you didn't supply the
HelpFilename arg when attaching a help file to the Child
Dialog), then you should do a 'FREE' upon those Child
Dialogs before ever changing the Main Window's help file.
Args
If the first template is being used (ie, first arg is 'CREATE'), then this
attaches a Help file to a window. If HelpFilename is omitted, then it doesn't
attach a new file, but instead shares the same help file that is attached to
the Main Window. Otherwise, this attaches the specified HelpFilename (ie, the
name of some OS/2 Help file) to the window whose title matches WindowTitle.
WindowTitle must be enclosed in quotes if there are spaces within the window
title. If WindowTitle is a null string (ie, use '""'), then the Main Window
will be the one to which the help file is being attached. You can call
'CREATE' at any time to change the help file attached to a window. You do not
need to 'FREE' a previous help file, except as noted above for Child Dialogs
that share the Main Window, when you wish to subsequently change the Main
Window's help file.
If the second template is being used (ie, first arg is 'FREE'), then this
detaches a Help file from the window whose title matches WindowTitle.
WindowTitle must be enclosed in quotes if there are spaces within the window
title. If WindowTitle is a null string (ie, use '""'), then any help file is
detached from the Main Window. 'FREE' only ever needs to be done as noted
above.
If the third template is being used, Panel is the panel number or name within
the help file that you want displayed. Panel must be enclosed in quotes if
there are spaces within the panel name. WindowTitle is the window whose help
file is to be used to find the panel. WindowTitle must be enclosed in quotes
if there are spaces within the window title. If WindowTitle is omitted, the
Main Window is used.
Note: The name of a panel should not start with a numeric character, although
these may appear later in the name. Also, you must not name a panel
such that the first 4 letters are CREA or FREE.
Returns
This may return some errors as described in Errors.
Examples
/* This attaches the file "test.hlp" (in the current dir, or along the help
path) to a window named "Main", and brings up a panel named "INFO" */
RXHELP 'CREATE' 'Main' 'test.hlp'
RXHELP 'INFO' 'Main'
ΓòÉΓòÉΓòÉ 6.7. RXQUERY ΓòÉΓòÉΓòÉ
Template RXQUERY WindowTitle
Description This command returns (in the special REXX variable RC) a 0 if
the passed WindowTitle does not match an open window, or 1 if a
window with that title is open. This can be used to check
whether a particular window is open.
Args
WindowTitle is a string to match with the title of any open window. This must
be enclosed in quotes if there are spaces within the window title.
Returns
0 if the specified window is not open, or 1 if that window is open.
Examples
/* This gets the version and revision numbers and displays each separately */
RXVERS
rev = RC
PARSE rev ver rev
RXSAY 'Version = 'ver
RXSAY 'Revision = 'rev
ΓòÉΓòÉΓòÉ 6.8. RXSAY ΓòÉΓòÉΓòÉ
Template RXSAY Message '|' Type Heading
Description This command pops up a message box on the Desktop, displaying
the text that you specified after the RXSAY command keyword.
There will be one or more push buttons that the user can click
the mouse upon in order to manually dismiss the message box.
The box remains displayed, and your script is suspended, until
the user dismisses that box, at which time your script resumes
its processing (on the next REXX line after the call to RXSAY).
Use this instead of the REXX standard SAY command. The SAY
command won't display anything because the REXX script isn't
being run from an OS/2 Command Prompt window, (and that's where
the standard SAY command tries to send its output, with the net
result that the output gets discarded). In fact, you can't use
the PULL nor PARSE PULL commands either, or any other REXX
standard command that tries to get input or output from a
command line. But then, that's why Rexx Dialog exists --
because the former method is a lousy way to get user input and
display output, and you're going to want to use Rexx Dialog's PM
Interface instead. Since Rexx Dialog offers other facilities to
open windows and display text, there are other ways of
displaying such, but RXSAY is the easiest and is a direct
replacement for the standard SAY command (mostly). Just change
any reference from SAY to RXSAY, and you've changed a REXX
script to output via Desktop message boxes. RXSAY doesn't
recognize any ANSI sequences to change color or move the cursor.
And sometimes programmers use the fact that SAY outputs to only
1 window in order to spread output of one "statement" across
several calls to SAY. On the other hand, each call to RXSAY
produces a distinct message box. So, the translation isn't
exact, but it's close enough. Generally, what RXSAY is used for
is to display error messages, or to offer the user a simple
prompt, such as to ask him if he wants to overwrite an existing
file.
If you have a Main Window open (via the RXDLG command), then the
message box is attached to that window. In this case, it won't
suspend other OS/2 applications, nor lockup the Desktop until
the message box is dismissed. If no Main Window is open, the
message box pops up directly upon the Desktop, and the user must
dismiss it before he can do anything else from the Desktop.
RXSAY offers a choice of various pushbuttons that can be created
at the bottom of the message box, which the user can click upon
to dismiss the message box. RXSAY will then return different
values depending upon which button the user clicked. For
example, you can use RXSAY to present a box that displays a
question and offers the user a YES or NO button, and write your
REXX script to do different things based upon the returned RC.
Args
Message The string that you want displayed. Just like with the standard
SAY command, it can be a literal string, or a variable. If you
intend to supply the Type arg, then you must put a | character
after the Message. This character must be enclosed in quotes in
order to prevent the REXX Interpreter from misinterpreting it as
a mathematical OR symbol. It's OK to omit blank spaces
inbetween the | and the Message and Type args, or even to
enclose all 3 in one set of quotes if you're supplying a literal
string for Message. For example, all of the following are the
same:
RXSAY 'hello' '|' 1
RXSAY 'hello''|'1
RXSAY 'hello|' 1
RXSAY 'hello|1'
Type What Buttons (ie, OK, CANCEL, YES, NO, etc) to place at the
bottom of the message box, and also what graphic symbol to
display next to the message (ie, Question Mark, Stop Sign,
Warning Sign, etc). If Type is omitted, then there are only an
OK button and a Stop Sign.
For the Type arg, pick any 1 of the following button groups, and
then pick out 1 of the graphic symbols, and add the two values
together.
BUTTONS
OK 0
OK and CANCEL 1
RETRY and CANCEL 2
ABORT, RETRY and IGNORE 3
YES and NO 4
YES, NO, and CANCEL 5
CANCEL 6
ENTER 7
ENTER and CANCEL 8
GRAPHIC SYMBOLS
None 0
Question Mark 16
Exclamation Mark 32
Asterisk 48
Stop Symbol 64
For example, set Type as 4+16 if you want YES and NO buttons
with a Question Mark symbol.
Heading The Heading that appears above the message. If you don't supply
any Heading text, then a default heading is used which consists
of "Rexx Dialog x.x" where x.x is the version and revision
number of the Rexx Dialog release.
Returns
A number which represents which button the user pressed to dismiss the message
box. Each of the different buttons that you can include in the box not only
dismisses the box, but also returns a different value, so your script knows
which one the user selected. Here are the values that each button returns.
OK 1
CANCEL 2
ABORT 3
RETRY 4
IGNORE 5
YES 6
NO 7
ENTER 9
Examples
/* Pop up a dialog with the question "Is your name Marvin"? Note that we stored
the name
in a variable. We also include YES and NO buttons, and a Question Mark
symbol. */
txt='Marvin'
RXSAY 'Is your name 'txt'?|' 20
IF RC = 6 THEN RXSAY 'Yes, your name is 'txt'.'
Note: Don't forget the | character, somewhere within quotes, inbetween the
Message and the Type args. Otherwise, the Type will be misinterpreted
as part of the message and displayed in the message box after the Message.
ΓòÉΓòÉΓòÉ 6.9. RXSET ΓòÉΓòÉΓòÉ
Template RXSET WindowTitle GroupNum ControlNum Operation Value
RXSET WindowTitle WindowOperation Value
Description This command sets the specified control within the specified
Group and Window to a particular value. In other words, it can
be used to set a currently displayed control to a new value.
The second template is used to change a window's
characteristics.
Args
WindowTitle is a string to match with the title of any open window. This must
be enclosed in quotes if there are spaces within the window title. WindowTitle
can be an empty string, ie '""', in which case, the Main Window is used for the
operation.
GroupNum is the Group containing the desired control, where the first Group in
the window is 1.
ControlNum is the desired control, where the first control in the Group is 1.
If you want the Operation to be performed upon all controls within the Group,
then pass a ControlNum of 0.
Operation is the operation that you desire as so:
VAL Change the value of the control to the Value string.
HIDE Hide the control (ie, visually remove it from the display). The
Value string is a 1 if you want to hide the Label for the
control (as well as the Value printout for a slider, and
ALL\NONE buttons with multiple select lists and checkmark
Groups), or 0 if you only want to hide the control itself. If
ControlNum is 0, then all controls in the Group are hidden, as
well as any surrounding groupbox. For a MENU group, the whole
menu is always hidden.
SHOW Show the control (if it was hidden). The Value string is a 1 if
you want to show the Label for the control (as well as the Value
printout for a slider, and ALL\NONE buttons with multiple select
lists and checkmark Groups), or 0 if you only want to show the
control itself. If ControlNum is 0, then all controls in the
Group are shown, as well as any surrounding groupbox. For a
MENU group, the whole menu is always shown.
SIZE Size a control (ie, visually change its width and/or height).
The Value string specifies the new width and height (in pels)
for the control. If the width is set to 0, then the width is
not changed (ie, the original width is retained). If the height
is set to 0 (or omitted), then the height is not changed. If
ControlNum is 0, then all controls in the Group are sized to the
specified width and height, as well as any surrounding groupbox.
A MENU group can't be sized.
Note: The SIZE command doesn't properly relocate labels and
groupboxes for ENTRY nor SLIDER controls. Furthermore, a
LIST box's Height should be set to some multiple of 16.
The SIZE command is provided primarily for sizing the
width of TEXT or DROPBOX controls, or the width and
height of LISTBOX controls.
MOVE Move a control (ie, visually change its position). The Value
string specifies the X and Y offsets (in pels from the current
position) to move the control. If X is set to 0, then the
vertical position is not changed. If Y is set to 0 (or
omitted), then the horizontal position is not changed. If
ControlNum is 0, then all controls in the Group are moved the
specified amount, as well as any surrounding groupbox. A MENU
group can't be moved.
Note: If you're using the SIZE or MOVE commands upon only 1
control within a group, and that control is encircled by
a groupbox, then you should HIDE the control before
issuing the SIZE or MOVE commands, and then SHOW the
control afterwards. This is necessary due a peculiarity
in the way that OS/2 GroupBoxes handle repainting.
Failure to follow this guideline may result in seeing
remnants of the original control's graphic not properly
erased inside of the groupbox. If the encircling
groupbox is a separate GROUP from the control, then
HIDE/SHOW the groupbox instead of the control. If you're
issuing several SIZE and/or MOVE commands, upon several
controls within a group, but one control at a time, you
only need to HIDE those controls (or the groupbox) once
before the MOVE/SIZE commands, and SHOW them afterwards.
ADD Add the value string (ie, text for an item) to a LIST or DROP
box, or add a new MENU bar. When adding a new menu bar, the old
menu bar is deleted.
DEL Delete a particular item (or all items) from a LIST or DROP box,
or a MENU label. When deleting a menu label, if it happens to
be a Menu Heading, all of the drop down items\subitems for that
heading are also deleted. If the label happens to be an Item
with SubItems, all of the SubItems are deleted. Note that the
numbering of the labels doesn't change simply because you
deleted items, subitems, or headings. You still must count
those deleted labels when counting the menu labels (unless you
create an entirely new menubar -- then the numbering of the
labels is reset).
FLAG Set Flags for the Group. In this case, the Value string will be
the Flags arg as you would specify it for RXFLAGS. But, the
only Flags you may set via RXSET are END, INDEX, and BOOL. The
ControlNum arg is irrelevant.
For the second template of RXSET, WindowOperation can be one of the following:
HIDE Hide the window and all of its controls (ie, visually remove it
from the display). If the Main Window, then all of the child
dialogs get hidden too.
SHOW Show the window (if it was hidden).
MOVE Move the window. In this case, the Value string will be the X
position and Y position.
SIZE Resize the window. In this case, the Value string will be the
Width and Height.
STATE Change the window's state. In this case, the Value string will
be a 0 to minimize the window, 1 to maximize the window, or 2 to
restore the window. If Value arg is omitted, the window is
minimized.
ACTIVE Brings the window to the front of the screen, and makes it
active.
FLAG Set Flags for the window. In this case, the Value string will
be the Flags arg as you would specify it to RXDLG. But, the
only Flags you may set via RXSET are NOCLOSE, MODAL, KEYS, ONCE,
and RESULT.
TIME Sets the time-out for the window. In this case, the Value
string will be the desired time-out in milliseconds. (1000
milliseconds = 1 second, 1000*60 milliseconds = 1 minute, etc).
If you pass a Value of 0 (or omit the Value arg), then the
time-out function for the window is turned off, and the timer is
stopped. A non-zero time-out will start the timer. See Time
out.
Value is the value for the Operation. Note that you do not need to place any
Value string inside of 2 sets of quotes, even if it is a literal string with
imbedded spaces.
Here is what Value string specifies for each Group Type when the Operation is
VAL:
PUSH Value is a 1 if the button is to be chosen as the default, or a
0 if the button is to be unselected. Note that if a button is
selected for default, all other buttons in the Group are
automatically unselected.
RADIO Value is a 1 if the button is to be selected, or a 0 if the
button is to be unselected. Note that if a button is selected,
all other buttons in the Group are automatically unselected.
CHECK Value is a 1 if the button is to be checked, or a 0 if the
button is to be unchecked.
ENTRY Value is the text to set into the entry box. The text should
not contain a | character. Omitting the text will blank the
box.
DROP Value is the text to set into the entry box. The text should
not contain a | character. Omitting the text will blank the
box.
LIST Value is the text of the item to select or deselect. This text
should be followed by a | character, and then either a 1 or 0 to
select or deselect any item that matches the text. If you omit
the text before the | character, then all items are selected if
a 1 follows the |, or all items are deselected if a 0 follows
the |.
Note: For single-select list boxes, only 1 item can be selected
at a time, and all other items will be automatically deselected.
SPIN Value is the numeric value to which the spin will be set.
SLIDER Value is the numeric value to which the slider (knob) will be
set.
TEXT Value is the phrase to display, and ControlNum is the phrase
number to replace. If the new phrase isn't as wide as the
original WidthOfPhrase (ie, when the TEXT Group was created),
text may be visually clipped.
MENU Value is the text to set into the menu label. The text should
not contain a | character. The ControlNum arg to RXSET is the
menu label number. See Menu Group for how to count the labels.
GROUP Value is the text to set for the groupbox label. The text
should not contain a | character.
Note: RESULT Type can't be used with a VAL Operation.
Here is what Value string specifies for each Group Type when the Operation is
DEL:
LIST or DROP Value is the text of the item (in the list) to delete. If you
omit the Value arg (ie, don't supply a string to match), then
all items in the list are deleted (ie, the list is "emptied").
MENU There is no Value arg. The ControlNum arg specifies the menu
label to delete. Note that you can delete the entire menu bar
by passing ControlNum of 0 (ie, specify that you want the delete
action applied to all menus in the Group).
Note: Other Types can't be used with a DEL Operation.
Here is what Value string specifies for each Group Type when the Operation is
ADD:
LIST or DROP Value is the text of the item to add to the list. This text
should be followed by a | character, and then a number that
specifies how you want the item added to the list. If you want
the item added to the end of the list, specify -1. If you want
the item added in ascending alphabetical order, specify -2. If
you want the item added in descending alphabetical order,
specify -3. All positive numbers represent the offset in the
list where you want the item placed, with 0 being at the
beginning of the list. For example, if you want to add the item
as the tenth item in the list, specify 9 (because 0 is the
first).
Note: Put quotes around any negative numbers that you pass, for
example '-1'. OS/2 REXX appears to have another bug
related to recognizing the minus sign for negative numbers.
MENU The Value arg are the HELP Flag, followed by the REXX variable
names where each dropdown menu is defined. In other words, the
Value arg is just like how you would specify the RXINFO string
for a MENU Group, except that instead of the TotalMenus count in
front of the variable names, you specify the 'HELP' flag
followed by a | character (or just omit the 'HELP' before the |
character if you don't desire a help menu). Note that you must
set up all of the stem variables as you would if you were
creating a MENU Group in a window.
Note: Other Types can't be used with a ADD Operation.
Returns
This could return an error. See Errors for details.
Examples
/* Assume that the first Group in a window called "Window 1" is an ENTRY Group,
and we want to change the contents of the 3rd entry to the string "hello there"
*/
RXSET '"Window 1"' 1 3 'VAL' 'hello there'
ΓòÉΓòÉΓòÉ 6.10. RXVERS ΓòÉΓòÉΓòÉ
Template RXVERS
Description This command returns a string (in the special REXX variable RC)
that identifies the version and revision numbers (separated by a
space) of RXDLG.DLL. For example, if the version/revision
number of Rexx Dialog is 1.0, then the returned string is '1 0'.
Args
None.
Returns
The version and revision numbers as one string.
Examples
/* This gets the version and revision numbers and displays each separately */
RXVERS
rev = RC
PARSE rev ver rev
RXSAY 'Version = 'ver
RXSAY 'Revision = 'rev
ΓòÉΓòÉΓòÉ 7. PM Lockups ΓòÉΓòÉΓòÉ
While your script is not "sleeping" within a call to RXDLG, and the script has
(NOCLOSE) windows open, it may be preventing other PM apps from multitasking
(due to OS/2 2.X PM having a single-threaded message queue). Only when RXDLG
is allowed to perform user interaction (ie, when you call RXDLG to perform some
operation that allows user interaction with those open windows) can you be
assured that your script isn't locking up PM.
So, if your script opens NOCLOSE windows, then whenever RXDLG returns, your
script should either close all open windows (so that the user can't interact
with them and perhaps cause a PM lockup while your script is busy doing
something), or finish its work quickly and get back to calling RXDLG with some
operation that allows user interaction.
But, what if your script doesn't want to close all windows, and yet, needs to
do some processing that may take a long time? In order to avoid any lockup
situation, you should periodically call RXDLG with the following call:
RXDLG '""' 255
Note that the WindowTitle arg is 2 double-quotes inside of single quotes. An
operation of 255 cleans out the PM message queue so that no PM lockup will
occur. The user will not be allowed to interact with any open windows in this
call to RXDLG (other than to resize/maximize/minimize the main window), so it
doesn't effect REXX variables or the window states at all.
For example, assume that you have some open windows, but you need to read in
the lines of a text file. Here's an example where RXDLG is called after
reading in every 10 lines in order to clean out the PM message queue. This
will allow the user to switch to and use other PM apps while your script is
reading in the lines of the text file.
IF ''\=STREAM(FileName,'c','query exists') THEN DO
code=LINEIN(FileName,1,0)
nLines=0
DO WHILE LINES(FileName)
Lin.nLines=LINEIN(FileName)
nLines=nLines+1
IF (nLines%10) = 0 THEN RXDLG '""' 255
END
code=STREAM(FName,'c','close')
END
Note: Never use any REXX function library "sleep" function that makes a call
to OS/2's DosSleep() routine. PM programs are not allowed to use
DosSleep() and doing so will lockup the Desktop. Calling RXDLG
automatically puts your program to sleep when the user is not
interacting with it, so there is no need to use any sleep function to
halt your script at any point. Simply call RXDLG with an operation that
does user interaction. If you need to wakeup at a certain time in order
to check upon some condition, then setup a time-out on a window (perhaps
making it MODAL so that the user won't be able to change to another
window). Then check the return RXID and RXSUBID both for 0 in order to
detect a time-out. If you need to ensure that the user can't interfere
with the time-out, then I suggest creating a window with something
simple, like a TEXT group, making the window MODAL, and hiding that
window. Then, when you need to do a time-out, use RXSET to set the
time-out, and then call RXDLG with an operation of 0 and specify that
window. After the time-out, you can use RXSET to disable further
time-outs for that window.
ΓòÉΓòÉΓòÉ 8. Launching programs ΓòÉΓòÉΓòÉ
Consider if you wanted to launch some OS/2 program (ie, not another REXX
script) from a Rexx Dialog script. For example, let's say that you wanted to
invoke the copy command on the file named BLORT to copy it to BLORT2. From a
regular REXX script (ie, started from an OS/2 Command Prompt), you could do the
following:
'COPY blort blort2'
If you put the above line in a Rexx Dialog script, you'll see the error message
REXX dialog unknown command: COPY.
The problem is that REXX is passing the above statement to Rexx Dialog, and
Rexx Dialog doesn't have a COPY command. Normally, REXX scripts are run from
the OS/2 command line, and so REXX would pass this command to the OS/2 command
line, which does have a COPY command. But, when running a script with RX.EXE,
REXX passes everything which it doesn't recognize as a built-in command to Rexx
Dialog. In this case, you need to specifically direct the above instruction to
the OS/2 shell. You do so by putting ADDRESS CMD before the line that you want
to send to the OS/2 shell (ie, CMD is the REXX environment name for the OS/2
shell, and ADDRESS tells REXX to send the following line to that environment
instead of letting Rexx Dialog try to implement that line). So the line would
be:
ADDRESS 'CMD' 'COPY blort blort2'
If you have several instructions which you need to send to the OS/2 shell, you
can change the environment permanently by just putting ADDRESS 'CMD' as a
self-contained instruction. But afterward, you need to change the environment
back to Rexx Dialog's environment (which is 'RXDLG') before calling any Rexx
Dialog commands again. You can toggle back to Rexx Dialog's environment by
simply using ADDRESS alone, or use ADDRESS 'RXDLG'. For example, here we
change the environment to the OS/2 Shell, execute a few copy commands, and then
return the environment to Rexx Dialog.
ADDRESS 'CMD'
'COPY blort blort2'
'COPY blort2 blort'
ADDRESS
If you're launching other programs (ie, not REXX scripts) from a Rexx Dialog
script, REXX suspends execution of your script until such time as that launched
program terminates. The numeric value that this program returned to OS/2 is
then returned to your REXX script in the RC variable.
But remember that a Rexx Dialog script must not do any kind of waiting or
sleeping while it's not within RXDLG, or this could lock up the PM desktop.
Unfortunately, that means that if the launched program does its own waiting for
user input, or takes a long time to execute, then this could lock up the
desktop.
Take the case with launching some Presentation Manager program from a Rexx
Dialog script. When your Rexx Dialog script calls that PM program, control
isn't returned to your script until the PM program terminates, and of course,
since most PM programs hang around until the enduser dismisses them, that means
that your Rexx Dialog script is stuck in that statement which launched the PM
program. Of course, that also means that your Rexx Script isn't calling RXDLG,
and therefore, if the enduser attempts to do something with any Rexx Dialog
windows your script has opened, then a PM lockup will occur. The solution is to
use OS/2's START command to launch the program. This causes the program to be
launched as a separate process, and control returns to your script immediately
(ie, the launched program is entirely independent of the script, and your
script can then proceed to do other things, such as call RXDLG to maintain its
user interface). Whenever launching PM programs from a Rexx Dialog script, or
other Rexx Dialog scripts by invoking RX.EXE, always use OS/2'S START command.
So if you have a PM program called BLORT.EXE in your C:\OS2\APPS drawer, here's
how you launch it:
ADDRESS 'CMD start' 'c:\os2\apps\blort.exe'
The one drawback to using START is, if the launched program returns an error
code, you won't get it. Instead, you'll always get a 0 (ie, success) return
from the above REXX statement, except for if OS/2 itself can't startup the
program.
Typically, OS/2 command line programs (ie, not PM) just perform one operation,
perhaps using arguments passed from the command line, and then terminate. It's
OK to call such a program by simply specifying its name after ADDRESS CMD (ie,
how you'd normally launch another program from a Rexx script). For example, if
you have a command line "TOUCH.EXE" program which takes one argument, the name
of a file whose creation date is to be set to the current date, and the program
does just that and exits without needing to prompt for user input itself, then
you may call it as so to update the file "BLORT.TXT'.
ADDRESS 'CMD' 'touch.exe blort.txt'
Control won't be returned to your script until after the TOUCH program
terminates, and the return code will be whatever TOUCH returned to OS/2. If
this is not 0, then this will cause the ERROR condition to be raised. (Of
course, if the program never returns 0 even for successful operation, you can
always use the START command to launch it as its own process with its error
code tossed away. Or you can monkey with RXERR or SIGNAL ON ERROR instructions
before you launch the program, to try to ignore an error return).
On the other hand, if this TOUCH program involved a very lengthy process during
which you didn't want to tie up the desktop, and didn't care about losing the
error return code, you could use the START command to launch it as its own
process.
You must use the start command when launching another Rexx Dialog script. For
example, to launch the Rexx Dialog script BLORT.CMD:
ADDRESS 'CMD start' 'rx.exe blort.cmd'
ΓòÉΓòÉΓòÉ 9. Time-out ΓòÉΓòÉΓòÉ
A time-out can be set for a window which, when your script is sleeping in RXDLG
(ie, you performed some operation that does user interaction) and the user has
not done anything with that window that would case RXDLG to return during that
specified time-out, then RXDLG automatically returns to your script. In this
case, RXID is set to 0 (ie, just like with the ENTER key if the RESULT Flag is
set, or other keys if the KEYS Flag is set), and RXSUBID is set to 0.
If you wish to change the time-out value, you can do so by calling RXSET with a
WindowOperation of 'TIME' and the desired time-out value. If you set a
time-out value of 0, then the time-out function for that window is disabled
(and any time-out that may have already occurred is cleared). Setting a
time-out value of anything but 0 causes a time-out for that window to be
enabled (and if the time-out was previously enabled, any time-out that may have
already occurred is cleared).
While your script is not sleeping in RXDLG, the timer will still be counting
down for the next time-out. So, if another time-out occurs while your script
is doing some processing, then upon the next call to RXDLG, your script will
immediately return with another time-out. Even if more than 1 time-out occurs
while your script is doing some processing (ie, you have a time-out of 10
milliseconds, but your script takes 50 milliseconds to do some processing
before calling RXDLG again), you'll only be notified of a single time-out. So,
the time-out should not be used as an accurate clock of elapsed time.
Setting a time-out value of anything but 0 clears out any time-out that may
have occurred while your script was doing some processing. So, if you wish to
"rearm" the time-out before calling RXDLG, simply set the time-out value with
RXSET before calling RXDLG.
If you want a countdown timer (ie, the timer counts down once, and then is
automatically disabled), then set the ONCE Flag for the Window. This ensures
that each time you set a time-out with RXSET, you'll receive one time-out at
most.
The time-out value is specified in milliseconds.
ΓòÉΓòÉΓòÉ 10. Keyboard Input ΓòÉΓòÉΓòÉ
If you set the KEYS Flag for a window, whenever that window has the focus (ie,
the window itself and not some control within it) and the user presses some key
combo upon the computer's keyboard, RXDLG will return. RXWIND will be set to
the title of the window which was active when the user pressed the key combo.
RXID will be 0 or a negative number depending upon whether the user held down
the ALT, SHIFT, and/or CTRL keys when he pressed another key, and whether the
key is a printable key (such as "s") or an unprintable key (such as the HOME
key).
Note: The ALT, SHIFT, or CTRL keys, pressed by themselves, do not cause RXDLG
to return. These are "modifier" keys, and only effect the value of RXID
returned when the user presses another key in combination with these modifiers.
When RXDLG returns, it does NOT close the window, even if that window did not
specify the NOCLOSE flag. The exception to this is pressing the ESC or ENTER
keys if the window's RESULT Flag is set.
When the user presses a printable key, without the CTRL or ALT keys held down,
then RXID is 0, and RXSUBID is that character. For example, if he presses the
'd' key alone, then RXSUBID is 'd'. If he holds down the shift key, then the
shifted character printed on the key is returned. For example, if he holds
down the SHIFT while pressing 'd', then RXSUBID is 'D'. If he holds the SHIFT
while pressing the '1' key, then RXSUBID is '!'.
If the user holds the ALT key while pressing a printable character, then RXID
is -1, and RXSUBID is that character. If he also holds the SHIFT key, that
will cause RXSUBID to be the shifted character as above.
If the user holds the CTRL key while pressing a printable character, then RXID
is -2, and RXSUBID is that character. If he also holds the SHIFT key, that
will cause RXSUBID to be the shifted character as above.
If the user holds both the ALT and CTRL keys while pressing a printable
character, then RXID is -3, and RXSUBID is that character. If he also holds
the SHIFT key, that will cause RXSUBID to be the shifted character as above.
If the user presses an unprintable character without the CTRL, ALT, or SHIFT
keys held down, then RXID is -4, and RXSUBID is a "virtual key number". Here
are the virtual key numbers for the following unprintable characters:
Break 4
BackSpace 5
TAB 6
BackTAB 7
Pause 13
Caps Lock 14
Page Up 17
Page Down 18
End 19
Home 20
Left 21
Up 22
Right 23
Down 24
Print Screen 25
Insert 26
Delete 27
Scroll Lock 28
Num Lock 29
SysRq 31
F1 32
F2 33
F3 34
F4 35
F5 36
F6 37
F7 38
F8 39
F9 40
F10 41
F11 42
F12 43
F13 44
F14 45
F15 46
F16 47
F17 48
F18 49
F19 50
F20 51
F21 52
F22 53
F23 54
F24 55
If the user holds the ALT key while pressing an unprintable character, then
RXID is -5, and RXSUBID is the virtual key number as described above.
If the user holds the CTRL key while pressing an unprintable character, then
RXID is -6, and RXSUBID is the virtual key number as described above.
If the user holds both the ALT and CTRL keys while pressing an unprintable
character, then RXID is -7, and RXSUBID is the virtual key number as described
above.
If the user holds the SHIFT key while pressing an unprintable character, then
RXID is -8, and RXSUBID is the virtual key number as described above.
If the user holds both the ALT and SHIFT keys while pressing an unprintable
character, then RXID is -9, and RXSUBID is the virtual key number as described
above.
If the user holds both the CTRL and SHIFT keys while pressing an unprintable
character, then RXID is -10, and RXSUBID is the virtual key number as described
above.
If the user holds the ALT, CTRL, and SHIFT keys while pressing an unprintable
character, then RXID is -11, and RXSUBID is the virtual key number as described
above.
If the user presses the ESC key, RXID is -12, and RXSUBID is 0.
If the user presses the ENTER key, RXID is 0, and RXSUBID is 10.
Note: If the user clicks upon the window's CLOSE ICON, RXID is -98, and
RXSUBID is 0. If the window's NEWSIZE flag is set, and the window is
resized, RXID is -20 and RXSUBID is 0. If the script is launched by an
app other than RX.EXE, and the app wants the script to abort, RXID is -
99, and RXSUBID is 0.
PM siphons off some key combos for operation of windows. For example, pressing
the ALT key usually activates a window's menu bar. And CTRL + ESC switches
between sessions. F1 activates any Help file attached to a window. Etc.
These key combos are never seen by your script.
Normally, you'll use ENTRY, DROP, and other PM controls to get strings of user
input. Use of KEYS flag is meant to be used for "keyboard commands". For
example, you can set KEYS for your Main Window, and when the user presses the
ALT and "f" keys, you can bring up the File Dialog (ie, via RXFILE) as part of
some sort of file operation. Each key combo will initiate a different
operation in your script. By using mnuemonic symbols (ie, ~ placed before the
letter that you wish underlined in any label for a control), and setting the
KEYS Flag, you can identity and implement keyboard shortcuts that will
implement the same operations as the controls in that window.
Rexx Dialog ignores key releases. Only key down is detected.
ΓòÉΓòÉΓòÉ 10.1. ESC and ENTER Keys ΓòÉΓòÉΓòÉ
If the RESULT Flag is set for a window, then when the window has the focus and
the user presses the ESC or ENTER key, RXDLG returns. RXID and RXSUBID are set
as described in Keyboard Input. But, all of the other variables are set per
this window's Groups as well, and if the window doesn't have its NOCLOSE Flag
set, the window is closed. Also, the first RESULT Group (if present) in that
window is setup in a FAILURE state if ESC was pressed, or SUCCESS state if the
ENTER key was pressed.
Note: When a control within the window has the focus, the ESC and ENTER keys
instead work with that control (regardless of whether you specified the
RESULT Flag). The dialog window itself must have the focus (ie, which
happens automatically after the user has finished manipulating a control
by pressing the ENTER or ESC keys. The ESC and ENTER keys can always be
used to deactivate a control and return the focus back to the window
itself. The ENTER key will usually cause a Group with its END Flag to
force RXDLG to return, whereas the ESC key will not).
ΓòÉΓòÉΓòÉ 11. Positioning a window ΓòÉΓòÉΓòÉ
If you double-click the mouse 2 button anywhere in a window, this pushs the
window down to the lower left corner of the Main Window (if a Child Dialog) or
the Desktop (if a Main Window). Since Child Dialogs open inside of the Main
Window, sometimes a situation may happen where the titlebar of the Child Dialog
is beyond the border of the Main Window (and therefore inaccessible by the
mouse unless you can resize the Main Window to get to that titlebar). Clicking
the mouse 2 button twice is an easy way to drop the window down to the lower
left corner, where the Child Dialog's controls will usually be more accessible.
ΓòÉΓòÉΓòÉ 12. Resizing a window ΓòÉΓòÉΓòÉ
If the window's NEWSIZE flag is set, then after the user resizes that window,
RXDLG returns with RXWIND set to the name of the window that was resized, RXID
= -20 (and RXSUBID = 0), and the window's Dimensions string is updated with the
width and height (as well as X and Y position of the lower left corner relative
to the Desktop). A use for this might be to issue a RXSET SIZE command to
resize any LISTBOX height, or TEXT or DROPBOX width in accordance with the size
of the window. Here's an example of detecting that a window has been resized,
and parsing the new width and height.
/* Creates a window called "Text" containing 1 TEXT Group with 1 line of
centered text */
RXTYPE.1 = 'TEXT'
/* Center the text */
RXFLAGS.1 = 'CENTER'
/* Text lines */
RXLABEL.1 = 'Hello'
/* TotalPhrases, PhrasesPerLine, WidthOfPhrase, BetweenPhrases */
RXINFO.1 = '1 1'
/* Position */
RXX.1 = 10
RXY.1 = 10
RXDIM = ' '
RXDLG 1 '"Text"' 'RXDIM' 'SIZE|NEWSIZE'
/* Do user interaction */
RXDLG
/* Is this a resize? */
IF RXID = -14 THEN DO
/* We only have 1 window, but if we had several open, we'd need to check
which one was resized so that we'd know which one's Dimensions string to parse
*/
IF RXWIND = 'Text' THEN DO
PARSE VAR RXDIM width height x y
/* Now width, height, x, and y hold the window dimensions */
END
END
ΓòÉΓòÉΓòÉ 13. Aborting a script ΓòÉΓòÉΓòÉ
If a script is going to be launched by an app other than RX.EXE (the app must
be written to specifically use RXDLG.DLL), then upon return from an RXDLG
Operation 0 or 1, you should check if RXID = -99, and immediately EXIT if so.
This is the app's way of indicating that it would like your script to
prematurely abort.
ΓòÉΓòÉΓòÉ 14. Errors ΓòÉΓòÉΓòÉ
All Rexx Dialog commands return either a string or number (depending upon which
you specify via RXERR, but some commands always return strings). The return is
stored in the special REXX symbol RC. As each command is issued, RC reflects
what that command returns. The return usually tells you whether a command
worked or failed (although sometimes the return provides other info instead
such as which button was used to dismiss a RXSAY box). An RC of 0 (for error
numbers) or an empty string, ie "" (for error strings) is considered to be a
successful return. In the case of a command that could fail as a result of
something that goes wrong within the command, you should always check RC after
issuing that command. Alternately, since all Rexx Dialog commands set the REXX
FAILURE or ERROR flags for any possible errors, you can SIGNAL ON ERROR or
SIGNAL ON FAILURE to an appropriate place in your REXX script to handle such an
error situation.
Some Rexx Dialog commands always work if they make it past the REXX interpreter
to RX.EXE. But of course, any command can fail as a result of some syntax
error (ie, you typed it in incorrectly) or other errors that occur before the
REXX interpreter ships the command off to RX.EXE. In this case, the ERROR or
FAILURE flag is usually raised by the REXX interpreter itself, and it will
return an RC value (usually a number that is not 0, instead of an empty
string). Or, the interpreter may abort the script and return an error number
to RX.EXE. In the case of these errors, RX.EXE displays a PM message box
containing the error. The heading of the dialog will be "REXX INTERPRETER
ERROR". (When you use RXSAY, the PM message box default heading is "Rexx
Dialog x.x" where x.x is the version and revision number of the Rexx Dialog
release). The error message provided by the interpreter usually identifies the
line number in your script where the error occurred, and may also display the
text upon that line.
Note: The interpreter doesn't count blank lines, or lines that only contain
comments. So when it reports that an error occurred upon line 5, that
doesn't mean that it actually is line 5 in your text file. You need to
count the lines, skipping any blank lines or lines that contain only
comments in order to find the "real" line 5.
If REXX aborts the script (ie, perhaps REXX detected an error with it before
even starting the script running), then RX.EXE will display an error message in
a PM message box. Once again, the message box will have a heading that says
"REXX INTERPRETER ERROR:". If the problem was with RX.EXE being unable to set
itself up or find the script that you specified to run, then the message box
heading will be "Rexx Dialog x.x". The 2 different headings allow you to
visually differentiate between errors with the REXX interpreter (ie, usually
with the standard REXX commands, or syntax problems, etc), and errors with
processing the 9 special Rexx Dialog commands (errors that occur in creating
and managing the PM interface). For the meaning of REXX INTERPRETER ERROR
messages, consult your REXX documentation.
When developing a script, it may be advantageous to include this line at the
top:
RXERR 'FULL'
This will force the REXX interpreter to supply the line number and REXX source
where the error occurred.
Here are the error messages (and corresponding error numbers) that each Rexx
Dialog command may return. The bottom two (highlighted) digits of the error
number indicate the "display level" for that message (to be used as a reference
when you set the display level with RXERR).
RXDLG
When you use the first template of RXDLG, it could return any of the following
errors:
211 "Can't create dialog."
Rexx Dialog couldn't create the window (into which all of the Groups
of controls are placed). Possible problems are: you have too many
windows open and OS/2 has run out of certain PM resources, or you may
have specified a window size that is too big for the display or X and
Y positions that cause problems (ie, try setting the windows
Dimensions string to a null string for default size and position).
212 "Can't create control: Group XXX, Control XXX."
Rexx Dialog couldn't create a particular control within a Group. The
XXX after "Group" will indicate which Group number the control
belonged to. For example, if the control was in the first Group that
you defined for the window, then XXX would be 1. The XXX after
"Control" will indicate which control within the group couldn't be
created. For example, if the control was in the first in the group,
then XXX would be 1. Possible problems are: you have too many
windows/controls open and OS/2 has run out of certain PM resources,
or you specified some incorrect width for the control, or you
specified some strange X and Y position for the group, or made some
other error in the setup of REXX variables particularly for that one
control within the Group.
213 "Bad Group Type: Group XXX, Control 1.."
An unknown Group Type was encountered. The XXX after "Group" will
indicate which Group number had an unknown Type. For example, if the
first Group that you defined for the window had a bad Type, then XXX
would be 1. Possible problems are: you specified some incorrect Type
for this Group (ie, check its RXTYPE variable), or you're using an
old version of RXDLG.DLL that doesn't support this Group Type (ie,
use the RXVERS command to discover whether the DLL's version and
revision is equal or greater than the version/revision in the title
of this book).
214 "Can't create control Label: Group XXX, Control XXX."
Rexx Dialog couldn't create a label for a particular control within a
Group. The XXX after "Group" will indicate which Group number the
control belonged to. For example, if the control was in the first
group that you defined for the window, then XXX would be 1. The XXX
after "Control" will indicate for which control within the Group the
label couldn't be created. For example, if the control was the first
in the Group, then XXX would be 1. Possible problems are: you have
too many windows/controls open and OS/2 has run out of certain PM
resources, or you specified some strange X position for the Group
which maybe didn't leave room for a label to the left of the control,
or you didn't properly specify the label for the control (ie, check
the RXLABEL string for the Group to make sure that you have enough
labels for all controls).
215 "Can't create Groupbox: Group XXX, Control XXX."
Rexx Dialog couldn't create a particular Groupbox around a Group (or
if the Type for a group is GROUP, then it couldn't create that
Groupbox). The XXX after "Group" will indicate the Group number for
which the Groupbox couldn't be created. For example, if the Groupbox
was to encircle the first group that you defined for the window, then
XXX would be 1. Possible problems are: you have too many
windows/controls open and OS/2 has run out of certain PM resources,
or you specified some incorrect width for the control, or you
specified some strange X and Y position for the group, or you didn't
properly specify the label for the Groupbox (ie, check the RXLABEL
string for the Group to make sure that you have enough labels for all
controls as well as the Groupbox). If the indicated "Control" number
is not equal to the TotalControls parameter in the Group's RXLABEL
string (with the exception of RESULT Group, or button Groups where
there are "skipped" buttons), then this indicates a potential problem
with not enough or too many labels in the RXLABEL string.
??? "Failed to create/set REXX variable XXX."
Rexx Dialog couldn't setup some REXX return variable (for example,
the RXVAL return for a Group, or RXWIND, etc). The error number can
be one of several different values depending upon what the REXX
Interpreter returns. This error indicates an internal problem with
the REXX Interpreter, and could be anything from a memory problem to
what-have-you. But, when receiving any such error, your script
should assume that RXDLG has not returned a good set of values. The
XXX tells which REXX variable in particular couldn't be setup.
Although this message is associated with a range of error numbers,
its display level is 16.
??? "Can't fetch REXX variable XXX."
Rexx Dialog couldn't find some REXX variable that your script was
supposed to setup prior to a call to RXDLG. (for example, the RXTYPE
for a Group, etc). The error number can be one of several different
values depending upon what the REXX Interpreter returns. The XXX
tells which REXX variable in particular couldn't be fetched. Check
to make sure that you have either defined that REXX variable in your
script (ie, sometimes, with copying and pasting source code, it's
easy to forget to change the extension on a stem variable to reflect
the Group number), or that the NumGroups arg to RXDLG reflects how
many Groups you have defined. This error message cannot be
surpressed, and the REXX Interpreter forces a message box display.
10008 "Not enough memory."
There is not enough free RAM in your system to setup some structures
needed to create window/controls. You'll have to close down other
running programs.
When you use the second template of RXDLG, it could return any of the following
errors:
10017 "Can't find REXX dialog."
RXDLG couldn't find the specified window to perform an operation
upon. Possible problems are: you've passed a WindowTitle arg to
RXDLG that doesn't match any of the open windows (or perhaps omitted
the WindowTitle arg, but included the Operation arg -- you must
supply both, or neither). If the passed WindowTitle arg is '""' (or
not supplied), then you must have at least a Main Window open. The
exception to this is an operation of 255, which will never return
this (or any other Rexx Dialog) error.
10007 "Too much device input to return: XXX."
The string to be returned is larger than 256 characters. You might
try trimming the start or end patterns, or parsing each value into
its own variable.
Also, the "Failed to create/set REXX variable XXX" error message\number may be
encountered for Operations of 0, 1, 2, 3, and 4 (although it's a trivial
problem with Operation 4 -- this just means that the Window's Dimensions string
hasn't been updated).
RXDEV
10005 "Can't find/setup device: XXX."
RXDEV couldn't find the specified device to perform an operation
upon. Possible problems are: you've passed a DevTitle arg to RXDEV
that doesn't match any of the open devices (or perhaps omitted the
DevTitle arg, but included the Operation arg -- you must supply both,
or neither). If the passed DevTitle arg is '""' (or not supplied),
then you must have at least 1 device open. Also, you must have a
Main Window open in order to open a device, and the device must be
opened for reading using FILEREXX's FileOpen. XXX will be the device
name passed to RXDEV.
10006 "Can't start REXX device thread."
Can't start a thread to read data from the device. Try closing down
other OS/2 apps.
10020 "XXX Operation not supported."
The operation that you specified is not recognized by this version of
Rexx Dialog. XXX will be the operation that Rexx Dialog doesn't
understand. Make sure that you spelled it correctly, and have a
current version of RXDLG.DLL. Also, you will see this error if you
forget to do an OPEN Operation on the specified DevName before
attempting to do some other operation.
10009 "Bad read NNN, Device: XXX."
There was an error reading the next byte from a device. XXX will be
the device name (as you specified during the OPEN Operation). This
error may happen when accessing a device that returns immediately
when it has no bytes to return to Rexx Dialog (ie, it doesn't "block"
reads). In this case, you'll have to find some way of querying the
device to determine if it has any input bytes queued (ie, usually via
some IOCTL vector that you'll access using FILEREXX), and read only
that many bytes (using FILEREXX's reading functions). This error may
also happen if CTRL-C or CTRL-BREAK is pressed, or some other
operation causes the device to abort a read (if the device supports
that). NNN is the error number returned from OS/2, and can be:
5 Access denied
6 Invalid handle
26 Not a DOS disk
33 Lock violation
109 Broken pipe connection
234 More data
-1 Can't get a semaphore for the device thread. Try closing down
other OS/2 apps.
RXFILE
311 "Can't create dialog."
Rexx Dialog couldn't open the File Dialog. Possible problems are:
you have too many windows open and OS/2 has run out of certain PM
resources, or you may have specified a bizarre filename (ie, try
setting to a null string).
The "Failed to create/set REXX variable XXX" error message\number may be
returned if Rexx Dialog couldn't return the filename.
The "Can't fetch REXX variable XXX" error message\number may be returned if
Rexx Dialog couldn't fetch the initial filename. Make sure that you initialize
the FilenameVar arg to RXFILE, even if you set it to a null string.
RXHELP
10022 "Can't attach help file."
Rexx Dialog couldn't attach the help file to the window. Possible
problems are: OS/2 has run out of certain PM resources, or you didn't
properly specify the help filename (ie, make sure that you spelled it
correctly, and supplied a complete path if that is needed).
10021 "Can't find help panel XXX."
Rexx Dialog couldn't find the specified panel number or name within
the help file for the window. Possible problems are: OS/2 has run
out of certain PM resources, or you didn't properly specify the panel
name or number (ie, make sure that you spelled it correctly), or no
such panel name or number exists within the help file that is
attached to the Window specified to RXHELP (ie, make sure that you
have the correct window and help file).
The "Can't find REXX dialog." error message\number may be returned if the
WindowTitle you specified doesn't match any open window.
RXSAY
RXSAY never causes a REXX FAILURE or ERROR, but always returns a number
(regardless of RXERR's NUM flag) as described in RXSAY.
RXSET
10018 "Can't find group XXX"
The window that you specified doesn't contain the GroupNum that you
specified. Make sure that you haven't asked for a Group number
larger than the number of Groups in the window, nor a Group number of
0.
10019 "Can't find control XXX"
The Group that you specified doesn't contain the control that you
specified. Make sure that you haven't asked for a control number
larger than the number of controls in the Group, nor a control number
of 0.
10010 "Can't start timer."
If you do a TIME operation to setup a timer for a window, and the
timer can't be setup, this error may be returned. OS/2 has a limited
number of timers available, so shut down other apps that may be using
timers.
The "Operation not supported." error message\number may be returned if the
operation that you specified is not recognized by this version of Rexx Dialog.
The "Can't find REXX dialog." error message\number may be returned if the
WindowTitle you specified doesn't match any open window.
RXVERS
RXVERS never causes a REXX FAILURE or ERROR, but always returns a string
(regardless of RXERR's NUM flag) as described in RXVERS.
Other Rexx Dialog commands
All other Rexx dialog commands do not return anything except successful returns
(ie, 0 error numbers, or null strings).
There are a few error messages that you may see that aren't related to specific
Rexx Dialog commands. Unless otherwise mentioned, these will happen before
your script starts executing, and usually reflect a problem in RX.EXE's setup.
These error messages are always displayed unless otherwise mentioned.
20001 "Can't find REXX script to run."
The script name that you specified for RX.EXE to run can't be found.
Check that you spelled the script name correctly and/or supplied the
correct path. If you didn't supply a path, then the script must be
in the same directory as RX.EXE, or must be in the directory
specified in the Working Directory or specified in the Parameters
field of the Program Object for the script (if launched from a
Desktop object).
20003 "Window registration failed."
RXDLG.DLL couldn't properly register its special window class.
Perhaps there is another running app that happens to have a
similiarly named public window class. (Unlikely, but try closing
down other running apps).
20004 "Can't install REXX."
RXDLG.DLL couldn't properly register its REXX handler. Perhaps there
is another running app that happens to have a similiarly named
handler. (Unlikely, but try closing down other running apps).
10002 "REXX dialog unknown command: XXX"
This error may occur while your script is running. It indicates that
your script contains a command that isn't some built-in REXX command,
but also isn't a Rexx Dialog command. It may be that you're trying
to run some executable, for example, OS/2's COPY command. See the
discussion in Launching programs.
This error message has a display level of 2.