In the last few months, I have written a series of articles introducing you to OS/2 REXX, EHLLAPI, and emulator screen parsing concepts, as well as OS/2 VREXX dialog functions. This article will combine all of those topics and also introduce another set of GUI functions to describe how a sophisticated desktop applicationan AS/400 monitor, for examplecan easily be created. By combining the simplicity of OS/2 REXX and the power of VREXX and EHLLAPI, you can create a desktop application (like the one shown in Figure 1) to continually monitor the CPU utilization of your AS/400. Before introducing the advanced VREXX windowing and draw functions, a review of requisite knowledge is in order.
REXX has been included with OS/2 as far back as V1.2 and has fast gained popularity with users as a quick and easy method of creating programs. Its syntax is very intuitive, and most users can pick it up simply by reviewing existing programs. Further, with a little effort and some help from one of the online references available with OS/2, you can become REXX-proficient in a matter of days.
You may already be familiar with REXX because its one of the languages available on the AS/400. In fact, implementations of REXX are available on most of the IBM platforms, including MVS and OS/2. In 1987, IBM declared REXX the procedures language for its Systems Application Architecture (SAA), solidifying its future in programming circles.
EHLLAPI allows a workstation program to interface directly with an emulator session in much the same way as a user would. The emulator session makes no distinction between keystrokes entered by the keyboard and those entered programmatically via a
program that makes EHLLAPI function calls. Further, data presented on an emulation screen with which a user interacts is equally available to the workstation program to copy, parse, or search. By performing programmatic interactions with the emulator session window minimized, the emulator interaction can be masked from the user. OS/2 supports EHLLAPI calls made from a simple REXX program which makes programmatically accessing your emulator data a breeze.
A workstation screen-parsing program types the keystrokes necessary to produce a terminal display, then actually reads the resulting display. This program operator, as its called in EHLLAPI circles, functions exactly as a user wouldit types keystrokes and reviews the output. A user can exploit this concept to create a workstation application that interacts with an emulator session to query system statistics or perform automated operations, for example.
VREXX for OS/2 REXX
Visual REXX for Presentation Manager, or VREXX for short, provides a robust suite of easily accessible GUI functions. With VREXX, your program can create windows, draw text and graphics in them, and display pop-up dialog boxes to display messages or receive user input. In other words, your program can continue to use standard REXX features, but the drab command line interface used to say text and pull user input is replaced with contemporary dialog boxes.
VREXX for OS/2 was introduced in the article A Visual OS/2 REXX Primer, which appeared in the January/February 1997 issue of Client Access/400 Expert. In that article, common dialog functions to invoke simple pop-up message and input boxes, as well as list and file boxes, were presented. In this article, advanced concepts such as windowing will be introduced, along with a new function set to support windowing and drawing. All of these features are available to a simple OS/2 REXX program.
VREXX lets a user create windows on an OS/2 workstation display by specifying the percentage of screen real estate a window will occupy, with the bottom left corner of the display being 0 percent and the top right corner being 100 percent. For example, to display a window occupying the center 50 percent of a display, the window create function call would specify 75 percent for the top, 25 percent for the bottom, 25 percent for the left, and 75 percent for the right. Figure 2 shows several windows. Window 1, for example, can be created specifying left and right values of 0 and 10, respectively. This tells VREXX that you want the window to occupy the 10 percent of the left-most side of the screen. Window 1 would have bottom and top values of 0 and 50, which positions it on the bottom half of the screen. Window 2 can be created by specifying left and right values of 25 and 75 and bottom and top values of 40 and 60. Window 3 requires left and right values of 40 and 100, and bottom and top values of 90 and 100.
Perhaps one of the most difficult concepts to grasp in VREXX drawing is window coordinates. A VREXX window is actually 1,000,000 separately addressable pixels. Lines have starting and ending addresses, polygons have corner coordinates, and so on. All points in a window are addressed using x,y coordinates, where the bottom-left point of the window has coordinates of 0,0, and the top-right corner has coordinates of 1000,1000.
To specify a line, polyline, or polygon, VREXX requires that the coordinates be bundled in a REXX stem variable and passed into the appropriate function. (For more information on stem variables, see A Visual OS/2 REXX Primer in the January/February 1997 issue of Client Access/400 Expert.) Figure 3 illustrates a polyline and the coordinates involved. In this example, four sets of coordinates are needed: 1,1; 3,7; 5,3; and 11,8.
The opportunities to exploit VREXX are endless. By combining dialog functions and windowing functions, a comprehensive application can be developed. One way to exploit this powerful functionality is to chart data in a window on a real-time basis. Consider the AS/400 pulse application illustrated in the OS/2 monitor sample program code in Figure 7. It continuously monitors an AS/400 and displays the results shown in Figure
1. It accomplishes this by combining VREXX and EHLLAPI functions to parse WRKSYSACT CPU screen output and continuously plot 100 samples on a dynamic graph. The routine invoked in this sample program is a slightly modified version of the code introduced in Harvesting Data from the AS/400 for Workstation Applications in the September/October 1996 issue of Client Access/400 Expert. Instead of writing the current CPU utilization to a log file, that code has been modified to return it to the calling program using an exit function like this:
exit Current_CPU * 10
Youll note that the CPU value is multiplied by 10 because our window charts 1,000 pixels. A point at the very top of the screen, where y=1000, would have a CPU value of 100 percent.
VREXX Window and Draw Function Reference
Ill describe some of the more useful VREXX windowing and draw functions. For a complete description of all of the VREXX functions, refer to the document titled Visual REXX for Presentation Manager included in the VREXX package. Before invoking VREXX functions, your REXX program must load and initialize VREXX. Refer to the VREXX sample code in Figure 7 for this procedure.
VREXX Windowing Functions
vOpenWindowvOpenWindow creates a new window and returns a window ID, which is used in subsequent functions that perform an action on the window. When a window is created, title and background colors are specified. The colors can later be changed with the vSetTitle and vBackColor and functions, respectively. The window dimensions are specified by a stem variable representing screen percentages, as illustrated in Figure 2. The code in the VREXX sample program code shows how to create a window in the top-right portion of the workstation screen. vResizevResize resizes and/or repositions a window on a workstation screen. It requires the window ID of the target window and a stem variable containing the new screen percentages. vCloseWindowvCloseWindow closes a window created with vOpenWindow. It requires the target window ID. vSetTitlevSetTitle changes the text in a windows title bar. The sample code in Figure 7 illustrates how to change title bar text. vColorBoxvColorBox allows a user to select window background and foreground colors from a selection dialog. Lines, arcs, fill patterns, and text use the foreground color for display. Figure 4 illustrates a color selection box. vColorBox sets the color stem variable to the users selection, where color.fore is the selected foreground color and color.back is the selected background color. Subsequent calls to vBackColor and vForeColor are necessary to actually make the colors change. A user can select and view a sample of various combinations of background and foreground colors. If OK is selected, the function returns the selected colors. vBackColorvBackColor sets a windows background color to either black, white, red, green, blue, cyan, yellow, or pink. A sample invocation would be: call vBackColor win_id, PINK
vForeColorvForeColor sets a windows foreground color (the color used to display lines, text, etc.) to either black, white, red, green, blue, cyan, yellow, or pink. A sample invocation would be:
call vForeColor win_id, BLACK
VREXX Draw Functions
vSayvSay draws a text string in the target window. The function requires three parameters: the target window ID; the x,y coordinate pair for the text starting point; and the text string. To draw a portion of the text displayed in Figure 5, the following code was used:
call VSay win_id, 50, 750, Line and Markers
vFontBoxvFontBox displays a dialog in which the user selects a font for subsequent vSay operations. vFontBox sets a stem variable to the users selection, where stem_name.type is the selected font type and stem_name.size is the selected font size. A call to vSetFont to pass in the selected font is necessary before the font will actually change. Figure 6 depicts a font selection box. A user can select and view various combinations of font types and sizes. If OK is selected, the function returns the selected font. vSetFontvSetFont changes the font the vSay function uses to display text. vSetFont requires three parameters: the target window ID, the font type, and the font size. The font type can be either SYSTEM, SYMBOL, COUR (Courier), HELV (Helvetica), or TIME (Times Roman). Fonts can be made bold and italic, as well. Using HELVI will produce Helvetica italics, HELVB creates Helvetica bold, and HELVBI produces Helvetica bold italics. The font size must be a positive integer greater than 0. A sample invocation is this:
call vSetFont win_id, HELV, 12
vDrawThe vDraw function draws pixels, lines, and polygons using the current marker, line, and fill values. vDraw requires four parameters: the target window ID; the function type (i.e., PIXEL, LINE, or POLYGON); the x,y coordinate pair stem names; and the number of coordinate pairs specified. For example, to create a box similar to the one illustrated in Figure 5, the function call would need to specify the four coordinate pairs representing the boxs corners. That function call might look like this:
x.1 = 650; y.1 = 900 /* top left */
x.2 = 900; y.2 = 900 /* top right */
x.3 = 900; y.3 = 350 /* bottom right */
x.4 = 650; y.4 = 350 /* bottom left */
call VDraw win_id, POLYGON, x, y, 4
To create a multi-coordinate line similar to the one illustrated in Figure 5, the function call would need to specify the four coordinate pairs representing the various points. That function call might look like this:
x.1 = 100; y.1 = 100
x.2 = 500; y.2 = 400
x.3 = 500; y.3 = 200
x.4 = 600; y.4 = 700
call VDraw win_id, LINE, x, y, 4
The sample program to chart CPU utilization in the VREXX sample program code actually plots 100 points on the window and connects them all to describe current and historical CPU utilization. vDrawParmsvDrawParms sets the current marker type, line type, and fill type that will be used for subsequent vDraw operations. For example, if vDrawParms specifies a line type of dashes, all subsequent lines drawn will be dashed and not solid. Coordinate marker types (the diamonds delimiting the line in Figure 5 are examples of markers) may be a cross, circle, plus sign, square, diamond, as well as a few other shapes.
Polygons and circles inherit fill patterns. The shapes in Figure 5 inherited a fill type of solid. Some other fill types that may be specified are no fill and horizontal lines.
For polygons and enclosed arcs (circles), a fill type can be specified. End points for lines can be highlighted by specifying a marker type. Refer to Visual REXX For Presentation Manager in the VREXX package for information on the enumerated values vDrawParms requires for its parameters. vArcvArc draws an arc or a complete circle using the radius; x,y center coordinates; and arc angles. To create the circle displayed in Figure 5, a call to vArc was made specifying the center x,y coordinates of 775,150 and a radius of 150. To accomplish a full circle, angle 1 and angle 2 were specified as 0 and 360 respectively. That function call looks like this:
call VArc win_id, 775, 150, 125, 0, 360
vClearWindowvClearWindow erases the contents of the specified window. The sample program to chart CPU utilization in the VREXX sample program code uses vClearWindow on each refresh cycle prior to drawing a new 100-point line.
Building Sophisticated GUIs with VREXX
As you can see, VREXX is a simple way to add a sophisticated GUI interface to your OS/2 REXX command line programs making simple function calls to add powerful graphics to any REXX program. With a little imagination, Im sure you can think of many ways you could use these tools in your shop.
IBMs EWS ftp site: ftp://software. watson.ibm.com/pub/os2/ews/vrexx2.zip ftp://members.aol.com/cmiksanek/ xmpvrex2.zip Newsgroup: comp.lang.rexx REXX EHLLAPI for Client Access/400 Optimized for OS/2, Client Access/400 Expert, March/April 1996
Harvesting Data from the AS/400 for Workstation Applications, Client Access/400 Expert, September/October 1996
A Visual OS/2 REXX Primer, Client Access/400 Expert, January/February 1997 OS/2 Procedures Language/2 REXX (available on softcopy in the OS/2 Information The REXX Language: A Practical Approach to Programming by Michael Cowlishaw, Prentice Hall (Cowlishaw is the designer of the REXX language.)
The REXX Language page at IBM Hursley: http://rexx.hursley.ibm.com/ rexx/rexx.htm Figure 1: AS/400 Pulse Monitor Window
Figure 2: Defining a VREXX Window Figure 3: Plotting Line Points via a VREXX Stem Variable
Figure 4: The vColorBox Dialog Figure 5: A VREXX Window and Simple Draw Object Types
Figure 6: The vFontBox Dialog
/* REXX */
This REXX program assumes VX_REAL.CMD is the
EHLLAPI routine which returns the current CPU
To use this .cmd, ensure VREXX is correctly
For best effect, create an OS/2 program icon
that is minimized on start-up and attach this
.CMD file to it.
VX_PULSE REAL OzMoeSYS C
| | |
| | +-> Emulator
| | Session ID
| +-> AS/400 System ID
| displayed in the
| pulse window
| title bar
+-> Operating mode: Real or
signal on failure name Failure_Exit
signal on halt name Halt_Exit
signal on syntax name Syntax_Exit
/* Get line input/parms */
parse arg Mode AS_400_ID Emulator_Session
Samples_Taken = 0
do FOREVER /* Only CNTL-C can stop :-) */
if mode = DEMO then do
samples.100 = RANDOM(1,1000)
do _pause = 1 to 99999; end _pause
call vx_real Emulator_Session
samples.100 = result
if result < 0 then signal Halt_exit
Samples_Taken = Samples_Taken + 1
new_text = Cur: ||Samples.100/10||%
call VSetTitle win_id, Win_Title||new_text
end /* Do forever */
/* Exit Routines */
say Halt exit
say Syntax exit
say Failure exit
/* Subroutines */
call RxFuncAdd VInit, VREXX, VINIT
initcode = VInit()
if initcode = ERROR then signal Cleanup_and_Exit
Create_Main_Window: win.left = 60; win.right = 100
win.top = 100; win.bottom = 80
win_title = AS/400 Pulse [Demo Mode]
if mode <> DEMO then
win_title = AS/400 Pulse for ||AS_400_ID
win_id = VOpenWindow(win_title, WHITE, win)
if Emulator_Session = then Emulator_Session = A
if Mode <> REAL then Mode = DEMO
if AS_400_ID = then AS_400_ID = [no AS/400 ID]
Initialize_Display_Matrix: samples.0 = 100
do i = 1 to samples.0
samples.i = 1
/* shift entries left, dropping samples.1 and prepping samples.100 for new sample */
do i = 1 to 99
z = i+1
samples.i = samples.z
Horizontally, the 1000-pixel window grid is
broken down into 100 reference points: 1, 10,
20, 30, etc.... The first point plotted is x=0
y=samples.1. The next point plotted is x=10
do i = 1 to 100
if i <> 1 then do
if i = 100 then l = 1000
else l = ( i-1 ) * 10
end /* i <> 1 */
else l = 1
x.i = l
y.i = samples.i
call VClearWindow win_id
call VDraw win_id, LINE, x, y, 100
This sample code plots and refreshes 100 points on a VREXX window. By calling another OS/2 REXX application, in this example an EHLLAPI emulator session parser, this application can dynamically chart AS/400 CPU utilization.
Figure 7: The OS/2 Pulse Monitor VREXX Program Code