This procedure displays a popup menu and let the user select between a max of 15 options.
You can select between various styles of presenting the menu, various border types and various locations on the screen. When the user have selected an option, the option number is returned to the caller.
The menu is dynamic and adapt it’s size to the number of options, the width of the Title, Footer, F-key text and the Options. This is possible as the popup procedure makes call to the Dynamic Screen Manager to create and maintain the popup window. The procedure is written in Totally Free RPG.
The Popup Menu procedure supports screen sizes *DS3 (24×80) and *DS4 (27×132).
Download:
- Source members as text files: PopMnuSources
The zip file contains the source members. Extract the source files and transfer them to your IBM i.
To display a popup menu to the user, and manage it, you must call the PopupMenu() procedure with the parameters:
PopupMenu(location: row: col: border: style: remove_menu: title: header: footer: fkey_text: options(15))
Where the parameters are:
- location
The location where to display the menu:
pmLocationCenter
The menu will be centered on the screen.
pmLocationCursor
The menu’s top left corner will be displayed just below the cursor.
pmLocationRowCol
The menu’s top left corner will be display at row given in parameter ROW and column given in parameter COL. - border
The layout of the popup menu border:
pmBorderDefault
If the terminal supports GUI, then the border is displayed with a GUI standard border. If the terminal only supports character mode, then the border is displayed using characters.
pmBorderReverseBlue
No matter if the terminal supports GUI or not, the border is displayed in Reverse Image in blue colour.
pmBorderReverseGreen
No matter if the terminal supports GUI or not, the border is displayed in Reverse Image in green colour.
pmBorderAlert
No matter if the terminal supports GUI or not, the border is displayed in Reverse Image in red colour. - style
The selection style of options:
pmStyleClassic
The options are presented as a traditional menu. They are numbered (done by the PopupMenu() procedure), an input field is displayed where the user must enter the number of the requested option.
pmStyleCursor
The options are presented as a list. The user must selected by moving the cursor to the requested option, and press the [ENTER] key.
pmStylePushBtn
The options are presented as a list of push buttons. The user must use either the mouse or the [TAB] and [BACK-TAB] keys to move to the requested option and then either use the mouse to select or by pressing the [ENTER] key. If the terminal supports GUI, the push buttons are displayed as GUI push buttons. If the terminal does not support GUI, the push buttons are displayed as text buttons. - remove_menu
If set to *On the menu is removed from the screen before the procedure returns.
If set to *Off the menu is left on the screen and it is caller’s responsibility to re-draw the screen. - title
A text to display as the title of the window showing the popup menu. Can be a max of 70 characters.
If you do not want a title to be displayed, then just the field to ” (empty character field). - header
The header is displayed as the first line in the popup menu window. Can be a max of 70 characters.
If you do not want a title to be displayed, then just the field to ” (empty character field). - footer
The footer is displayed under the list of options. Can be a max of 70 characters. A blank line is added between the list of options and the footer.
If you do not want a footer to be displayed, then just the field to ” (empty character field). - fkey_text
The fkey_text is displayed under the footer. It is displayed in blue colour and it can be a max of 70 characters. If no footer then the fkey_text is displayed under the list op options.
If you do not want a fkey_text to be displayed, then just the field to ” (empty character field). - options(15)
The options that is displayed in the popup menu. It is a character array of 15 elements, of 70 characters.
At least one option must be filled in the array. The array must be filled from the beginning and it must be filled without ‘holes’. When presented, the options are considered to terminate at the first blank/empty element.
PopupMenu() returns an integer:
- A value greater than *Zeros
The number of the option that the user selected. - pmResultNoSelection
The user pressed F3 or F12 to cancel the menu. - pmResultNoOptions
There are no options in the Options array. - pmResultBorderInvalid
The value for the border is invalid. - pmResultStyleInvalid
The value for the style is invalid. - pmResultColInvalid
The value for the column is invalid. - pmResultRowInvalid
The value for the row is invalid. - pmResultLocationInvalid
The value for the location is invalid. - pmResultAPIError
One of the APIs returned an error when called.
A big thanks to to Scott C. Klement for creating the original QSNAPI_H source member and releasing it.
Have fun 🙂
Listing 1, member POPMNU_PR, type RPGLE:
**Free
//
// PopMnu_Pr
// ---------
// Prototype for function PopupMenu() that shows a popup menu and lets
// the user select an option.
//
// Jesper Wachs, Version 1, December 2018.
//
// The source member are delivered 'as is'.
//
// Neither Jesper Wachs nor anyone else who has been involved in
// the creation, production or delivery of this product shall be
// liable for any direct, indirect, consequential or incidental
// damages (including damages for loss of business profits,
// business interruption, loss of business information, and the
// like) arising out of the use or inability to use such product
// even if Jesper Wachs has been advised of the possibility of
// such damages.
//
Dcl-PR PopupMenu Packed(3:0);
iLocation Packed(3:0) Const;
iRow Packed(3:0) Const;
iCol Packed(3:0) Const;
iBorder Packed(3:0) Const;
iStyle Packed(3:0) Const;
iRmvMenu Ind Const;
iTitle Char(70) Const;
iHeader Char(70) Const;
iFooter Char(70) Const;
iFKeyText Char(70) Const;
iOptions Char(70) Const Dim(15);
End-PR;
//
// The procedure PopupMenu must be called with these parameters:
//
// PopupMenu(
// location: Controls where the popup menu is to be
// displayed. See constants for details.
// row: If location is pmLocationRowCol then set this
// to the row (1 - 27). Otherwise, set to zero.
// col: If location is pmLocationRowCol then set this
// to the col (1 - 132).Otherwise, set to zero.
// border: The type of border to display around the
// popup menu.
// style: The style of the menu.
// pmStyleClassic will display a option number
// in front of the option. An entry field to enter
// the option number is displayed. Selection is
// done by entering the number and pressing the
// ENTER key.
// pmStyleCursor will display the options centered
// in the window. Selection is done by moving the
// cursor to the option in question and pressing
// the ENTER key.
// pmStyleBtn will display each option as a push
// button either in GUI or Text mode, depending
// on the terminal (emulator) capabilities.
// Selection is done by clicking on the push
// button in question with the mouse or using the
// arrow keys and pressing the ENTER key.
// rmvmenu: Set to *On to remove the popup menu after
// the user have made a selection. Set to *Off
// to leave the popup menu on screen. This will
// require that caller redraw the screen to
// remove the popup menu.
// title: The title of the popup menu. Is displayed in
// top of the border of the popup menu. Can be
// set to *blanks.
// header: The header for the menu options. Is displayed
// at the top of the popup window above the
// menu items. Can be set to *blanks.
// footer: The footer for the menu options. Is displayed
// just below the menu options. Can be set to
// *blanks.
// fkeytext: Aline to be display with F-keys. The line will
// be displayed in blue colour.
// options: An array with 15 options. The options must be
// filled from the begining of the array.
// Not used options must be set to *blanks.
// )
//
// Constants
// ---------
//
// pmLocation*
// -----------
// The place to display the menu.
//
// pmLocationCenter:
//
Dcl-C pmLocationCenter Const(1);
//
// pmLocationCursor:
//
Dcl-C pmLocationCursor Const(2);
//
// pmLocationRowCol:
//
Dcl-C pmLocationRowCol Const(3);
//
// pmStyle*
// --------
// The style of the menu.
//
// pmStyleClassic:
//
Dcl-C pmStyleClassic Const(1);
//
// pmStyleCursor:
//
Dcl-C pmStyleCursor Const(2);
//
// pmStylePushBtn:
//
Dcl-C pmStylePushBtn Const(3);
//
// pmBorder*
// ---------
// The border of the menu.
//
// pmBorderDefault:
//
Dcl-C pmBorderDefault Const(1);
//
// pmBorderReverseBlue:
//
Dcl-C pmBorderReverseBlue Const(2);
//
// pmBorderReverseGreen:
//
Dcl-C pmBorderReverseGreen Const(3);
//
// pmBorderAlert:
//
Dcl-C pmBorderAlert Const(4);
//
// pmResult*
// ---------
// pmResultAPIError:
//
Dcl-C pmResultAPIError Const(-7);
//
// pmResultLocationInvalid:
//
Dcl-C pmResultLocationInvalid Const(-6);
//
// pmResultRowInvalid:
//
Dcl-C pmResultRowInvalid Const(-5);
//
// pmResultColInvalid:
//
Dcl-C pmResultColInvalid Const(-4);
//
// pmResultStyleInvalid:
//
Dcl-C pmResultStyleInvalid Const(-3);
//
// pmResultBorderInvalid:
//
Dcl-C pmResultBorderInvalid Const(-2);
//
// pmResultNoOptions:
//
Dcl-C pmResultNoOptions Const(-1);
//
// pmResultNoSelection:
//
Dcl-C pmResultNoSelection Const(0);
Listing 2, member POPMNU, type RPGLE:
**Free Ctl-Opt NoMain BndDir('QC2LE'); // // PopMnu // ------ // Function to display a popup menu where the user can select an // option. The option number is then returned to caller. // // Jesper Wachs, Version 1, December 2018. // // The source member are delivered 'as is'. // // Neither Jesper Wachs nor anyone else who has been involved in // the creation, production or delivery of this software shall be // liable for any direct, indirect, consequential or incidental // damages (including damages for loss of business profits, // business interruption, loss of business information, and the // like) arising out of the use or inability to use such product // even if Jesper Wachs has been advised of the possibility of // such damages. // // Copymember for exported functions. // ---------------------------------- /copy qrpglesrc,popmnu_pr // // Copymember(s) for imported functions. // ------------------------------------- /copy qrpglesrc,qsnapiw_h // // Prototypes for local functions. // ------------------------------- Dcl-PR CalcMenuSize Packed(3:0); iStyle Packed(3:0) Const; iGUISupport Ind Const; iTitle Char(74) Const; iHeader Char(74) Const; iFooter Char(74) Const; iFKeysText Char(74) Const; iOptions Char(74) Const Dim(15); oMaxLen Packed(3:0); oNbrElm Packed(3:0); oMaxElmLen Packed(3:0); oNbrLin Packed(3:0); End-PR; Dcl-PR CreatePopupWindow Int(10:0); iRow Packed(3:0) Const; iCol Packed(3:0) Const; iNbrRow Packed(3:0) Const; iNbrCol Packed(3:0) Const; iNbrElm Packed(3:0) Const; iBorder Packed(3:0) Const; iStyle Packed(3:0) Const; iTitle VarChar(70) Value; iHeader VarChar(70) Value; iFooter VarChar(70) Value; iFKeyText VarChar(70) Value; ohCmdBuf Int(10:0); ohInpBuf Int(10:0); ohWin Int(10:0); End-PR; Dcl-PR GetScreenSize; oRows Packed(3:0); oCols Packed(3:0); End-PR; Dcl-PR OptionsAsClassic Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iFtrLen Packed(3:0) Const; oSltOpt Packed(3:0); End-PR; Dcl-PR OptionsAsCursor Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iFtrLen Packed(3:0) Const; oSltOpt Packed(3:0); End-PR; Dcl-PR OptionsAsPushBtnChar Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iMaxLen Packed(3:0) Const; iMaxElmLen Packed(3:0) Const; iRow Packed(3:0) Const; oSltOpt Packed(3:0); End-PR; Dcl-PR OptionsAsPushBtnGUI Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iMaxLen Packed(3:0) Const; iMaxElmLen Packed(3:0) Const; iRow Packed(3:0) Const; oSltOpt Packed(3:0); End-PR; Dcl-PR ValidateParms Packed(3:0); iLocation Packed(3:0) Const; iRow Packed(3:0) Const; iCol Packed(3:0) Const; iBorder Packed(3:0) Const; iStyle Packed(3:0) Const; iOptions Char(70) Const Dim(15); End-PR; // // Exported funtions. // ------------------ // PopupMenu // --------- // Dcl-Proc PopupMenu Export; Dcl-PI PopupMenu Packed(3:0); iLocation Packed(3:0) Const; iRow Packed(3:0) Const; iCol Packed(3:0) Const; iBorder Packed(3:0) Const; iStyle Packed(3:0) Const; iRmvMenu Ind Const; iTitle Char(70) Const; iHeader Char(70) Const; iFooter Char(70) Const; iFKeyText Char(70) Const; iOptions Char(70) Const Dim(15); End-PI; // Local work fields. Dcl-S Row Packed(3:0); Dcl-S Col Packed(3:0); Dcl-S CsrCol Int(10:0); Dcl-S CsrRow Int(10:0); Dcl-S GUISupport Ind; Dcl-S hCmdBuf Int(10:0); Dcl-S hInpBuf Int(10:0); Dcl-S hWin Int(10:0); Dcl-S SltOpt Packed(3:0); Dcl-S RowMax Packed(3:0); Dcl-S ColMax Packed(3:0); Dcl-S MaxElmLen Packed(3:0); Dcl-S MaxLen Packed(3:0); Dcl-S NbrElm Packed(3:0); Dcl-S NbrLin Packed(3:0); Dcl-S RtnCode Packed(3:0); Dcl-S Res Int(10:0); // Validate input parms RtnCode = ValidateParms(iLocation: iRow: iCol: iBorder: iStyle: iOptions); If RtnCode = *Zeros; // Check if GUI is supported CallP QsnQry5250(QsnQ5250: %Size(QsnQ5250): *Omit); If %BitAnd(QsnQ5wscb5: x'02') = x'02'; GUISupport = *On; Else; GuiSupport = *Off; EndIf; // Based on input values, calculate the size of the popup menu. RtnCode = CalcMenuSize(iStyle: GUISupport: iTitle: iHeader: iFooter: iFKeyText: iOptions: MaxLen: NbrElm: MaxElmLen: NbrLin); If RtnCode = *Zeros; // This section sets the row and column of where to display the // popup menu. CallP GetScreenSize(RowMax: ColMax); // Adjust the popup menu based on the location to display it. Select; // Display the popup menu at Row, Col for the top left corner. When iLocation = pmLocationRowCol; Row = iRow; Col = iCol; // Display the popup menu at the Row, Col where the cursor is // currently positioned. When iLocation = pmLocationCursor; // Disable Window Mode RtnCode = QsnSetEnvWinMod('0': *Omit: *Omit: *Omit: *Omit: *Omit); // Get Cursor Address If RtnCode = *Zeros; RtnCode = QsnGetCsrAdr(CsrRow: CsrCol: *Omit: *Omit); Row = CsrRow + 1; Col = CsrCol; EndIf; If RtnCode <> *Zeros; RtnCode = pmResultAPIError; EndIf; // Display the popup menu at the center of the screen, taking // into consideration if the screen is in 24x80 or 27x132 mode. When iLocation = pmLocationCenter; Row = (RowMax - NbrLin - 0) / 2; Col = (ColMax - MaxLen - 3) / 2; EndSl; If RtnCode = *Zeros; If Row + NbrLin + 1 > RowMax; Row = RowMax - 1 - NbrLin; EndIf; If Col + MaxLen + 5 > ColMax; Col = ColMax - 5 - MaxLen; EndIf; // Build the menu window. RtnCode = CreatePopupWindow(Row: Col: NbrLin: MaxLen: NbrElm: iBorder: iStyle: iTitle: iHeader: iFooter: iFKeyText: hCmdBuf: hInpBuf: hWin); If RtnCode = *Zeros; // This section makes adjustmens based on the style to use for // the menu. // Add options depending on the menu type Select; // Classic style: Menu options and a field to enter the sele When iStyle = pmStyleClassic; RtnCode = OptionsAsClassic(hCmdBuf: hInpBuf: hWin: NbrElm: iOptions: %Len(%TrimR(iHeader)): %Len(%TrimR(iFooter)): SltOpt ); If RtnCode = *Zeros; RtnCode = SltOpt; EndIf; // Cursor style: User must move the cursor to the selection // ENTER. When iStyle = pmStyleCursor; RtnCode = OptionsAsCursor(hCmdBuf: hInpBuf: hWin: NbrElm: iOptions: %Len(%TrimR(iHeader)): Row: SltOpt ); If RtnCode = *Zeros; RtnCode = SltOpt; EndIf; // Push Button style: Each menu item is a push button. The u // click on the button to select the item When iStyle = pmStylePushBtn; If GUISupport = *Off; RtnCode = OptionsAsPushBtnChar(hCmdBuf: hInpBuf: hWin: NbrElm: iOptions: %Len(%TrimR(iHeader)): MaxLen: MaxElmLen: Row: SltOpt ); If RtnCode = *Zeros; RtnCode = SltOpt; EndIf; Else; // Display char push buttons RtnCode = OptionsAsPushBtnGUI(hCmdBuf: hInpBuf: hWin: NbrElm: iOptions: %Len(%TrimR(iHeader)): MaxLen: MaxElmLen: Row: SltOpt ); EndIf; If RtnCode = *Zeros; RtnCode = SltOpt; EndIf; EndSl; EndIf; EndIf; EndIf; // Delete Command Buffer If hCmdBuf <> *Zeros; CallP QsnDltBuf(hCmdBuf: *Omit); EndIf; // Delete Input Buffer If hInpBuf <> *Zeros; CallP QsnDltBuf(hInpBuf: *Omit); EndIf; // End Window If hWin <> *Zeros; CallP QsnEndWin(hWin: iRmvMenu: *Omit); EndIf; // Delete environment If hWin <> *Zeros; CallP QsnDltEnv(hWin: *Omit); EndIf; EndIf; Return RtnCode; End-Proc PopupMenu; // // Internal functions. // ------------------- // CalcMenuSize // ------------ // Calculates the height and width of the popup menu, based on the // number of items and the width of each item. Dcl-Proc CalcMenuSize; Dcl-PI CalcMenuSize Packed(3:0); iStyle Packed(3:0) Const; iGUISupport Ind Const; Title Char(74) Const; Header Char(74) Const; Footer Char(74) Const; FKeyText Char(74) Const; Options Char(74) Const Dim(15); MaxLen Packed(3:0); NbrElm Packed(3:0); oMaxElmLen Packed(3:0); NbrLin Packed(3:0); End-PI; // Local work fields. Dcl-S ElmLen Packed(3:0); Dcl-S Idx Packed(3:0); Dcl-S MaxOptLen Packed(3:0); NbrLin = *Zeros; MaxLen = %Len(%TrimR(Title)); // If there is a Header text, then make room for it. ElmLen = %Len(%TrimR(Header)); If ElmLen > *Zeros; NbrLin = NbrLin + 2; EndIf; If ElmLen > MaxLen; MaxLen = ElmLen; EndIf; // If there is a Footer text, then make room for it. ElmLen = %Len(%TrimR(Footer)); If ElmLen > *Zeros; NbrLin = NbrLin + 1; If ElmLen > MaxLen; MaxLen = ElmLen; EndIf; EndIf; // If there is a FKey text, then make room for it. ElmLen = %Len(%TrimR(FKeyText)); If ElmLen > *Zeros; NbrLin = NbrLin + 1; EndIf; If ElmLen > MaxLen; MaxLen = ElmLen; EndIf; NbrElm = %Elem(Options); MaxOptLen = *Zeros; // Find longest element For Idx = 1 to %Elem(Options); If Options(Idx) = *Blanks; NbrElm = Idx - 1; Leave; EndIf; ElmLen = %Len(%TrimR(Options(Idx))); If ElmLen > MaxOptLen; MaxOptLen = ElmLen; EndIf; EndFor; If NbrElm > *Zeros; oMaxElmLen = MaxOptLen; // Make adjustments based on the style. Select; // Classic style: If more than 9 items, make sure they are aligned. When iStyle = pmStyleClassic; NbrLin = NbrLin + 2; If NbrElm >= 10; MaxOptLen = MaxOptLen + 4; Else; MaxOptLen = MaxOptLen + 3; EndIf; If MaxOptLen > MaxLen; MaxLen = MaxOptLen; EndIf; // Cursor style: Make more space. When iStyle = pmStyleCursor; NbrLin = NbrLin + 1; If MaxOptLen > MaxLen; MaxLen = MaxOptLen; EndIf; // Push Button style: Make more space and make menu wide enough. When iStyle = pmStylePushBtn; NbrLin = NbrLin + 1; If iGUISupport = *Off; MaxOptLen = MaxOptLen + 2; Else; MaxOptLen = MaxOptLen + 3; EndIf; If MaxOptLen > MaxLen; MaxLen = MaxOptLen; EndIf; EndSl; // Make sure height and width are within limits. NbrLin = NbrLin + NbrElm; If NbrLin > 20; NbrLin = 20; EndIf; If MaxLen > 74; MaxLen = 74; EndIf; Return *Zeros; Else; Return pmResultNoOptions; EndIf; End-Proc CalcMenuSize; // // CreatePopupWindow // ----------------- // Creates the popup window by filling the required commands into // the command buffer. Dcl-Proc CreatePopupWindow; Dcl-PI CreatePopupWindow Int(10:0); iRow Packed(3:0) Const; iCol Packed(3:0) Const; iNbrRow Packed(3:0) Const; iNbrCol Packed(3:0) Const; iNbrElm Packed(3:0) Const; iBorder Packed(3:0) Const; iStyle Packed(3:0) Const; iTitle VarChar(70) Value; iHeader VarChar(70) Value; iFooter VarChar(70) Value; iFKeyText VarChar(70) Value; ohCmdBuf Int(10:0); ohInpBuf Int(10:0); ohWin Int(10:0); End-PI; // Local work fields. Dcl-S Res Int(10:0); Dcl-S StartCol Int(10:0); Dcl-S StartLin Int(10:0); Dcl-S WinDLen Int(10:0); iTitle = %Trim(iTitle); iHeader = %Trim(iHeader); iFooter = %Trim(iFooter); iFKeyText = %Trim(iFKeyText); // Default Windows Description WinDLen = %Size(QsnWinD); QsnWinD = *Allx'00'; Res = QsnInzWinD(QsnWinD: WinDLen: *Omit); If Res >= *Zeros; // Create command buffer ohCmdBuf = QsnCrtCmdBuf(300: 20: 0: *Omit: *Omit); // Create input buffer ohInpBuf = QsnCrtInpBuf(200: 50: 0: *Omit: *Omit); // Clear buffers Res = QsnClrBuf(ohCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ohInpBuf: *Omit); // Create a window // Set creation parms. QsnWTopR = iRow; QsnWLeftC = iCol; QsnWNumR = iNbrRow; QsnWNumC = iNbrCol; QsnWMinR = iNbrRow; QsnWMinC = iNbrCol; QsnWMaxR = iNbrRow; QsnWMaxC = iNbrCol; // Set attributes and colours based on border type. Select; // Default border When iBorder = pmBorderDefault; QsnWTAtrC = QSN_SA_BLU_RI; QsnWTAtrM = QSN_SA_RI; // Reverse blue border When iBorder = pmBorderReverseBlue; QsnWGUI = *Off; QsnWULCh = *Blank; QsnWTopCh= *Blank; QsnWURCh = *Blank; QsnWLCh = *Blank; QsnWRCh = *Blank; QsnWLLCh = *Blank; QsnWBotCh = *Blank; QsnWLRCh = *Blank; QsnWAtrC2 = QSN_SA_BLU_RI; QsnWTAtrC = x'00'; QsnWAtrM2 = QSN_SA_RI; QsnWTAtrM = x'00'; // Reserve green broder When iBorder = pmBorderReverseGreen; QsnWGUI = *Off; QsnWULCh = *Blank; QsnWTopCh= *Blank; QsnWURCh = *Blank; QsnWLCh = *Blank; QsnWRCh = *Blank; QsnWLLCh = *Blank; QsnWBotCh = *Blank; QsnWLRCh = *Blank; QsnWAtrC2 = QSN_SA_GRN_RI; QsnWTAtrC = x'00'; QsnWAtrM2 = QSN_SA_RI; QsnWTAtrM = x'00'; // Alert border When iBorder = pmBorderAlert; QsnWGUI = *Off; QsnWULCh = *Blank; QsnWTopCh= *Blank; QsnWURCh = *Blank; QsnWLCh = *Blank; QsnWRCh = *Blank; QsnWLLCh = *Blank; QsnWBotCh = *Blank; QsnWLRCh = *Blank; QsnWAtrC2 = QSN_SA_RED_RI; QsnWTAtrC = x'00'; QsnWAtrM2 = QSN_SA_RI; QsnWTAtrM = x'00'; EndSl; If iTitle > *Blanks; QsnWTtlO = 76; QsnWTtl = iTitle; QsnWTtlL = %Len(iTitle); EndIf; ohWin = QsnCrtWin(QsnWinD: WinDLen: *Omit: *Omit: *Omit: *Omit: *Omit: *Omit: *Omit); // Set Current window Res = QsnSetCurWin(ohWin: *Omit); // Set Environment Window Mode QsnEWAtrC = '1'; QsnEWULR = QsnWTopR; QsnEWULC = QsnWLeftC; QsnEWNumR = QsnWNumR; QsnEWNumC = QsnWNumC + 2; Res = QsnSetEnvWinMod('1': *Omit: QsnEnvWM: %Size(QsnEnvWM): *Omit: *Omit); EndIf; EndIf; If Res = *Zeros; // Starting point for constants StartLin = *Zeros; // Write Header text If iHeader > *Blanks; StartLin = StartLin + 1; StartCol = ((iNbrCol - %Len(iHeader)) / 2) + 2; Res = QsnWrtDta(iHeader: %Len(iHeader): *Omit: StartLin: StartCol: QSN_SA_HI: *Omit: QSN_SA_HI: *Omit: ohCmdBuf: *Omit: *Omit); StartLin = StartLin + 1; EndIf; If Res = *Zeros; // Adjust for number of element in menu StartLin = StartLin + iNbrElm + 1; // Write footer If iFooter > *Blanks; StartLin = StartLin + 1; Res = QsnWrtDta(iFooter: %Len(iFooter): *Omit: StartLin: 2: QSN_SA_NORM: *Omit: QSN_SA_NORM: *Omit: ohCmdBuf: *Omit: *Omit); If iStyle = pmStyleClassic; StartLin = StartLin + 1; EndIf; EndIf; If Res = *Zeros; // Write F-Key text If iFKeyText > *Blanks; StartLin = StartLin + 1; Res = QsnWrtDta(iFKeyText: %Len(iFKeyText): *Omit: StartLin: 2: QSN_SA_NORM: *Omit: QSN_SA_BLU: *Omit: ohCmdBuf: *Omit: *Omit); EndIf; EndIf; EndIf; EndIf; If Res <> *Zeros; Res = pmResultAPIError; EndIf; Return Res; End-Proc CreatePopupWindow; // // GetScreenSize // ---------------- // Returns the size of the screen. Dcl-Proc GetScreenSize; Dcl-PI GetScreenSize; oRows Packed(3:0); oCols Packed(3:0); End-PI; Dcl-C C24ROWS Const(24); Dcl-C C80COLS Const(80); Dcl-C C27ROWS Const(27); Dcl-C C132COLS Const(132); Dcl-C C24X80MODE Const('3'); Dcl-C C27X132MODE Const('4'); // Local work fields. Dcl-S wDspMode Char(1); CallP QsnRtvMod(wDspMode: *Omit: *Omit); Select; When wDspMode = c24x80Mode; oRows = c24Rows; oCols = c80Cols; When wDspMode = c27x132Mode; oRows = c27Rows; oCols = c132Cols; // This should not be possible. Other; oRows = -1; oCols = -1; EndSl; Return; End-Proc GetScreenSize; // // OptionsAsClassic // ---------------- // Build the menu items as classic menu options and add an entry field. Dcl-Proc OptionsAsClassic; Dcl-PI OptionsAsClassic Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iFtrLen Packed(3:0) Const; oSltOpt Packed(3:0); End-PI; // Local work fields. Dcl-S Answer Char(2); Dcl-S FldLen Packed(1:0); Dcl-S Idx Packed(3:0); Dcl-S InpFldLin Packed(3:0); Dcl-S Len Packed(9:0); Dcl-S Offset Packed(3:0); Dcl-S OneChar Char(1); Dcl-S pInputData Pointer; Dcl-S Res Int(10:0); Dcl-S TempString VarChar(70); Dcl-S TwoDigits Zoned(2:0); Dcl-DS InputData Based(pInputData); Row Uns(3:0); Col Uns(3:0); AID Char(1); Field Char(500); End-DS; // DS for converting char to numeric Dcl-DS *N; TheChar Char(1) Pos(1); TheNum Zoned(1:0) Pos(1); End-DS; oSltOpt = *Zeros; // Dertermine where to start the list of items. If iHdrLen > *Zeros; Offset = 2; InpFldLin = 4; Else; Offset = *Zeros; InpFldLin = 2; EndIf; // Adjust if a footer is entered. If iFtrLen > *Zeros; InpFldLin = InpFldLin + 1; EndIf; InpFldLin = InpFldLin + iNbrElm; // Write each item, preceeded by the item nbr, to the window. For Idx = 1 to iNbrElm; TwoDigits = Idx; TempString = %EditC(TwoDigits: '4'); If iNbrElm < 10; TempString = %TrimL(TempString); EndIf; TempString = TempString + '. ' + %Trim(iOptions(Idx)); // Write option to buffer Res = QsnWrtDta(TempString: %Len(TempString): *Omit: Idx + Offset: 2: QSN_SA_NORM: *Omit: QSN_SA_NORM: *Omit: ihCmdBuf: *Omit: *Omit); EndFor; // Add Input field for selection Res = QsnWrtDta('===>': 4: *Omit: InpFldLin: 2: *Omit: *Omit: *Omit: *Omit: ihCmdBuf: *Omit: *Omit); // Loop until valid input DoU AID = Qsn_Enter Or AID = Qsn_F3 Or AID = Qsn_F12; // Set Field If iNbrElm < 10; FldLen = 1; Else; FldLen = 2; EndIf; Res = QsnSetFld(1: FldLen: InpFldLin: 7: QSN_FFW_NUM_ONLY + QSN_FFW_MDT: *Omit: 0: QSN_SA_UL: QSN_SA_GRN_UL: ihCmdBuf: *Omit: *Omit); // Read Input Res = QsnReadInp(QSN_CC1_NULL: QSN_CC2_NO_IC: *Omit: *Omit: ihCmdBuf: *Omit: *Omit); // Put and Get Buffer Res = QsnPutGetBuf(ihCmdBuf: ihInpBuf: *Omit: *Omit); // Retrieve current window Res = QsnRtvCurWin(ihWin: *Omit); If Res > *Zeros; Res = *Zeros; EndIf; // Get input data pInputData = QsnRtvDta(ihInpBuf: *Omit: *Omit); Select; // ENTER key pressed. When AID = Qsn_Enter; // Extract field data Len = QsnRtvDtaLen(ihInpBuf: *Omit: *Omit) - %Size(Row) - %Size(Col) - %Size(AId); If Len > *Zeros; Answer = %Trim(%SubSt(Field: 1: Len)); // Scrup data out OneChar = %Subst(Answer: 1: 1); If OneChar >= '0' And OneChar <= '9'; TheChar = OneChar; oSltOpt = TheNum; EndIf; OneChar = %Subst(Answer: 2: 1); If OneChar >= '0' And OneChar <= '9'; oSltOpt = oSltOpt * 10; TheChar = OneChar; oSltOpt = oSltOpt + TheNum; EndIf; If oSltOpt = *Zeros Or oSltOpt > iNbrElm; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndIf; EndIf; // F3 or F12 key pressed. When AID = Qsn_F3 Or AID = Qsn_F12; // Do not do anything, as this will terminate the loop. Other; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndSl; EndDo; If Res = -1; Res = pmResultAPIError; EndIf; Return Res; End-Proc OptionsAsClassic; // // OptionsAsCursor // --------------- // Build the menu items for selection by moving the cursor. Dcl-Proc OptionsAsCursor; Dcl-PI OptionsAsCursor Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iFtrLen Packed(3:0) Const; oSltOpt Packed(3:0); End-PI; // Local work fields. Dcl-S Idx Packed(3:0); Dcl-S Offset Packed(3:0); Dcl-S pInputData Pointer; Dcl-S Res Int(10:0); Dcl-S TempString VarChar(70); Dcl-DS InputData Based(pInputData); Row Uns(3:0); Col Uns(3:0); AID Char(1); Field Char(500); End-DS; oSltOpt = *Zeros; If iHdrLen > *Zeros; Offset = 2; Else; Offset = *Zeros; EndIf; // Write each option to the window. For Idx = 1 to iNbrElm; TempString = %Trim(iOptions(Idx)); // Write option to buffer Res = QsnWrtDta(TempString: %Len(TempString): *Omit: Idx + Offset: 2: QSN_SA_NORM: *Omit: QSN_SA_NORM: *Omit: ihCmdBuf: *Omit: *Omit); EndFor; // Loop until valid input DoU AID = Qsn_Enter Or AID = Qsn_F3 Or AID = Qsn_F12; // Set the cursor position Res = QsnSetCsrAdr(*Omit: 1 + Offset: 2: ihCmdBuf: *Omit: *Omit); // Read Input Res = QsnReadInp(QSN_CC1_NULL: QSN_CC2_NO_IC: *Omit: *Omit: ihCmdBuf: *Omit: *Omit); // Put and Get Buffer Res = QsnPutGetBuf(ihCmdBuf: ihInpBuf: *Omit: *Omit); // Retrieve current window Res = QsnRtvCurWin(ihWin: *Omit); If Res > *Zeros; Res = *Zeros; EndIf; // Get input data pInputData = QsnRtvDta(ihInpBuf: *Omit: *Omit); Select; // ENTER key pressed. When AID = Qsn_Enter; // Calculate the selected line oSltOpt = Row - iFtrLen - Offset; If oSltOpt < 1 Or oSltOpt > iNbrElm; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndIf; // F3 or F12 key pressed. When AID = Qsn_F3 Or AID = Qsn_F12; // Do not do anything, as this will terminate the loop. Other; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndSl; EndDo; If Res = -1; Res = pmResultAPIError; EndIf; Return Res; End-Proc OptionsAsCursor; // // OptionsAsPushBtnChar // -------------------- // Build the menu items as push buttons, in char format for non-GUI // terminals. Dcl-Proc OptionsAsPushBtnChar; Dcl-PI OptionsAsPushBtnChar Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iMaxLen Packed(3:0) Const; iMaxElmLen Packed(3:0) Const; iRow Packed(3:0) Const; oSltOpt Packed(3:0); End-PI; // Local work fields. Dcl-S FieldXPos Packed(3:0); Dcl-S Idx Packed(3:0); Dcl-S Offset Packed(3:0); Dcl-S PadSpaces Packed(3:0); Dcl-S pInputData Pointer; Dcl-S Res Int(10:0); Dcl-S Spaces Char(75) Inz(*Blanks); Dcl-S TempString VarChar(70); Dcl-DS InputData Based(pInputData); Row Uns(3:0); Col Uns(3:0); AID Char(1); Field Char(500); End-DS; oSltOpt = *Zeros; // Calculate pushbutton start pos FieldXPos = (iMaxLen - iMaxElmLen) / 2; FieldXPos = FieldXPos + 2; // Compensate starting line if no Header If iHdrLen > *Zeros; Offset = 2; Else; Offset = *Zeros; EndIf; // Loop though the items and draw them For Idx = 1 to iNbrElm; TempString = '<' + %Trim(iOptions(Idx)); PadSpaces = iMaxElmLen - %Len(TempString) + 1; If PadSpaces > *Zeros; TempString = TempString + %SubSt( Spaces: 1: PadSpaces); EndIf; TempString = TempString + '>'; // Input field to allow for cursor to shift between pushbuttons Res = QsnSetFld(Idx: 1: Idx + Offset: FieldXPos: QSN_FFW_IO: *Omit: 0: QSN_SA_NORM: *Omit: ihCmdBuf: *Omit: *Omit); // Write option to buffer Res = QsnWrtDta(TempString: %Len(TempString): *Omit: Idx + Offset: FieldXPos - 1: QSN_SA_NORM: *Omit: QSN_SA_NORM: *Omit: ihCmdBuf: *Omit: *Omit); EndFor; // Set the cursor position Res = QsnSetCsrAdr(1: *Omit: *Omit: ihCmdBuf: *Omit: *Omit); // Loop until valid input DoU AID = Qsn_Enter Or AID = Qsn_F3 Or AID = Qsn_F12; // Read Input Res = QsnReadInp(QSN_CC1_NULL: QSN_CC2_NO_IC: *Omit: *Omit: ihCmdBuf: *Omit: *Omit); // Put and Get Buffer Res = QsnPutGetBuf(ihCmdBuf: ihInpBuf: *Omit: *Omit); // Retrieve current window Res = QsnRtvCurWin(ihWin: *Omit); If Res > *Zeros; Res = *Zeros; EndIf; // Get input data pInputData = QsnRtvDta(ihInpBuf: *Omit: *Omit); Select; // ENTER key pressed. When AID = Qsn_Enter; // Calculate the selected pushbutton oSltOpt = Row - iRow - Offset; If oSltOpt < 1 Or oSltOpt > iNbrElm; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndIf; // F3 or F12 key pressed. When AID = Qsn_F3 Or AID = Qsn_F12; // Do not do anything, as this will terminate the loop. Other; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndSl; EndDo; If Res = -1; Res = pmResultAPIError; EndIf; Return Res; End-Proc OptionsAsPushBtnChar; // // OptionsAsPushBtnGUI // ------------------- // Build the menu items as GUI push buttons. Dcl-Proc OptionsAsPushBtnGUI; Dcl-PI OptionsAsPushBtnGUI Int(10:0); ihCmdBuf Int(10:0) Const; ihInpBuf Int(10:0) Const; ihWin Int(10:0) Const; iNbrElm Packed(3:0) Const; iOptions Char(70) Const Dim(15); iHdrLen Packed(3:0) Const; iMaxLen Packed(3:0) Const; iMaxElmLen Packed(3:0) Const; iRow Packed(3:0) Const; oSltOpt Packed(3:0); End-PI; // Local work fileds. Dcl-S FieldXPos Packed(3:0); Dcl-S Idx Zoned(2:0); Dcl-S Offset Packed(3:0); Dcl-S PadSpaces Packed(3:0); Dcl-S pInputData Pointer; Dcl-S Res Int(10:0); Dcl-S Spaces Char(75) Inz(*Blanks); Dcl-S TempString VarChar(70); Dcl-DS InputData Based(pInputData); Row Uns(3:0); Col Uns(3:0); AID Char(1); Field Char(500); End-DS; oSltOpt = *Zeros; // Calculate pushbutton start pos FieldXPos = (iMaxLen - iMaxElmLen) / 2; // Compensate starting line if no Header If iHdrLen > *Zeros; Offset = 3; Else; Offset = 1; EndIf; // Fill the Major Structure MJLen = %Size(MJStruc); MJClass = x'D9'; MJType = x'50'; MJFlag1 = x'04'; MJFlag2 = x'14'; MJFlag3 = x'00'; // Push buttons MJTPSlt = x'41'; MJGUIDev = x'20'; MJNWSwMne = x'30'; MJNWSwoMne = x'30'; MJRes1 = x'00'; MJRes2 = x'00'; MJTextSize = iMaxElmLen + 2; MJRows = iNbrElm; MJCols = 1; MJPad = 0; MJNumSep = '0'; MJCounSltChr = '/'; MJMousCnlAID = x'00'; Res = QsnWrtSFMaj(MJStruc: %Size(MJStruc): *Omit: Offset: FieldXPos: ihCmdBuf: *Omit: *Omit); // Fill the Minor Structure MIType = x'10'; MIFlag1 = x'01'; MIFlag2 = x'00'; MIFlag3 = x'e0'; // Loop though the options and draw them For Idx = 1 to iNbrElm; // Fill the individual part of Minor Structure MIValue = '1'; MIChoText = %Trim(iOptions(Idx)); MILen = %Size(MIStruc) - %Size(MIChoText) + %Len(%Trim(iOptions(Idx))); Res = QsnWrtSFMin(MIStruc: MILen: ihCmdBuf: *Omit: *Omit); EndFor; // Loop until valid input DoU AID = Qsn_Enter Or AID = Qsn_F3 Or AID = Qsn_F12; // Read Input Res = QsnReadInp(QSN_CC1_NULL: QSN_CC2_NO_IC: *Omit: *Omit: ihCmdBuf: *Omit: *Omit); // Put and Get Buffer Res = QsnPutGetBuf(ihCmdBuf: ihInpBuf: *Omit: *Omit); // Retrieve current window Res = QsnRtvCurWin(ihWin: *Omit); If Res > *Zeros; Res = *Zeros; EndIf; // Get input data pInputData = QsnRtvDta(ihInpBuf: *Omit: *Omit); Select; // ENTER key pressed. When AID = Qsn_Enter; // Calculate the selected pushbutton oSltOpt = Row - iRow - Offset + 1; If oSltOpt < 1 Or oSltOpt > iNbrElm; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndIf; // F3 or F12 key pressed. When AID = Qsn_F3 Or AID = Qsn_F12; // Do not do anything, as this will terminate the loop. Other; AID = *Allx'00'; // Clear buffers Res = QsnClrBuf(ihCmdBuf: *Omit); If Res >= *Zeros; Res = QsnClrBuf(ihInpBuf: *Omit); EndIf; EndSl; EndDo; If Res = -1; Res = pmResultAPIError; EndIf; Return Res; End-Proc OptionsAsPushBtnGUI; // // ValidateParms // ------------- // Validates that the input parms are within limits. Dcl-Proc ValidateParms; Dcl-PI ValidateParms Packed(3:0); iLocation Packed(3:0) Const; iRow Packed(3:0) Const; iCol Packed(3:0) Const; iBorder Packed(3:0) Const; iStyle Packed(3:0) Const; iOptions Char(70) Const Dim(15); End-PI; // Local work fields. Dcl-S RtnCode Packed(3:0) Inz(*Zeros); Select; // Location When iLocation < pmLocationCenter Or iLocation > pmLocationRowCol; RtnCode = pmResultLocationInvalid; // Row When iRow < *Zeros Or iRow > 27; RtnCode = pmResultRowInvalid; // Col When iCol < *Zeros Or iCol > 132; RtnCode = pmResultColInvalid; // Style When iStyle < pmStyleClassic Or iStyle > pmStylePushBtn; RtnCode = pmResultStyleInvalid; // Border When iBorder < pmBorderDefault Or iBorder > pmBorderAlert; RtnCode = pmResultBorderInvalid; // Options When iOptions(1) = *Blanks; RtnCode = pmResultNoOptions; EndSl; Return RtnCode; End-Proc ValidateParms;
If you have installed Jesper’s ToolBox for IBM i you can use the Make member in Listing 4 to compile the module and the example program.
Listing 4, member POPMNU_MK, type TXT:
;
; POPMNU_MK
; ---------
; Make member for the module and command POPMNU.
;
v &lib jwtools
v &srclib jwtools
v &proto PopMnu_Pr
v &debug *source
;
; Check and possibly build PopMnu module.
;
v &mod1 PopMnu
o &srclib &mod1 *module
u &srclib qrpglesrc *file &mod1
u &srclib qrpglesrc *file &proto
u &srclib qrpglesrc *file qsnapiw_h
ci dltmod &srclib/&mod1
c crtrpgmod &srclib/&mod1 srcfile(&srclib/qrpglesrc) dbgview(&debug)
;
; Check and possibly build PopMnu_Ex1 module.
;
v &mod2 PopMnu_Ex
o &srclib &mod2 *module
u &srclib qrpglesrc *file &mod2
u &srclib qrpglesrc *file &proto
ci dltmod &srclib/&mod2
c crtrpgmod &srclib/&mod2 srcfile(&srclib/qrpglesrc) dbgview(&debug)
;
; Build main program.
;
v &pgm PopMnu_Ex
o &lib &pgm *pgm
u &srclib &mod1 *module
u &srclib &mod2 *module
ci DltPgm &lib/&pgm
c CrtPgm &lib/&pgm module(&srclib/&mod1 &srclib/&mod2)
Listing 5, member QSNAPIW_H, type RPGLE
**Free
//
// Prototypes for DSM APIs
// -----------------------
// All DSM Windows API declarations added by Jesper Wachs, December 2018.
//
//
// Copyright (c) 2004 Scott C. Klement
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPO
// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTI
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRI
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WA
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
/If Defined(QSNAPIW_H)
/Eof
/EndIf
/Define QSNAPIW_H
// Standard DSM APIs
// -----------------
Dcl-PR QsnClrBuf Int(10:0) ExtProc('QsnClrBuf');
BufHandle Int(10:0) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnCrtCmdBuf Int(10:0) ExtProc('QsnCrtCmdBuf');
InitSize Int(10:0) Const;
IncrAmt Int(10:0) Const Options(*Omit);
MaxSize Int(10:0) Const Options(*Omit);
Handle Int(10:0) Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnCrtInpBuf Int(10:0) ExtProc('QsnCrtInpBuf');
BufSize Int(10:0) Const;
IncrAmt Int(10:0) Const Options(*Omit);
MaxSize Int(10:0) Const Options(*Omit);
Handle Int(10:0) Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnDltBuf Int(10:0) ExtProc('QsnDltBuf');
BufHandle Int(10:0) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnDltEnv Int(10:0) ExtProc('QsnDltEnv');
Environment Int(10:0);
ErrorCode Char(32767) Const Options(*Omit:
*VarSize);
End-PR;
Dcl-PR QsnGetAID Char(1) ExtProc('QsnGetAID');
AIDChar Char(1) Options(*Omit);
LowLvlEnvHnd Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnGetCsrAdr Int(10:0) ExtProc('QsnGetCsrAdr');
CsrRow Int(10:0) Const Options(*Omit);
CsrCol Int(10:0) Const Options(*Omit);
LowLvlEnvHnd Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnPutBuf Int(10:0) ExtProc('QsnPutBuf');
CmdBufHnd Int(10:0) Const;
LowLvlEnvHnd Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnPutGetBuf Int(10:0) ExtProc('QsnPutGetBuf');
CmdBufHandle Int(10:0) Const;
InpBufHandle Int(10:0) Const;
LowEnvHandle Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnReadInp Int(10:0) ExtProc('QsnReadInp');
CC1 Char(1) Const;
CC2 Char(1) Const;
DataBytes Int(10:0) Options(*Omit);
InpBufHandle Int(10:0) Options(*Omit) Const;
CmdBufHandle Int(10:0) Options(*Omit) Const;
LowEnvHandle Int(10:0) Options(*Omit) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnRtvDta Pointer ExtProc('QsnRtvDta');
InpBufHandle Int(10:0) Const;
PtrToData Pointer Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnRtvDtaLen Int(10:0) ExtProc('QsnRtvDtaLen');
InpBufHandle Int(10:0) Const;
DataLen Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnRtvMod Int(10:0) ExtProc('QsnRtvMod');
QsnDspMod Char(1) Options(*Omit);
QsnLowLvlEnv Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnSetCsrAdr Int(10:0) ExtProc('QsnSetCsrAdr');
FldNbr Int(10:0) Const Options(*Omit);
CsrRow Int(10:0) Const Options(*Omit);
CsrCol Int(10:0) Const Options(*Omit);
CmdBuf Int(10:0) Const Options(*Omit);
LowLvlEnvHnd Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnSetFld Int(10:0) ExtProc('QsnSetFld');
FieldID Int(10:0) Const Options(*Omit);
FieldLen Int(10:0) Const Options(*Omit);
Row Int(10:0) Const Options(*Omit);
Column Int(10:0) Const Options(*Omit);
FFW Char(2) Const Options(*Omit);
FCW Char(2) Const
Dim(32767)
Options(*Omit: *VarSize);
NumOfFCW Int(10:0) Const Options(*Omit);
MonoAttr Char(1) Const Options(*Omit);
ColorAttr Char(1) Const Options(*Omit);
CmdBufHandle Int(10:0) Const Options(*Omit);
LowEnvHandle Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnQry5250 Int(10:0) ExtProc('QsnQry5250');
Qry5250Cap Char(64) Options(*VarSize);
Qry5250CapL Int(10:0) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnWrtDta Int(10:0) ExtProc('QsnWrtDta');
Data Char(32767) Const Options(*VarSize);
DataLen Int(10:0) Const;
FieldID Int(10:0) Const Options(*Omit);
Row Int(10:0) Const Options(*Omit);
Column Int(10:0) Const Options(*Omit);
StrMonoAttr Char(1) Const Options(*Omit);
EndMonoAttr Char(1) Const Options(*Omit);
StrColorAttr Char(1) Const Options(*Omit);
EndColorAttr Char(1) Const Options(*Omit);
CmdBufHandle Int(10:0) Const Options(*Omit);
LowEnvHandle Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnWrtSFMaj Int(10:0) ExtProc('QsnWrtSFMaj');
MajStruc Char(30) Const Options(*VarSize);
MajStrucLen Int(10:0) Const;
SFMajFldID Int(10:0) Const Options(*Omit);
SFMajRow Int(10:0) Const Options(*Omit);
SFMajCol Int(10:0) Const Options(*Omit);
SFMajCmdBuf Int(10:0) Const Options(*Omit);
SFLowLvlEnv Int(10:0) Const Options(*Omit);
SFErrorCode Char(32767) Const Options(*Omit:
*VarSize);
End-PR;
Dcl-PR QsnWrtSFMin Int(10:0) ExtProc('QsnWrtSFMin');
MinStruc Char(80) Const Options(*VarSize);
MinStrucLen Int(10:0) Const;
SFMinCmdBuf Int(10:0) Const;
SFMinLowLvl Int(10:0) Const Options(*Omit);
SFErrorCode Char(32767) Const Options(*Omit:
*VarSize);
End-PR;
//
// Window DSM APIs
// ---------------
Dcl-PR QsnCrtWin Int(10:0) ExtProc('QsnCrtWin');
WinDesc Char(156) Const Options(*VarSize);
WinDescL Int(10:0) Const;
UsrExtInf Char(32767) Const Options(*Omit:
*VarSize);
UsrExtInfL Int(10:0) Const Options(*Omit);
StartWindow Char(1) Const Options(*Omit);
LowLvEnvDes Char(32767) Const Options(*Omit:
*VarSize);
LowLvEnvDesL Int(10:0) Const Options(*Omit);
WindowHnd Int(10:0) Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnEndWin Int(10:0) ExtProc('QsnEndWin');
WinHnd Int(10:0) Const;
RestoreScn Char(1) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnInzWinD Int(10:0) ExtProc('QsnInzWinD');
WinDesc Char(77) Const Options(*VarSize);
WinDescLen Int(10:0) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnRtvCurWin Int(10:0) ExtProc('QsnRtvCurWin');
CurWinHnd Int(10:0) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnSetCurWin Int(10:0) ExtProc('QsnSetCurWin');
WinHnd Int(10:0) Const;
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
Dcl-PR QsnSetEnvWinMod Int(10:0) ExtProc('QsnSetEnvWinMod');
EnableWin Char(1) Const;
PrvWinModSet Char(1) Options(*Omit);
WinModDesc Char(156) Options(*Omit: *VarSize);
WinModDescL Int(10:0) Const Options(*Omit);
LowLvlEnvHnd Int(10:0) Const Options(*Omit);
ErrorCode Char(32767) Options(*Omit: *VarSize);
End-PR;
//
// Standard DSM API structures
// ---------------------------
// Data structure for QsnQry5250 API.
//
Dcl-DS QsnQ5250;
QsnQ5Ret Int(10:0);
QsnQ5Avl Int(10:0);
QsnQ5Stat Char(1);
QsnQ5Wkstn BinDec(4:0);
QsnQ5CLvl Char(3);
QsnQ5R1 Char(16);
QsnQ5WType Char(1);
QsnQ5MType Char(4);
QsnQ5Model Char(3);
QsnQ5KbdID Char(1);
QsnQ5EKbd Char(1);
QsnQ5PcKbd Char(1);
QsnQ5SNum Char(4);
QsnQ5MaxIn BinDec(4:0);
QsnQ5WSCSp Char(2);
QsnQ5R2 Char(1);
QsnQ5WSCB1 Char(1);
QsnQ5WSCB2 Char(1);
QsnQ5WSCB3 Char(1);
QsnQ5WSCB4 Char(1);
QsnQ5WSCB5 Char(1);
QsnQ5R3 Char(5);
QsnQ5Prt Char(1);
QsnQ5R4 Char(1);
QsnQ5GrdBf Char(1);
QsnQ5R5 Char(9);
End-DS;
//
// Window DSM API structures
// -------------------------
// Data structures for QsnSetEnvWinMod API.
//
Dcl-DS QsnEnvWM;
QsnEWAtrC Char(1);
QsnEWULR Int(10:0);
QsnEWULC Int(10:0);
QsnEWNumR Int(10:0);
QsnEWNumC Int(10:0);
End-DS;
//
//
//
Dcl-DS MJStruc;
MJLen Int(5:0);
MJClass Char(1);
MJType Char(1);
MJFlag1 Char(1);
MJFlag2 Char(1);
MJFlag3 Char(1);
MJTPSlt Char(1);
MJGUIDev Char(1);
MJNWSwMne Char(1);
MJNWSwoMne Char(1);
MJRes1 Char(1);
MJRes2 Char(1);
MJTextSize Int(3:0);
MJRows Int(3:0);
MJCols Int(3:0);
MJPad Int(3:0);
MJNumSep Char(1);
MJCounSltChr Char(1);
MJMousCnlAID Char(1);
End-DS;
//
//
//
Dcl-DS MIStruc;
MILen Int(3:0);
MIType Char(1);
MIFlag1 Char(1);
MIFlag2 Char(1);
MIFlag3 Char(1);
MIValue Char(1);
MIChoText Char(70);
End-DS;
//
// Data structures for QsnCrtWin and QsnChgWin APIs.
//
Dcl-DS QsnWinD;
QsnWTopR Int(10:0);
QsnWLeftC Int(10:0);
QsnWNumR Int(10:0);
QsnWNumC Int(10:0);
QsnWMinR Int(10:0);
QsnWMinC Int(10:0);
QsnWMaxR Int(10:0);
QsnWMaxC Int(10:0);
QsnWFS Char(1);
QsnWAtrM1 Char(1);
QsnWAtrM2 Char(1);
QsnWAtrM3 Char(1);
QsnWAtrC1 Char(1);
QsnWAtrC2 Char(1);
QsnWAtrC3 Char(1);
QsnWShowB Char(1);
QsnWShowBA Char(1);
QsnWShowLA Char(1);
QsnWShowRA Char(1);
QsnWMsgL Char(1);
QsnWULCh Char(1);
QsnWTopCh Char(1);
QsnWURCh Char(1);
QsnWLCh Char(1);
QsnWRCh Char(1);
QsnWLLCh Char(1);
QsnWBotCh Char(1);
QsnWLRCh Char(1);
QsnWGUI Char(1);
QsnWFlg1 Char(1);
QsnWFlg2 Char(1);
QsnWR1 Char(1);
QsnWBdrF Char(1);
QsnWTtlF Char(1);
QsnWTAtrM Char(1);
QsnWTAtrC Char(1);
QsnWR2 Char(1);
QsnWR3 Char(3);
QsnWTtlO Int(10:0);
QsnWTtlL Int(10:0);
QsnWR4 Int(10:0);
QsnWTtl Char(70);
End-DS;
//
// Standard DSM API constants
// --------------------------
// AID keys
//
Dcl-C QSN_F1 x'31';
Dcl-C QSN_F2 x'32';
Dcl-C QSN_F3 x'33';
Dcl-C QSN_F4 x'34';
Dcl-C QSN_F5 x'35';
Dcl-C QSN_F6 x'36';
Dcl-C QSN_F7 x'37';
Dcl-C QSN_F8 x'38';
Dcl-C QSN_F9 x'39';
Dcl-C QSN_F10 x'3A';
Dcl-C QSN_F11 x'3B';
Dcl-C QSN_F12 x'3C';
Dcl-C QSN_F13 x'B1';
Dcl-C QSN_F14 x'B2';
Dcl-C QSN_F15 x'B3';
Dcl-C QSN_F16 x'B4';
Dcl-C QSN_F17 x'B5';
Dcl-C QSN_F18 x'B6';
Dcl-C QSN_F19 x'B7';
Dcl-C QSN_F20 x'B8';
Dcl-C QSN_F21 x'B9';
Dcl-C QSN_F22 x'BA';
Dcl-C QSN_F23 x'BB';
Dcl-C QSN_F24 x'BC';
Dcl-C QSN_SLP x'3F';
Dcl-C QSN_FET x'50';
Dcl-C QSN_PA1 x'6C';
Dcl-C QSN_PA2 x'6E';
Dcl-C QSN_PA3 x'6B';
Dcl-C QSN_CLEAR x'BD';
Dcl-C QSN_ENTER x'F1';
Dcl-C QSN_HELP x'F3';
Dcl-C QSN_ROLLDOWN x'F4';
Dcl-C QSN_ROLLUP x'F5';
Dcl-C QSN_PAGEUP x'F4';
Dcl-C QSN_PAGEDOWN x'F5';
Dcl-C QSN_PRINT x'F6';
Dcl-C QSN_RECBS x'F8';
// Control Characters
Dcl-C QSN_CC1_NULL x'00';
Dcl-C QSN_CC1_LOCKBD x'20';
Dcl-C QSN_CC1_MDTNBY x'40';
Dcl-C QSN_CC1_MDTALL x'60';
Dcl-C QSN_CC1_CLRMOD x'80';
Dcl-C QSN_CC1_MDTNBY_CLRALL x'A0';
Dcl-C QSN_CC1_MDTNBY_CLRMOD x'C0';
Dcl-C QSN_CC1_MDTALL_CLRALL x'E0';
Dcl-C QSN_CC2_NULL x'00';
Dcl-C QSN_CC2_NO_IC x'40';
Dcl-C QSN_CC2_RST_CSR_BL x'20';
Dcl-C QSN_CC2_SET_CSR_BL x'10';
Dcl-C QSN_CC2_UNLOCKBD x'08';
Dcl-C QSN_CC2_ALARM x'04';
Dcl-C QSN_CC2_MSG_OFF x'02';
Dcl-C QSN_CC2_MSG_ON x'01';
//
// Field Format Words
//
Dcl-C QSN_NO_FFW x'0000';
Dcl-C QSN_FFW_BYPASS x'6000';
Dcl-C QSN_FFW_DUP x'5000';
Dcl-C QSN_FFW_MDT x'4800';
Dcl-C QSN_FFW_ALPHA_SHIFT x'4000';
Dcl-C QSN_FFW_ALPHA_ONLY x'4100';
Dcl-C QSN_FFW_NUM_SHIFT x'4200';
Dcl-C QSN_FFW_NUM_ONLY x'4300';
Dcl-C QSN_FFW_KATA x'4400';
Dcl-C QSN_FFW_DIGIT_ONLY x'4500';
Dcl-C QSN_FFW_IO x'4600';
Dcl-C QSN_FFW_SIGNED_NUMERIC x'4700';
Dcl-C QSN_FFW_AUTO_ENTER x'4080';
Dcl-C QSN_FFW_FER x'4040';
Dcl-C QSN_FFW_AUTO_FER x'4040';
Dcl-C QSN_FFW_MONOCASE x'4020';
Dcl-C QSN_FFW_AUTO_MONOCASE x'4020';
Dcl-C QSN_FFW_ME x'4008';
Dcl-C QSN_FFW_NOADJUST x'4000';
Dcl-C QSN_FFW_RA_ZERO x'4005';
Dcl-C QSN_FFW_RA_BLANK x'4006';
Dcl-C QSN_FFW_MF x'4007';
Dcl-C QSN_FCW_RESEQ x'8000';
Dcl-C QSN_FCW_MSR x'8101';
Dcl-C QSN_FCW_SLP x'8102';
Dcl-C QSN_FCW_MSR_SLP x'8103';
Dcl-C QSN_FCW_SLP_SA x'8106';
Dcl-C QSN_FCW_DBCS_ONLY x'8200';
Dcl-C QSN_FCW_DBCS_PURE x'8220';
Dcl-C QSN_FCW_DBCS_EITHER x'8240';
Dcl-C QSN_FCW_DBCS_OPEN x'8280';
Dcl-C QSN_FCW_DBCS_OPEN_CO x'82C0';
Dcl-C QSN_FCW_TRANSPARENT x'8400';
Dcl-C QSN_FCW_FET x'8501';
Dcl-C QSN_FCW_CONT_FIRST x'8601';
Dcl-C QSN_FCW_CONT_LAST x'8602';
Dcl-C QSN_FCW_CONT_MIDDLE x'8603';
Dcl-C QSN_FCW_CP x'8800';
Dcl-C QSN_FCW_HL x'8900';
Dcl-C QSN_FCW_PDS x'8A00';
Dcl-C QSN_FCW_MOD11 x'B140';
Dcl-C QSN_FCW_MOD10 x'B1A0';
Dcl-C QSN_READ_INP x'42';
Dcl-C QSN_READ_MDT x'52';
Dcl-C QSN_READ_IMM x'72';
Dcl-C QSN_READ_MDT_ALT x'82';
//
// Screen Attributes
//
Dcl-C QSN_NO_SA x'00';
Dcl-C QSN_SA_NORM x'20';
Dcl-C QSN_SA_CS x'30';
Dcl-C QSN_SA_BL x'28';
Dcl-C QSN_SA_UL x'24';
Dcl-C QSN_SA_HI x'22';
Dcl-C QSN_SA_RI x'21';
Dcl-C QSN_SA_ND x'27';
Dcl-C QSN_SA_GRN x'20';
Dcl-C QSN_SA_GRN_RI x'21';
Dcl-C QSN_SA_WHT x'22';
Dcl-C QSN_SA_WHT_RI x'23';
Dcl-C QSN_SA_GRN_UL x'24';
Dcl-C QSN_SA_GRN_UL_RI x'25';
Dcl-C QSN_SA_WHT_UL x'26';
Dcl-C QSN_SA_RED x'28';
Dcl-C QSN_SA_RED_RI x'29';
Dcl-C QSN_SA_RED_BL x'2A';
Dcl-C QSN_SA_RED_RI_BL x'2B';
Dcl-C QSN_SA_RED_UL x'2C';
Dcl-C QSN_SA_RED_UL_RI x'2D';
Dcl-C QSN_SA_RED_UL_BL x'2E';
Dcl-C QSN_SA_ND_2F x'2F';
Dcl-C QSN_SA_TRQ_CS x'30';
Dcl-C QSN_SA_TRQ_CS_RI x'31';
Dcl-C QSN_SA_YLW_CS x'32';
Dcl-C QSN_SA_YLW_CS_RI x'33';
Dcl-C QSN_SA_TRQ_UL x'34';
Dcl-C QSN_SA_TRQ_UL_RI x'35';
Dcl-C QSN_SA_YLW_UL x'36';
Dcl-C QSN_SA_ND_37 x'37';
Dcl-C QSN_SA_PNK x'38';
Dcl-C QSN_SA_PNK_RI x'39';
Dcl-C QSN_SA_BLU x'3A';
Dcl-C QSN_SA_BLU_RI x'3B';
Dcl-C QSN_SA_PNK_UL x'3C';
Dcl-C QSN_SA_PNK_UL_RI x'3D';
Dcl-C QSN_SA_BLU_UL x'3E';
Dcl-C QSN_SA_ND_3F x'3F';