Wednesday, February 15, 2017

Using API to test Help Panels

quhdsph api to diplay uim help module text

After publishing the post about how to create help text for display files using UIM several people messaged me that there is an IBM i API that can be used to test the help, without needing to add code to a display file. I have to admit I was unaware of the API, and am grateful to those who messaged me.

I decided to create a program to call the Display Help, QUHDSPH, API that way I can have a simple user interface to use, I only need to enter the variables I want and leave the rest with there defaults. I am going to show a very simple example here to illustrate how QUHDSPH can be used. As this is a simple example program a lot of the code I would add for myself, for validation etc. is not present.

For simplicity I am using a display file to enter the variables for the help module I want to see. There are other ways I could have done this, perhaps using a command instead, but I want this to be K.I.S.S compliant.

The source for my very simple display files looks like:

01  A                                      DSPSIZ(24 80 *DS3)
02  A                                      PRINT
03  A                                      ERRSFL
04  A                                      INDARA
05  A                                      CA03(03)
06  A          R SCREEN
07  A                                  1 30'TEST HELP PANEL GROUPS'
08  A                                      DSPATR(HI)
09  A                                  3  2'Help panel group  .'
10  A            ZHELPPNL      10   B  3 22
11  A                                  4  4'Library . . . . .'
12  A            ZPNLLIB       10   B  4 24DFTVAL('*LIBL')
13  A                                  5  2'Help module . . . .'
14  A            ZHELPMOD      32   B  5 22
15  A                                  6  2'Display type  . . .'
16  A            ZDSPTYPE       1   B  6 22DFTVAL('1')
17  A                                      VALUES('1' '2')
18  A                                  6 29'1=Window, 2=Full screen'
19  A                                 23  3'F3=Exit'
20  A                                      COLOR(BLU)

I am sure that most of us are fully familiar with the DDS for a display, but there are couple of things I do want to mention:

Line 3: Even though there is no validation for this display file I have added an error subfile, ERRSFL, rather than use a Message Subfile, to show messages.

Line 4: The INDARA denotes that I am using an Indicator Data Structure in the RPG program that uses this display file. This allows me to give the display file's indicators meaningful names, rather than just use the number.

Lines 12 and 16: The DFTVAL keyword means that this is the value that will be shown in the field when the display file is written to the screen.

Line 17: Using the VALUES keyword means that only these values can be entered into the field and accepted by the display file. Any other value will be rejected by the display file, and an error message will be displayed.

The RPG program is also very simple, let me start with the definitions:

01  **free
02  ctl-opt option(*nodebugio:*srcstmt:*nounref) ;

03  dcl-f TSTHLPPNLD workstn indds(IndDs) ;

04  dcl-ds IndDs qualified ;
05    Exit ind pos(3) ;
06  end-ds ;

07  dcl-pr QUHDSPH extpgm ;
08    *n char(52) const ;
09    *n char(4) const ;
10    *n char(8) const ;
11    *n char(55) const ;
12    *n char(20) const ;
13    *n char(1) const ;
14    *n char(8) const ;
15    *n char(8) const ;
16    *n char(8) const ;
17    *n int(10) ;
18  end-pr ;

19  dcl-s DisplayType char(1) ;
20  dcl-s ErrorCode int(10) ;
21  dcl-s HelpString char(52) ;

Line 1: **FREE means that this program is written in totally free RPG. Well, what else would I use?

Line 2: My standard control options.

Line 3: This is the definition of my display file. The INDDS gives the name of my Indicator data structure.

Lines 4 - 6: This is the small Indicator data structure, as I only to define one indicator.

Lines 7 – 18: This is the procedure definition for the QUHDSPH API program. I can tell this is a program due to the EXTPGM on line 7, and as I am calling this definition the same name as the program I do not have to give the program name in the EXTPGM keyword. I never give the procedure parameter variable names, therefore, I need to give no name or null, *N, instead.

Line 8: First parameter is the "Help identifier array". This consists of the help panel group name, 10 characters, the library it is in, 10 characters, and the name of the help module contained within, 32 characters. As I am only going to be displaying one help module I only need a parameter that is 52 long. I do not want the called program to change the value of parameter, therefore, I use the CONST keyword.

Line 9: As I only want to display one help module the "Number of help identifiers" must be 1. The API expects a binary four long variable, but I am going to put a hexadecimal value in a character four long parameter to achieve the same result.

Line 10: This is where it starts to get complicated. The documentation explains that this is an array of two elements that are both binary four long variables. I wanted to make this simple for me so I have made this parameter a character eight parameter, which is the equivalent of two binary four variables, and I will be moving a hexadecimal value to this parameter.

Line 11: "Full display title" is what will be displayed at the top of the Help module. I am going to pass one value to this no matter which panel group is used.

Line 12: If I was using a "Qualified search index object" I would pass the detail of it in this parameter.

Line 13: "Display type" is whether I want to display the help in a window or in a full screen. If it will not display in a window check your user profile as the value *HLPFULL in the User Options parameter, USROPT, will override it.

Line 14: I can decide where I want the "Upper left corner" of the help window to display. I am not going to give this so I will be passing a hexadecimal value of zeros.

Line 15: I can decide where I want the "Lower right corner" of the help window to display. I don't care so I will be passing a hexadecimal value of zeros.

Line 16: I could give where I want the "Cursor location" to be, but I will pass hexadecimal zeros and the API will display the cursor in the default location.

Line 17: If an error occurs in the API a value is returned to this parameter. As this is the only parameter that could contain a value returned by the API it cannot have the CONST keyword.

Lines 19 – 21: These are the variables I will use in the program.

And now onto the "action" part of the program.

22  dow (1 = 1) ;
23    exfmt SCREEN ;
24    if (IndDs.Exit) ;
25      leave ;
26    endif ;

27    HelpString = ZHELPPNL + ZPNLLIB + ZHELPMOD ;

28    if (ZDSPTYPE = '1') ;
29      DisplayType = 'N';
30    else ;
31      DisplayType = 'Y';
32    endif ;

33    QUHDSPH(HelpString :
34            x'00000001' :
35            x'0000000100000001' :
37            '*NONE' :
38            DisplayType :
39            x'0000000000000000' :
40            x'0000000000000000  :
41            x'0000000000000000' :
42            ErrorCode ) ;
43  enddo ;

Line 22: I have the "action" part of the program in a Do-loop, which ends on line 43.

Line 23: The record format in the display file is executed.

Lines 24 – 26: If the F3 key is pressed I quit the Do loop, and the program will end.

Line 27: I concatenate the name of Help panel group, the library the Help panel is in, and the Help module name, all into one variable.

Lines 28 – 32: If 1 was entered in the display file's "Display type field", for window, then I need to pass N to QUHDSPH. And I pass Y I want full screen, 2.

Lines 33 – 42: Here I am calling QUHDSPH. I have broken the parameters onto separate lines to make it easier to understand.

Line 33: Name of the Help panel, library and Help module.

Line 34: Hexadecimal 1 as I only want to display one Help module.

Line 35: As I explained for line 10 I am passing this hexadecimal value in a character field, rather than an array of two binary variables.

Line 36: Whenever I use this program I want this to be displayed at the top of the Help module.

Line 37: As I am not using a search index I need to pass *NONE.

Line 38: This will be how the help is displayed, see lines 28 – 32.

Line 39 – 41: I don't not care to give the positions for the window, therefore, I am just passing hexadecimal value of 0.

Line 42: If there was an error in QUHDSPH, then a value is returned to this variable.

When I run the program for a Help module this is what I see:

Click on image to see a larger version

This API is a good simple way to test Help panels, and I am sure I will be using in the future.


You can learn more about the QUHDSPH API from the IBM website here.


This article was written for IBM i 7.3, and should work for earlier releases too.


  1. Replies
    1. Thank you for the feedback. I do appreciate all feedback as it the only way I know that you find things like this interesting.

  2. Great program. I didn't know that the API to display the UIM panel existed. I had to add a colon and quote to statement 40, and I added *INLR=*on above statement 22 because my compiler didn't like that there was no way to determine the end of the program. Also I am missing the PTFS for **free even though I am on 7.2 with TR3. I just shifted everything to column 8 and beyond.

    1. Thank you for letting me know about the coding error on line 40, oops. I have corrected it.

      I decided to omit the *INLR = *ON line from the example as, in my opinion, what can I say about it that every RPG program does not know already. I would have placed it at the end of the program, but there is no reason why you could not place it where you decided to do so.

      You are right if you do not have the PTF for the totally free RPG you do need to start your code in the eighth column, and end it on or before the 80th.

      If I was you I would encourage your system administrator to get all of the current outstanding PTFs for your system. But wait until after March 31, as you want the ones for TR6 too [wink]


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.