Wednesday, September 2, 2015

Having a timeout on screen

dspf time out invite waitrcd maxdev

The germ for this post came from a comment made by Glenn Gundermann on last week's Display screens of results without having to press Enter:

How would you do it for the times you don't want to lock the keyboard? You might want to have a screen being displayed to allow the user to do actions but if they don't, perform an action after a timeout.

After a bit of playing I have a solution that will have a screen time out if someone does not press a key in a certain amount of time. This is just simple example to demonstrate the method I found. In the example the user will be presented with a screen they can either press Enter, F3 to exit, or do nothing. If they do nothing after two seconds the program will proceed and display a second screen.

This is the display file:

01  A                                      DSPSIZ(24 80 *DS3)
02  A                                      CA03
03  A                                      INDARA
04  A          R SCREEN1
05  A                                      INVITE
06  A                                  3  3'This is the first screen'
07  A          R SCREEN2
08  A                                  3  3'We are finished'

I am sure most of you are familiar with the keywords in the display file. Exceptions might be for the INDARA and the INVITE.

I discussed using the INDARA in No More Number Indicators, therefore, if are unfamiliar with INDARA I recommend you check the post out.

The INVITE keyword is described in the IBM documentation as:

To send an invite to a specific device, your program sends an output operation to the device with the INVITE keyword in effect.

The keyword can be used at the file or record format level. I want to use it at the record format for SCREEN1, as I do not want to use it with SCREEN2.

I compiled this display file with the following command. Notice that the 'Maximum record wait time' parameter, WAITRCD, is given. I have given two seconds. If you were using this in a "live" environment you would want to use a larger value.

  CRTDSPF FILE(MYLIB/TESTDSPF) SRCFILE(MYLIB/DEVSRC) 
            RSTDSP(*YES) DFRWRT(*NO) WAITRCD(2)

And now for the RPG, all free of course:

01  dcl-f TESTDSPF workstn indds(IndDs)
                             maxdev(*file) ;

02  dcl-ds IndDs qualified ;
03    Exit ind pos(3) ;
04  end-ds ;

05  dcl-s wkCount packed(3) ;

06  for wkCount = 1 to 10 ;
07    write SCREEN1 ;
08    read(e) TESTDSPF ;

09    if (%status  = 01331) ;
10      leave ;
11    elseif (IndDs.Exit) ;
12      *inlr = *on ;
13      return ;
14    endif ;
15  endfor ;

16  exfmt SCREEN2 ;

17  *inlr = *on ;

If you have to use RPG fixed format definitions you can see the code here.

The first thing to notice is the MAXDEV(*FILE) keyword on line 1. Officially this is to give the number of devices defined for the work station file. In reality it just has to be there.

Lines 2 to 4 are my indicator area data structure.

Line 5 is a work variable I will use in a FOR group, which start on line 6, if you are not familiar with the FOR group check out FOR replaces DO in RPGLE. This FOR group will be executed ten times if I press the Enter key.

To do this I cannot use EXFMT to display my display file record format SCREEN1. I have to use a WRITE to the record format, line 7, followed by a READ of the display file, line 8. I need to have an error extender on the READ.

I use the %STATUS built in function to check the program/file status, line 9. If it is "01331" then the time given in the CRTDSPF's WAITRCD parameter has been exceeded. I leave the FOR group on line 10.

If F3 has been pressed I quit the program, lines 11 – 13.

I can use EXFMT for SCREEN2 as there is no invite in that record format.

If you remember all the steps in both the display file and RPG, it is easy to create a similar timeout functionality in your own code.

 

More information about these keywords can be found on the IBM website...

 

This article was written for IBM i 7.2, and it should work with earlier releases too.


Fixed format definitions

01  FTESTDSPF  CF   E             WORKSTN indds(IndDs)
02  F                                       maxdev(*file)

03  D IndDs           DS                  qualified
04  D   Exit                  3      3N

05  D wkCount         S              3P 0
     /free

Return

4 comments:

  1. You may want to make your code more robust to avoid the CPF4737.

    http://www.mcpressonline.com/forum/forum/x-archive-threads-started-before-01-01-2002/programming-aa/4341-cpf4737-i-o-error-when-using-invite

    https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&cad=rja&uact=8&ved=0CC8QFjADahUKEwiUqtznyNjHAhVIiw0KHVaEDkQ&url=http%3A%2F%2Fforums.iprodeveloper.com%2Fforums%2Faft%2F11352&usg=AFQjCNHjN108tNQFdBJm4fYG17HK0x2IQg

    "Code an error indicator on the WRITE statement of the workstation, and use the major and minor code fields in the INFDS in pos 401-402 and 403-404 respectively. If the error indicator comes on and the major/minor value is '0412', then you simply need to READ the workstation file to clear then input buffer. Then you can WRITE again. Thanks to Gary Guthrie for this solution, a few years ago! "

    Chris Ringer

    ReplyDelete
    Replies
    1. Let me make the first URL a link here..

      The second link does not really go anywhere useful.

      Delete
  2. Please add CA03(03 'Exit') in the display file

    ReplyDelete
  3. I have specified the invite keyword to implement a screen refresh and that works fine, except that the invite seems to be blanking out my record format name which I am using to access a help function in the program.

    Is there anyone who has run into this issue, and if so is there any way around this problem

    ReplyDelete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.