The answer is that panel groups offer significant advantages over display files,
especially when used in action-list applications (i.e., work-with panels). This article
discusses those advantages and explains how to use UIM in a list application. I also
provide the WRKUSR utility as an example of a list application that uses UIM. This
utility is useful in its own right and is available for download here — for a description of WRKUSR, see "The WRKUSR
Utility", below
Versatility. Panel group tag language is more versatile than DDS. It provides UIM (User Interface Manager)-specific commands, called dialog commands, that assign functions to list options and function keys in the panel-group source. UIM, a part of OS/400, is responsible for all operations related to panel groups. When you use dialog commands, you can leave list-option and function-key processing to UIM; you don't need to write the code to handle these requests. However, depending on the nature of your application and the action you assign to the option or function key, you may need to provide an exit program to assist UIM in its processing.
Ease of coding command lines. It's much easier to include a command line in a UIM panel than in a display file — simply specify a CMDLINE tag. A UIM-provided command line has all the facilities of a typical OS/400 command line. You can enter commands on it, prompt a command, and retrieve previous commands (using the appropriate dialog commands). You can even specify parameters for list options on the command line. UIM adds these parameters to the end of the list option's command string before executing the command. Providing these functions in a display file application requires many lines of code.
Easier list management. UIM lists are easier to fill than subfiles. You don't need to keep track of a subfile record number. UIM assigns every entry a unique identifier, called a handle, and uses the handle in all operations related to the list entry. If UIM invokes an exit program to perform an action on the list entry, UIM passes the handle to the exit program so it can access the entry.
Scrolling support is better in UIM, too. To add entries to an incomplete list, all you have to do is specify the exit program UIM calls. UIM handles everything else related to scrolling; you don't have to enable and disable scrolling keys, indicate whether there are more entries to see, or determine which entry should be at the top of the page. All UIM needs is for the exit program to tell it when the list is complete.
Longer list records. A subfile record is limited to the width of the display device on which it is shown; a UIM list has no such limitation. If you define a UIM list wider than the display device, you just specify which list columns should be displayed. You can show different views of the list one after the other by using the CHGVIEW dialog command — this is the service provided by the F11 function key in most OS/400 work-with panels.
A wider choice of languages. Not all high-level languages support subfiles. To use a subfile, you must develop it in a language that supports it, such as RPG or Cobol. But application programs interact with panel groups through APIs, so you can use any programming language that allows calls to APIs (and I can't think of any that don't) to develop a UIM application. In fact, panel groups are about the only means of displaying lists in languages that don't support subfiles.
Combined display and print panels. Unlike a DDS source member, a panel group can contain both display and print panels. The advantage of having both types of panels in the same object is data sharing. Once your program puts data into the panel group's variable pool, that data is available to all the panels. Consequently, you can print what a display panel shows without having to gather the information all over again.
Consistency. In panel groups, UIM, not the programmer, controls how
information in the panel is organized. UIM follows predetermined guidelines to ensure
panel consistency. Since IBM uses panel groups for most OS/400 panels, using such panels
in your own applications will give your displays a familiar look. Thus your users will
relate to them easily, especially if you assign list options and function keys those
functions commonly associated with them, such as 2=Change, 3=Copy, F3=Exit, F4=Prompt.
UIM provides a number of dialog commands that you can specify in certain attributes of several UIM tags. Dialog commands provide screen management functions (e.g., scrolling, displaying help modules) and programming-related functions. Three programming-related commands — CALL, CMD, and RETURN — deserve some attention here.
The CALL dialog command specifies that UIM call a program. The syntax for the command is CALL pgm-var, where pgm-var is a dialog variable that contains the name or address of the program to be called. The parameter passed to the program depends on the function for which it is called (e.g., whether to process a function key or a list option). I'll discuss this further later.
The CMD dialog command specifies that UIM submit a system command for processing. Its syntax is CMD cmd-string, where cmd-string is the command string to be processed. If the string contains dialog variables, UIM substitutes their current value into the command string before submitting it to the system. Each dialog variable must be preceded by an ampersand (&) and followed by a period (.). The command string can also contain prompt characters to make the system prompt the command before executing it.
The RETURN dialog command returns control to the application program that displayed the
panel from which the command was executed. The syntax is RETURN n, where n
is an integer. When UIM returns control to the application program, it places the value
n in the Function Requested parameter of the QUIDSPP (Display Panel) API, thus
providing a way for the program to process certain function keys, such as F5=Refresh.
A panel group has two sections — the prologue and the body. The prologue contains tags that define elements referred to later in the body, while the body contains tags that define the panels of the panel group. Figure 1 shows the required order of tags in the source for a panel group.
Variables in a panel group are called dialog variables. A dialog variable is defined by a VAR tag, which in turn refers to a CLASS tag that provides the variable's attributes — its type, length, and characteristics. The VAR tag also specifies an error status variable (if any) associated with the dialog variable. UIM automatically defines the error status variable as a one-byte character variable and sets the variable to 1 if the dialog variable is in error. An application program can also set the error status of a dialog variable during a put operation. If it sets the value to 1, UIM takes the variable to be in error. UIM uses reverse text to display variables in error.
Variable records are the structures through which application programs access dialog variables. A VARRCD tag defines a variable record. Its VARS attribute specifies the name (s) and order of the variables in the record. An application program cannot put or get information from a dialog variable except through a variable record. You specify the name of the variable record to use for the put or get operation as a parameter in the call to the appropriate API. The values you put or get must be in the same order as the variables in the record.
Lists are the UIM equivalents of subfiles. The LISTDEF tag defines a list, specifying the dialog variables within it. A list can have no more than 50 dialog variables. Each dialog variable contains a column of information. You don't have to display all the columns of a list; a LISTVIEW tag in a panel definition lets you specify which columns to display. You can use several LISTVIEW tags to define different views of a list.
All of a panel's active function keys must be defined. UIM does not automatically assign a function to any key, even the engraved keys (e.g., Enter, Print, Page up). A KEYI tag defines a function key. In the tag's ACTION attribute, you specify a dialog command to indicate the action UIM is to take when the key is pressed. The KEYI tags for a panel's function keys are grouped in a key list. The key list tag, KEYL, provides a name for the list. When defining the panel, you specify this name to refer to the function keys.
The panel group body contains the panel definitions. A PANEL tag begins the definition of a display panel and specifies the panel's name, help module, key list, and size. It also specifies a truth table (if any) for the panel, dialog variables to contain information about the location of the cursor when the panel is exited, and the action UIM should take if the user presses Enter and there is no request to process. The USREXIT attribute of this tag specifies a general exit program for the panel. UIM calls this program each time the user presses a function key or Enter and dialog variables or list entries have changed. The general exit program can perform additional validity checking or some other function. In the WRKUSR utility, the general exit program for the Position List panel positions the list to the entry specified by the user.
Within a list panel definition, you can define a data presentation area to provide information on the list. Tags for defining the depth, layout, and content of data presentation areas include DATA, DATACOL, DATAGRP, and DATAI. A DATA tag begins the definition of the data area and specifies the depth and layout of the area. A DATACOL tag defines a column in the data area. A data area can have two or three columns — the first for the prompt text, the second for the data, and the third (if specified) for the choices. A DATAI tag defines a data item displayed in the data area. It specifies the dialog variable from which UIM gets the value it displays and the prompt text for the item. If the data area has three columns, DATAC tags define the choices associated with each data item. DATAGRP tags specify how UIM should group data items.
A LIST tag begins the definition of a list area. A list area includes the lines for the legend of the list options, the column headings, and the rows of list entries. The LIST tag's LISTDEF attribute specifies the list from which UIM takes the data it displays in the list area. The ACTOR attribute specifies how the list options are processed — by either UIM or the application program. For non-action lists (i.e., lists that have no options), specify ACTOR=NONE. The PARMS attribute names a dialog variable in which UIM stores parameters entered on the command line for action list processing. This dialog variable will be included in the command string associated with the list options so that the parameters are added to the command before it's processed.
A LISTACT tag defines the action UIM performs on a list entry. The OPTION attribute assigns a number to the list action. This is the number the user types beside a list entry to request the specified action. The ENTER attribute specifies the action the UIM takes when the user presses Enter, and the PROMPT attribute specifies the action taken when the user requests the prompt function. You can specify either the CALL or CMD dialog command for these attributes. The USREXIT attribute names the exit program UIM calls after it performs the action specified for the ENTER or PROMPT attribute. Typically, the exit program updates or removes the list entry.
A LISTCOL tag defines a column in a list area. It specifies the dialog variable whose data UIM displays in the column. It also specifies the column's width and the text used as the column heading. A LISTVIEW tag specifies the list columns that are to be displayed together. You can use several LISTVIEW tags to define different views of a wide list. If you use list views, you'll also have to assign the CHGVIEW dialog command to a function key (e.g., F11), which the user can press to see each view of the list. You must specify at least one LISTVIEW tag in a list area definition.
A print head panel is required for UIM printing. It contains title text for the printout and information to be printed on every page. If there is data you want UIM to print on every page of a report, specify it in the print head panel. The PRTTRAIL tag, which can be specified only within the definition of a print head panel, provides text printed at the end of a report (e.g., END OF LISTING).
A PRTPNL tag begins the definition of a print panel. PRTPNL is similar to the PANEL tag for display panels but has fewer attributes and fewer tags available for use within the print panel definition. The PRTPNL tag specifies the name of the panel, its width, and its truth table (if any).
Figure 2 shows samples of the UIM tags discussed above. These are taken from the source of the WRKUSR utility panel group. Figures 3a and 3b show two of the utility's display panels, and Figure 3c shows a printout from its print panel. For more information on the UIM tag language and dialog commands, refer to Appendix 1.1 and Appendix 1.2 of Application Display Programming (SV41-3715 for V3R2; SC41-4715 for V3R6).
An application program for a UIM list application should perform the following tasks.
If the output is to be displayed, call the QUIDSPP (Display Panel) API to display the panel. If the panel is being displayed following refresh processing, have the application program set the list attribute so that the page being displayed when the function key was pressed is the page UIM displays. This is done before calling the API. Setting a page to display involves specifying the handle of the list entry at the top of the page in the Display Position Attribute parameter of API QUISETLA. The application program will need to get the handle of this entry using the QUIGETLE (Get List Entry) API before setting the list's attribute.
When the application program calls the QUIDSPP API, UIM assumes control and displays the panel. UIM also handles processing of the user's requests related to the panel. If the user chooses an option or presses a function key, UIM processes it. This may involve calling an exit program that returns control to UIM when it is through. For example, if the user attempts to scroll beyond the last entry in an incomplete list, UIM calls the list extension exit program for more entries. The application program is not notified. When the exit program marks the list complete, UIM changes "More . . ." at the lower right corner of the screen to "Bottom." UIM returns control to the application program only when it processes a RETURN, EXIT, or CANCEL dialog command in the first panel of the application.
Generally speaking, all user programs called by UIM are exit programs. These include programs called as a result of the CALL dialog command, programs specified in the USREXIT attribute of a panel definition (PANEL) or list action (LISTACT) tag, and programs called to add more entries to an incomplete list. All exit programs are specified by naming a dialog variable that refers to the program to call.
The definition of the dialog variable determines whether UIM calls the program by address or by name. If the dialog variable is defined as a pointer, the call is by address. This is the most efficient way of calling a program, but to use it, the application program must be developed in a language, such as C/400 or Pascal, that supports pointers. If the dialog variable is defined as a 20-byte character variable, the call is by name. The first 10 bytes contain the name of the program, and the second 10 bytes contain its library or the special value *LIBL or *CURLIB. If the dialog variable is defined as a 130- byte character variable, the call is in the extended program model environment. This is the least efficient way of calling an exit program. Unless you are pushed against a wall, do not use this type of call.
The parameter UIM passes an exit program depends on two things: the type of exit parameter interface for the application, and the function for which the exit program is called. You specify the type of exit parameter interface in the Exit Parameter Interface parameter of the QUIOPNDA or QUIOPNPA API. Using this parameter, you can request that UIM pass either a single parameter structure or multiple parameters to exit programs. It's more efficient for UIM to pass a single parameter structure simply because it's easier to manage information on a single location in memory than on several different locations. The rest of this discussion assumes the single-parameter case.
The content of the parameter structure depends on the function for which UIM calls the exit program. Figure 5 shows the various parameter structures for the different calls of exit programs. Notice that the first four fields in all the structures are the same, so rather than specify a different exit program for each type of function, you can have a single exit program handle all the different requests. This program will use the value in the parameter structure's Type of Call field to determine the function UIM requested. It may then call a service program to process the request. The advantage of this approach is that you need to define only one dialog variable for the exit program. If you had several exit programs, you would need to define several dialog variables, and your application program would need to make several calls to API QUIPUTV to update each of them.
The WRKUSR utility has a single exit program, WRKUSRXC (Figure 6), which receives the parameter structure, determines the function requested, and calls the appropriate service program to process it. The service program may display or print a panel, causing control to return to UIM, which may then call the exit program again to process another request on the new panel. As you can see, the exit program may be called several times for different functions during processing, and you should bear this in mind when designing your application.
For example, if a user presses F17=Position to on the Work with Users panel, UIM calls WRKUSRXC for function key processing. WRKUSRXC determines that the user pressed F17 and calls service program WRKUSRX1C to service the request. This program displays the Position List panel (Figure 3b) with a call to the QUIDSPP API. At this point, UIM regains control. When the user specifies the entry to position the list to and presses Enter, UIM again calls exit program WRKUSRXC, this time as a general panel exit program. WRKUSRXC in turn calls service program WRKUSRX2C to position the list. Although control passes back and forth, the operation goes so smoothly that you don't realize several programs are involved.
I use a general panel exit program call to position the list so that if an error occurs while the list is being positioned, UIM redisplays the Position List panel (with the appropriate error message). Had I used a function key processing call or some other exit program call, the Position List panel would not be redisplayed when an error occurs. Rather, the user would be returned to the Work with Users panel and would have to press F17 again to get back to the Position List display.
For more information about the UIM APIs and exit programs, refer to Chapters 58 and 59 of System Programmers Interface Reference (SC41-8223 for V2R3) or Chapters 67 and 68 of System API Reference (SC41-3801 for V3R2; SC41-4801 for V3R6).
The WRKUSR utility offers an alternative way of working with user profiles. It presents a
panel similar to IBM's Work with User Profiles panel, but with several additional
features.
WRKUSR utility has many objects — 14 in all. To create each one manually could be a
burden, so I also provide a source member, CRTWRKUSR, that contains the create commands
for the objects. You can compile this member into a CL program, which you can then call
to install the utility.
— A.O.
1. Create the commands:
CRTCMD CMD(library/DUPUSRPRF) +
PGM(DUPUSPFC) +
SRCFILE(QCMDSRC) +
HLPPNLGRP(DUPUSPFH) +
HLPID(*CMD)
CRTCMD CMD(library/RNMUSRPRF) +
PGM(DUPUSPFC) +
SRCFILE(QCMDSRC) +
HLPPNLGRP(DUPUSPFH) +
HLPID(*CMD)
2. Create help panel group DUPUSPFH:
NLGRP PNLGRP(library/DUPUSPFH) +
SRCFILE(QPNLSRC)
3. The next step is to create the processing programs. But first, notice that CL program
DUPUSPF1C contains some commented-out lines that contain the annotation "V3.1."
These lines reflect changes IBM made to the CRTUSRPRF (Create User Profile) command in
Version 3 of OS/400. If you're on Version 3, remove the comment marks from these lines
before creating the program. Then create the processing programs using the following
commands:
LPGM PGM(library/DUPUSPFC) +
SRCFILE(QCLSRC)
CRTCLPGM PGM(library/DUPUSPF1C) +
SRCFILE(QCLSRC)
CRTRPGPGM PGM(library/DUPUSPFR) +
SRCFILE(QRPGSRC) Azubike Oguine is an associate analyst with Chevron Nigeria, Ltd., in Lagos, Nigeria. You can reach him by e-mail at azub@chevron.com; by phone at (234) 12600600, extension 8047; or by fax at (234) 12600395.