MainframeSupports
tip week 14/2017:

One of my readers recently made me aware that my SCRNSHOT REXX does not work, if you are using a 3270 screen with a character width of 132. The variable ZSCREENW is correctly set to 132, but the contents of ZSCREENI is for many screens still build 80 characters wide. Total surprise. What are they thinking about at IBM??

I could not leave this challenge unattended so I have made an extended version of SCRNSHOT which in most cases is able to detect whether the contents of ZSCREENI is formatted for 80 or 132 character screen width:

/* REXX */
ARG LINECNT COLCNT REUSE
ADDRESS ISPEXEC "VGET (ZSCREENI ZSCREENW ZSCREEND ZSCREENC)"
ADDRESS TSO "ALLOC FI(SCRNSHOT) DA(SCRNSHOT) MOD CATALOG",
            " SPACE(1 1) TRACKS RECFM(F B) LRECL("ZSCREENW") REUSE"
DROP SCRNSHOT.
IF DATATYPE(LINECNT, 'W') = 0
THEN
  LINECNT = 1
IF DATATYPE(COLCNT, 'W') = 0
THEN
  COLCNT = 8
STARTPOS = ZSCREENC + 1
IF REUSE = ''
THEN DO
  SCRNSHOT = STARTPOS
  ADDRESS ISPEXEC "VPUT SCRNSHOT"
END
ELSE DO
  ADDRESS ISPEXEC "VGET SCRNSHOT"
  STARTPOS = SCRNSHOT
END
/* START EXTRA CODE TO DETECT SCREEN WIDTH */
WIDTH = 0
RULER = SUBSTR(ZSCREENI, 81, 54)' '
W = POS(' ', RULER) + 79
POSNO = 1
DO WHILE W < ZSCREENW
  WIDTH = W
  DO LINENO = 3 TO ZSCREEND
    IF SUBSTR(ZSCREENI, W * LINENO + 1, 1) <> ' '
    THEN DO
      WIDTH = 0
      LEAVE
    END
  END
  IF WIDTH > 0
  THEN
    W = ZSCREENW
  ELSE DO
    POSNO = POSNO + 1
    W = POS(' ', RULER, POSNO) + 79
  END
END
IF WIDTH = 0
THEN
  WIDTH = ZSCREENW
ELSE
  IF POS(COPIES('-', WIDTH - 1), ZSCREENI) > WIDTH + 2
  THEN
    WIDTH = ZSCREENW
COLCNT = MIN(WIDTH, COLCNT)
/* END EXTRA CODE TO DETECT SCREEN WIDTH */
DO LINENO = 1 TO LINECNT
  SCRNSHOT.LINENO = SUBSTR(ZSCREENI, STARTPOS, COLCNT)
  STARTPOS = STARTPOS + WIDTH
END
SCRNSHOT.0 = LINECNT
ADDRESS TSO "EXECIO * DISKW SCRNSHOT (STEM SCRNSHOT. OPEN FINIS)"
ADDRESS TSO "FREE FI(SCRNSHOT)"
ADDRESS ISPEXEC "EDIT DATASET(SCRNSHOT)"
EXIT

I have added a quite large chunk of code able to detect the screen width. The rule is that every line starts with a blank character. Normally the first character is a field attribute and stored as a blank in the screen buffer. I have also made an extra verification ensuring that the second line is a horisontal bar consisting of the right amount of dashes. These verifications ensures that it is highly likely that the variable WIDTH (which is used in the final loop) has the correct value compared to ZSCREENI. By the way I have tried to find a Z-variable containing the actual screen width used in ZSCREENI, but in vain.

There is no guarantee that the above improvements works in all cases. There might be panels where the first position in each line contains a characher not equal to space. There are lots of products which controls the way their ISPF panels are built and for these panels it might easily go wrong for the extra logic I have built in. If you have a better proposal of how to solve this challenge please let me know about it!

Previous tip in english        Forrige danske tip        Tip list