Screen Shots in Advanced Revelation

Published ByDateVersionKnowledge LevelKeywords
Revelation Technologies16 MAY 19902.XEXPERTCAPTURED, KEYSTROKES, CRT, SNAPSHOTS, KEYSTROKE, CAPTURE, SCREEN, V87

A previously undocumented feature of the Keystroke Capture utility allows you to take snapshots of any portion of the CRT. These snapshots can be used to produce screen images for documentation, to display them during a tutorial or demo, or to use them in testing. This Technical Bulletin explains how to use this feature.

Note: The screen shot feature of keystroke capture is available in all releases of Advanced Revelation 1.1 or higher.

You can capture a screen image only while capturing keystrokes. To take a screen shot follow these steps:

  1. Start the capture keystroke utility through the menu or by pressing [Alt-0].
  2. When the Start Capture window appears, enter the name that you will assign to the capture set.
  3. Perform the steps necessary to display the image you wish to capture.
  4. Press [Alt-8] to suspend the capture process and invoke the capture editor.
  5. In the capture editor window, press [Alt-F8] to invoke the screen shot program.
  6. You are now looking at the underlying screen image. Note the single borders around the screen. These borders can be resized ([Ctrl-F7]) and moved ([Ctrl-F8]). By default, you are initially placed in Resize mode.
  7. Once you have positioned the borders, press [F9] to take the snapshot. Everything within the borders will be part of the captured image. If any border is at the edge of the screen, the snapshot will include the characters hidden by the border.
  8. Repeat steps 2 and 4 through 7 as many times as necessary to get your screen images.
  9. Press [Alt-0] again to terminate the keystroke capture process and save the capture set and images.

All of your snapshots are stored in the CAPTURED file with the key captured_name.SNAP, where captured_name is the name of your captured keystroke set. For example, if you named the captured keystroke set SAMPLE, the screen shots you have taken are in the CAPTURED file in the record SAMPLE.SNAP.

All the pictures taken during the session will be in the same record. Each field in the record is a different picture. The values in each field have this layout:

ValueDescription
1Left column (x) coordinate
2Top row (y) coordinate
3Right column (x) coordinate
4Bottom row (y) coordinate
5+Screen image

Because the screen image is stored as part of a dimensioned array, it cannot contain field marks. If a field mark is displayed on the screen when you capture it, the resulting captured_name.SNAP record will be corrupted.

The captured image may contain lower-level delimiters, though, including value marks. Because of this, you should not assume that the image will be in only the fifth value of a field.

Figure 1 is a program that demonstrates how to display the stored images on the screen. The program prompts the user first for the name of a screen image record. The program counts the number of images in the record, parses up each image, and then calls VIDEO.RW to display the image on the screen one at a time. This code also illustrates a method of extracting the screen images that accounts for the possibility of value marks in the image.

When the screen image is captured, the captured keystroke set is modified to mark a reference to the image. This takes the form:

@S V87,captured_name.SNAP@

V87 is a dummy program in the VERBS file that does nothing. The idea is that if you wish to make use of the captured image, you can substitute your own routine for the dummy V87. The capture playback process will call your routine and pass it the name of the record containing the captured images.

Figure 2 is a sample program that might be used in a testing system. For the sample, assume the programmer has developed a captured keystroke set, and in the process of creating the set has taken snapshots of parts of the screen. The screen images are stored in a file called ORIG_IMAGES.

During execution of the keystrokes, the programmer wants to know whether the screen is still the same. The program compares what is currently displayed on the screen with what was displayed on the screen when the captured set was first created. If there are any differences, an error record is logged.

The program maintains a labeled common area called /PICTURE/. This stores the number of the next screen image. Because of the way V87 is called, the program knows the name of the record that contains all the screen images but not the field number of the image to process. To move sequentially through the images, the program has to maintain its own counter in a global variable.

You could extend a program such as this one to display both the original image and the current image by using the information found in the error log.

Note that the program as written is color sensitive. That is, if the original image was captured on a color monitor but the keystroke set was executed on a monochrome monitor, the test would fail, even though the screens looked the same. Also note that this program is sensitive to data displayed on the screen that is supposed to change, such as dates and times.

The image stored by the snapshot feature contains the extra video information used by the system. These color attribute bytes are not needed if you print the image to a printer in fact, they will confuse the printer. Figure 3 is a program that removes the attribute bytes from the image and then prints the image to a printer.

Figure 1

*
* A program to display captured images on the screen.
*
DECLARE SUBROUTINE FSMSG, MSG, VIDEO.RW, INPUT.CHAR

EQU UCOL$  TO 1 ;* left col coordinate
EQU UROW$  TO 2 ;* top row coordinate
EQU LCOL$  TO 3 ;* right col coordinate
EQU LROW$  TO 4 ;* bottom row coordinate
EQU IMAGE$ TO 5
EQU ESC$   TO @INT.CONST<1>

OPEN CAPTURED TO FILE_CAPTURED ELSE
  FSMSG() ; * this subroutine is available beginning with Version 2.0
  STOP
END

REPLY =''

TEXT = 'Please enter the name of the screen shot record.|'
TEXT<-1> = "(The record must end in '.SNAP')"
MSG(TEXT, 'RCE', REPLY,'' )

IF REPLY <> ESC$ THEN
  READ SNAPSHOT FROM FILE_CAPTURED, REPLY THEN
     CNT = COUNT(SNAPSHOT, @FM) + (SNAPSHOT <> '')
     FOR CNTR = 1 TO CNT
       LEFT   = SNAPSHOT<CNTR, UCOL$>
       TOP    = SNAPSHOT<CNTR, UROW$>
       RIGHT  = SNAPSHOT<CNTR, LCOL$>
       BOTTOM = SNAPSHOT<CNTR, LROW$>
       *
       * first store away whatever is on the screen
       VIDEO.RW(LEFT, TOP, RIGHT, BOTTOM, 'R', VID_IMAGE)
       *
       * fetch the stored image, accounting for the possiblity of
       * value marks in the image.
       POS = INDEX(SNAPSHOT, @VM, 4)
       SNAPSHOT[1,POS] =''
       *
       * now display the image
       VIDEO.RW(LEFT, TOP, RIGHT, BOTTOM, 'W', SNAPSHOT)
       *
       * pause to let the user look at it
       INPUT.CHAR(DUM)
       *
       * restore previous image
       VIDEO.RW(LEFT, TOP, RIGHT, BOTTOM, 'W', VID_IMAGE)
     NEXT CNTR
  END ELSE
     FSMSG() ; * 2.0-specific routine
  END
END
STOP

Figure 2

SUBROUTINE V87 (INBASKET)
*
* customized version of V87 (screen shot playback routine)
* the parameter INBASKET passes the name of the record containing
* the captured screen images (all images are in one record).
*
DECLARE FUNCTION UNASSIGNED
DECLARE SUBROUTINE FSMSG, VIDEO.RW

EQU UCOL$  TO 1 ;* left col coordinate
EQU UROW$  TO 2 ;* top row coordinate
EQU LCOL$  TO 3 ;* right col coordinate
EQU LROW$  TO 4 ;* bottom row coordinate
EQU IMAGE$ TO 5
EQU ORIG$  TO ORIG_IMAGES ; * file name for stored images
EQU LOG$   TO ERROR_LOG

* the labeled common area stores the next image (field number) to process
COMMON /PICTURE/ PIC_CNT@

IF UNASSIGNED(PIC_CNT@) THEN
  * this is the first time through the code -- initialize the
  * common area.
  PIC_CNT@ =
END

ERROR =''

IF PIC_CNT@<1> <> INBASKET THEN
  * here is a new captured set being run. Initialize the counter and store
  * the name of the captured set.
  *
  * the common area has this layout:
  *
  * <1> original stored screen image
  * <2> counter (field number) of next image to examine
  *
  PIC_CNT@<1> = INBASKET
  PIC_CNT@<2> = 1
END

IMAGE_CTR    = PIC_CNT@<2>
STORED_IMAGE = XLATE(ORIG$, INBASKET, IMAGE_CTR,'X')
PIC_CNT@<2>  = IMAGE_CTR+1

IF STORED_IMAGE THEN
  LEFT   = STORED_IMAGE<1,UCOL$>
  TOP    = STORED_IMAGE<1,UROW$>
  RIGHT  = STORED_IMAGE<1,LCOL$>
  BOTTOM = STORED_IMAGE<1,LROW$>
  *
  * get the currently-displayed screen image at these coordinates. the
  * variable ON_SCREEN will be loaded with the current image.
  VIDEO.RW(LEFT, TOP, RIGHT, BOTTOM, 'R', ON_SCREEN)
  *
  * compare the original image and the on screen image
  CURRENT_IMAGE = FIELD(STORED_IMAGE, @VM,5,99999)
  IF CURRENT_IMAGE = ON_SCREEN THEN
     *
     * this program won't report that everything matched, although it could.
     *
  END ELSE
     ERROR = 'Image ': IMAGE_CTR :' doesn't match original.'
     ERROR<2> = STORED_IMAGE
     ERROR<3> = ON_SCREEN
  END
END ELSE
  ERROR = 'Image' : IMAGE_CTR :' missing for ': INBASKET
END

IF ERROR THEN
  * update the error log
  OPEN LOG$ TO FILE_LOG THEN
     WRITE ERROR ON FILE_LOG, COMPARE*:TIMEDATE() ELSE
        FSMSG() ; * 2.x only
     END
   END ELSE
     FSMSG() ; * 2.x only
   END
END
RETURN

Figure 3

*
* program to print captured images to the printer
*
DECLARE SUBROUTINE FSMSG, MSG

EQU IMAGE$ TO 5
EQU ESC$ TO @INT.CONST<1>
EQU FORMFEED$ TO CHAR(12)

OPEN CAPTURED TO FILE_CAPTURED ELSE
  FSMSG() ; * version 2.x-specific routine
  STOP
END

REPLY =''
MSG('Please enter the name of the screen shot record.|','RCE', REPLY,'')

PRINTER ON

IF REPLY <> ESC$ THEN
  READ SNAPSHOT FROM FILE_CAPTURED, REPLY THEN
    CNT = COUNT(SNAPSHOT, @FM)+ 1
    FOR CNTR = 1 TO CNT
      MSG('Printing screen %1% of %2%.','UB', MSG_IMAGE, CNTR:@VM:CNT)
      LINE_LEN = (SNAPSHOT<CNTR,3> - SNAPSHOT<CNTR,1>)+ 1
      WORKING = FIELD(SNAPSHOT<CNTR>, @VM, 5, 99)
      WORKING_LEN = LEN(WORKING)
      PRINT_LINE =''
      *
      * Note the STEP 2 in the following FOR..NEXT loop. This allows
      * the program to skip the video attribute bytes in the print image.
      FOR CNTR2 = 1 TO WORKING_LEN STEP 2
        PRINT_LINE := WORKING[CNTR2,1]
        IF LEN(PRINT_LINE) = LINE_LEN THEN
           PRINT PRINT_LINE
           PRINT_LINE =''
        END
      NEXT CNTR2
      MSG('','DB',MSG_IMAGE,'')
      *
      * The following line ensures that all images print on separate
      * pages.
      *
      PRINT FORMFEED$
    NEXT CNT
  END ELSE
    * read failed
    FSMSG() ; * Version 2.0-specific routine
  END
END
PRINTER OFF
STOP
  • tips/revmedia/r54.txt
  • Last modified: 2024/06/19 20:20
  • by 127.0.0.1