In the last two installments (DSM lets you build screens and windows on the fly and How to save, restore the screen...
-- the quick and easy way) we explored the use of Dynamic Screen Manager (DSM), which comprises a large set of APIs. Specifically, in the last installment, we saw how quick and simple it is to save and restore the screen using two DSM APIs, QsnSavScr and QsnPutBuf. The only drawback was that it required your application to be written in an ILE language. Here, we will introduce a "helper" program you can put to use immediately to accomplish the same thing from a non-ILE program.
The helper program takes care of the calls to the DSM APIs. The key to making this work is to write the helper program in an ILE language.
The program shown below, SAVE_RST, is a short ILE CL program. It can be called from any program, be it ILE or non-ILE. The program is easily translated to ILE COBOL or ILE RPG, either of which will increase the performance considerably. Below that is the RPG version, SAVE_RST.RPG.
pgm parm(&Buffer &SaveOrRst) DCL VAR(&Buffer) TYPE(*char) LEN(4) DCL VAR(&SaveOrRst) TYPE(*char) LEN(1) IF (&SaveOrRst = 'R') + /* Restore screen. */ + CALLPRC PRC('QsnPutBuf') PARM(&Buffer *OMIT *OMIT) ELSE + /* Save screen. */ + CALLPRC PRC('QsnSavScr') PARM(&Buffer *OMIT *OMIT *OMIT) return
* c *entry plist c parm Buffer 4 c parm SaveOrRst 1 * * c SaveOrRst ifeq 'R' * * Restore screen c call 'QsnPutBuf' c parm Buffer * c else * * Save screen c call 'QsnSavScr' c parm Buffer * c endif * * * Return without LR on. c return *
The program parameters
The program accepts two parameters, Buffer and SaveOrRst. The Buffer parameter is just a 4-byte space DSM uses to store the address of the internal buffer where it stores the screen information. Simply declare a 4-byte field in the calling program for this parameter; the calling program should not manipulate the contents of this field in any way.
The SaveOrRst parameter controls the operation of the helper program; if it is an 'R' the program restores the screen, otherwise the screen is saved. This may seem a bit backward but it helps guard against accidental restore operations which may generate an escape message (while they may still be incorrect, accidental save operations generally will not cause an escape message).
How to use the program
Using this helper program is easier than using the DSM APIs themselves. Simply call it once to save the screen (by setting the SaveOrRst parameter to something other than 'R', such as 'S'). Then call it again with the SaveOrRst parameter set to 'R' to restore the screen. It can be called any number times to restore the saved screen.
Below is a sample RPG program, T_SAVRST.RPG, that shows how to use this helper program. After calling SAVE_RST to save the screen, the program writes a display file record to the screen. Before going into a long processing loop, the programmer wishes to restore the original screen, which is accomplished by calling SAVE_RST again with the SaveOrRst parameter set to 'R'.
* FTEST CF E WORKSTN * * * Save screen. C CALL 'SAVE_RST' C PARM BUFFER 4 C PARM 'S' SORR 1 * * * ---------------------------------------------- * Call to screen-altering program here. * Test with WRITE OF TEST DSPF. * C WRITEREC C '1' IFEQ '0' C READ REC 99 C ENDIF * ---------------------------------------------- * * * Restore screen. C CALL 'SAVE_RST' C PARM BUFFER 4 C PARM 'R' SORR 1 * * ----------------------- * Long processing here. * ----------------------- * C 1 DO 300 I 70 C Z-ADD3456 Z2 50 C SQRT Z2 Z 50 C ENDDO * * * ------------- * EXFMT here. * ------------- * * * C RETRN *
The only thing you have to be careful about is calling other programs that use DSM in between calls to SAVE_RST. These programs can cause the DSM environment to change, thereby destroying the previous contents of DSM's internal buffers.
To get around that, create the SAVE_RST program to run in a named activation group. This is done by specifying DFTACTGRP(*NO) and ACTGRP(name) on the CRTBNDCL command (or the CRTBNDCBL command for COBOL or the CRTBNDRPG command for RPG).
DFTACTGRP(*NO) specifies that the program is not to run in the default activation group -- the activation group that supports OPM (Original/Old Program Model) programs. Instead, the program will run in its own activation group identified with whatever name you provide on the ACTGRP parameter. As long as the helper program does not execute an operation that causes the activation group to end (e.g., *INLR = 1 in RPG) -- and none of the programs discussed here do -- the activation group will remain active until the job ends or it is deleted using the Reclaim Activation Group (RCLACTGRP) command.
About the author: Ron Turull is editor of Inside Version 5. He has more than 20 years' experience programming for and managing AS/400-iSeries systems.