You are here: Development Standards > Upgrading OSAS > Converting to 6.xx Graphical > Converting Programs

# Converting Programs

After you convert and clean up the resource file for a function, you must make the changes in the programs themselves to handle both character and graphical modes. OSAS uses the same code for both interfaces.

As you convert the programs, you may need to make adjustments to the resource file If you followed the steps above to clean up the resource file, you should not need to add input fields, but you may need to add other labels where necessary.

You must add or change several areas of code to make your programs run in both graphical and character mode. The order in which you make the changes does not matter; however, you must make all the changes before the program runs successfully.

Merge New General Routines

Before you begin, use the BASIS _update utility and the GENLIB.61 library file to update the common routines. Starting with version 6.1, the routines GENINPUT, GENLINE, GENERROR, GENLOCK, and GENNUM have all changed.

Convert Screen Prompts (7500)

The Prompts section of code displays field labels on a character screen after boxes are drawn on the screen by the Box (7900) section of code. Here is a sample of code from a typical Prompts section:
`7500 PROMPTS:`
`7502 GOSUB BOX`
`7504 PRINT ‘SB’,STBL(“FTXT”),`
`7520 PRINT @(3,2),"Pick Customer ID From",@(52,2),"Print By:",`
`7530 PRINT @(23,3),"Thru",@(54,3),"1. Customer ID",`
`7540 PRINT @(8,4),"Sales Rep 1 From",@(54,4),"2. Sales Rep ID",`
`.`
`.`
`7660 IF KIT THEN PRINT @(54,18),”Kit Detail”,`
`7692 RETURN`

As you can see, several changes were required before creating the BRC based on the suggestions above. The code should look something like this:
`7500 PROMPTS:`
`7502 GOSUB BOX`
`7504 PRINT ‘SB’,STBL(“FTXT”),`
`7520 PRINT @(3,2),"Pick Customer ID”,@(23,2),”From",@(52,2),"Print By:",`
`7530 PRINT @(23,3),"Thru",@(54,3),"1. Customer ID",`
`7540 PRINT @(8,4),"Sales Rep 1”,@(23,4),”From",@(54,4),"2. Sales Rep ID",`
`.`
`.`
`7660 IF KIT THEN PRINT @(54,18),”Kit Detail”,`
`7692 RETURN`

After you make these changes and properly generate the graphical screen, add a line to this section of code that branches to GUI_PROMPTS, a section of code that retrieves the graphical screen from the resource file. You must retrieve the screen before doing any screen paints. Here is a sample of the line of code:
`7501 IF GUI THEN GOTO GUI_PROMPTS`

The variable GUI is set by the menu programs. It is set to 1 if the functions are run in graphical mode, or 0 if not. The line should be positioned in the code block so that if GUI=1, the program skips the character prompt display and branches to GUI_PROMPTS.

Add Graphical Prompts (17500)

Although the code is different, the graphical GUI_PROMPTS section plays the same role as the character-based PROMPTS section: it displays the screen and paints the screen prompts. GUI_PROMPTS also displays the data controls on the form as well. Here is a sample of the GUI_PROMPTS section:
`17500 REM 17500 "----- GUI Prompts and Box"`
`17510 GUI_PROMPTS:`
`17520 LET`
`OSGUI.SCRNID$="ARPRH.BRC",OSGUI.WIND_ID[1]=1,OSGUI.CONTEXT_POINTER=1`
`17530 LET MSG$=""; CALL "GENGURES.PUB",FILE[ALL],OSGUI$,MSG$; IF`
`17530: CVS(MSG$,3)<>"" THEN LET X9$=MSG$,O7=1; GOSUB GENERROR; GOTO QUIT`
`17540 CALL "GENGUFNC.PUB::BUILD_MENU_STRINGS",MENUHLP$,MENU1$`
`17545 IF O2$(2,1)="1" THEN CALL`
`"GENGUFNC.PUB::BUILD_ITEM_LOOKUP_MENU_STRINGS",`
`17545:MENUITEM$`
`17550 LET MENU1$=MENU1$+MENUITEM$+MENUHLP$; PRINT`
`(OSGUI.CHAN)'SETMENU',MENU1$;`
`17550:LET MENU1$="",MENUHLP$="",MENUITEM$=""`
`17555 IF KIT THEN PRINT (OSGUI.CHAN)'SHOW'(4220)`
`17560 IF O2$(22,1)<>"1" THEN PRINT (OSGUI.CHAN)'DISABLE'(4210)`
`17565 IF O2$(2,1)="1" THEN PRINT (OSGUI.CHAN)'SHOW'(14040,14050),`
`17565:'DISABLE'(-20600)`
`17570 PRINT (OSGUI.CHAN)'TITLE'(0,TITLE$),'SHOW'(0)`
`17575 RETURN`

Refer to “GUI Screen Prompts” for more information on specific types of GUI_PROMPTS sections.

Convert Screen Data (7700)

The DATA section of code is used to display data in the fields on the character screen. Here is a sample of a typical DATA section:
`7700 DATA:`
`7704 PRINT 'CF','SF',`
`7710 PRINT @(29,2),N1$; REM Cust ID`
`7720 PRINT @(29,3),N2$`
`.`
`.`
`7860 PRINT @(8,20),N5:"#"`
`7890 RETURN`

In the same way as the PROMPTS section, you must add a line that skips the character data paint routine and instead branches to a graphical data painting routine. Here is a sample of the line to add to this program:

`7702 IF GUI THEN GOTO GUI_DATA`

In graphical mode, the line skips to the GUI_DATA section. In text mode, the data is painted as usual.

Add Graphical Screen Data (17700)

Like the prompt sections, the GUI_DATA section plays the same role as DATA: it displays the data on the screen. Here is a typical GUI_DATA section:

`17700 REM 17700,5 "----- GUI Data"`
`17710 GUI_DATA:`
`17715 PRINT (OSGUI.CHAN)'TITLE'(4000,N1$)`
`17720 PRINT (OSGUI.CHAN)'TITLE'(4010,N2$)`
`17725 PRINT (OSGUI.CHAN)'TITLE'(4020,N3$)`
`17730 PRINT (OSGUI.CHAN)'TITLE'(4030,N4$)`
`17735 PRINT (OSGUI.CHAN)'TITLE'(4040,N5$)`
`17740 PRINT (OSGUI.CHAN)'TITLE'(4050,N6$)`
`17745 PRINT (OSGUI.CHAN)'TITLE'(4060,N7$)`
`17750 PRINT (OSGUI.CHAN)'TITLE'(4070,N8$)`
`17755 PRINT (OSGUI.CHAN)'TITLE'(4080,FND$(N1))`
`17760 PRINT (OSGUI.CHAN)'TITLE'(4090,FND$(N2)); LET TMP=FNCHECK(4150,FNB$(1))`
`17765 PRINT (OSGUI.CHAN)'TITLE'(4100,INV_FROM$); LET`
`TMP=FNCHECK(4160,FNB$(2))`
`17770 PRINT (OSGUI.CHAN)'TITLE'(4110,INV_THRU$); LET`
`TMP=FNCHECK(4170,FNB$(3))`
`17775 LET TMP=FNCHECK(4180,FNB$(4))`
`17780 LET TMP=FNCHECK(4190,FNB$(5))`
`17785 LET TMP=FNCHECK(4200,FNB$(6))`
`17790 LET TMP=FNCHECK(4210,FNB$(7))`
`17795 LET TMP=FNCHECKRADIO(N3,"0412104122"),TMP=FNCHECKRADIO(N5,"0413104132")`
`17795:,TMP=FNCHECKRADIO(N4,"04141041420414304144")`
`17800 IF KIT THEN LET TMP=FNCHECK(4220,KIT_DETAIL$)`
`17805 RETURN`

Refer to “GUI Data Display” for more information on the GUI_DATA section.

Add GENNUM, GENPHONE

In programs that display or allow entry of numeric data or phone numbers, add and implement the GENNUM and GENPHONE sections of code.

Add GENCHECK, GENCHECK_RADIO, and GENLIST

As you add the GUI_DATA section of code, add and implement the GENCHECK, GENCHECK_RADIO, and/or GENLIST sections as needed. Use GENCHECK for check boxes on the form, GENCHECK_RADIO for radio buttons, and GENLIST for list boxes.

Add GUI_ID

On each line where variables are assigned before a CALL to GENINPUT.PUB, you must assign a graphical control ID to the field. Add the variable GUI_ID to the end of the line where the other GENINPUT variables are assigned (X0, X1, X3, X4, and so on). The GUI_ID variable is also set within HLE program before CALLing GENLINE to tell GENLINE which grid control to use.

Add GUI_RADIO$

If the program uses radio buttons, you must use the GUI_RADIO$ variable to specify which buttons make up the radio group. This variable must contain the control ID of each radio button. Each control ID must be 5 characters in length. Here is a sample of the GUI_RADIO$ assignment in ARPRH:

`1730 LET`
`X0=17,X1=8,X3=1,X4=1,X1$="#",X=N3,GUI_ID=4120,GUI_RADIO$="0412104122"`

In this example, radio buttons 4121 and 4122 below to this radio group. GUI_ID is set to the control ID of the group box.

Add CLEAR_GLOBAL

You must add the CLEAR_GLOBAL section to most programs that require user interaction. Here is a sample of the CLEAR_GLOBAL section:

`18200 REM 18200,5 "----- Clear GUI Global"`
`18205 CLEAR_GLOBAL:`
`18210 IF GUI THEN LET DUMMY$=STBL("!CLEAR","DESTID",ERR=18215)`
`18215 RETURN`

When a user clicks to move from one field to field on a graphical screen, the ID of control on which the user clicked is stored in a global variable called DESTID. The global variable is used in GENGUINP.PUB to tell which field the user clicked on. GENGUINP.PUB then passes back the appropriate variable in Y$: Y$=”U” if the user clicked on a field above the field with focus, or Y$=”E” if the user clicked on a field below the field with focus. (This is why the standards require the fields in the resource file to be numbered in increasing order.) When GENGUINP.PUB is CALLed with the same GUI_ID as the DESTID global, GENGUINP.PUB clears the global and handles input as usual.

The movement, then, of the field focus is handled automatically by GENGUINP.PUB, and requires no special program code.

However, it may be necessary to stop this movement at times. For example, at the end of the screen’s processing (in the PROCEED or OUTPUT sections, for example), if an error message must be displayed, or if required information is not available for a field, you must use the CLEAR_GLOBAL section to clear the DESTID global to stop GENGUINP.PUB from automatically issuing the Y$ commands.

The result of not including this call is an endless loop if you click on certain fields, because DESTID will contain a control ID until the program reaches that control or until the program specifically clears the variable. Here are some examples that illustrate the proper use of the CLEAR_GLOBAL routine:

`1070 LET X0=3,X1=29,X3=0,X4=6,X$=N2$,WINDID$="ARCIQ W1",GUI_ID=4010`
`1080 GOSUB GENINPUT; REM "CUST # - THRU"`
`1085 IF Y$="U" THEN GOTO 1030`
`1090 LET N2$=X$+FILL(6-LEN(X$))`
`1110 IF N2$<N1$ AND N2$<>FILL(6) THEN LET X9$=FT$; GOSUB CLEAR_GLOBAL; GOSUB`
`1110:GENERROR; GOTO 1070`

In this code sample, the user must enter a customer ID in the Customer Thru field that is greater than the value in the Customer From field. If not, the program branches from 1110 back to 1070. In case the user enters a From value greater than the existing Thru value, and then clicks on a control after the Thru field, the program will use the CLEAR_GLOBAL subroutine to clear DESTID.

Here’s another example:

`1070 LET X0=2,X1=18,X3=0,X4=6,X$=C0$,WINDID$="ARACC W1",P0=0,GUI_ID=4000`
`1080 GOSUB GENINPUT; REM "CUSTOMER ID"`
`1100 IF Y$="U" THEN GOTO 1000`
`1110 LET X$=X$+FILL(6-LEN(X$))`
`1120 LET C0$=X$`
`1130 IF X$=FILL(6) THEN LET Y$=""; GOSUB CLEAR_GLOBAL; GOTO 1030`

In this code sample, the user must enter an ID. If the user clicks on a field below the ID field without entering an ID, the CLEAR_GLOBAL subroutine prevents a looping issue if the user clicks on any other field.

There may also be places where you need to jump around controls based on data entered in other fields. This normally happens with check boxes and list buttons, as in this example:

`1630 IF X$(1,1)="Y" THEN LET C4$(6,1)="1" ELSE LET C4$(6,1)="0"`
`1632 IF SAVEX$="NO" AND X$="YES" AND GUI THEN GOSUB CLEAR_GLOBAL ELSE IF`
`1632:SAVEX$="YES" AND X$="NO " AND GUI AND STBL("DESTID",ERR=1635)="4020" THEN`
`1632:GOSUB CLEAR_GLOBAL`
`1635 IF C4$(6,1)="0" THEN IF GUI THEN PRINT (OSGUI.CHAN)'DISABLE'(4020,14020)`
`1635:FI; GOTO CREDIT_LIMIT ELSE IF GUI THEN PRINT (OSGUI.CHAN)'ENABLE'`
`1635:(4020,14020)`

This code sample checks the user’s input in the Finance Charge? field. If the user is running in graphical mode and changes the answer from YES to NO, the program checks to see if the Finance Charge Code field gets focus; if it does, the program clears DESTID to prevent an endless loop. If the user changes the answer from NO to YES, the program always clears DESTID so that the program will stop at the Finance Charge Code field.

Convert Speedos

In programs that display counters or speedos at the bottom of the screen, you must take special steps to convert the speedos to GUI. Search all programs for speedos, because speedos are used in many types of programs, including report printing programs and functions that do some type of processing that requires time to run. In graphical mode, speedos will appear on the status bar.

This sample prints a speedo on the status bar in graphical mode, but as a standard text message in text mode:

`1002 IF DEVICE$<>FID(0) THEN IF GUI THEN PRINT (OSGUI.CHAN)'TITLE'`
`(100,"Printing...") ELSE PRINT @(1,22),FILL(77),'SB',@(2,22),"Printing...",`

Convert Other Screen Updates

Look for other places in your program where you print data to the screen without using the DATA section of code. You must then add the appropriate code to your programs, and the appropriate fields in your resource file, to accomplish this. Here is a sample from a pre-6.1 version of ARENTLN2 that displays the shipped and backordered quantities after the ordered quantity and unit of measure were entered:

`1660 PRINT 'SF',STBL("FTXT2"),@(11,9),FNNUM$(TD5[1],MQTY$),`
`1670 PRINT 'SF',STBL("FTXT2"),@(11,10),FNNUM$(TD5[2],MQTY$),`

This code is changed as follows to work in graphical mode:

`1660 IF GUI THEN PRINT (OSGUI.CHAN)'TITLE'(4150,FNGUINUM$(TD5[1],MQTY$,4150))`
`1660: ELSE PRINT 'SF',STBL("FTXT2"),@(11,9),FNNUM$(TD5[1],MQTY$),`
`1670 IF GUI THEN PRINT (OSGUI.CHAN)'TITLE'(4160,FNGUINUM$(TD5[2],MQTY$,4160))`
`1670:ELSE PRINT 'SF',STBL("FTXT2"),@(11,10),FNNUM$(TD5[2],MQTY$),`

Pay particular attention to inquiry program types. In these types of programs, the user enters in a value on which to inquire, and a whole screen of data is presented. Because these fields are display only, they are not picked up by the graphical screen creation utility, and you must manually build these fields into your resource files.

This applies to any field where input from the user is not required. You must place the appropriate control (usually a static text control or a check box control) into your resource file manually.

Add Code to Disable and Enable Fields

As discussed earlier in this section, you must enable and disable fields at certain times in your programs.

For example, when you first enter the Payment Methods function in Accounts Receivable, the Payment Method field is enabled and the remaining fields are disabled to force entry of a valid payment method. When the payment method is entered, the Payment Method field is disabled and the remaining fields are enabled. When you return to the payment method field (after the Abandon or Proceed commands), the Payment Method field is again enabled and the remaining fields are again disabled.

This code sample handles both enabling and disabling of controls:

`18000 REM 18000,5 "----- Disable Fields"`
`18005 DISABLE_FIELDS:`
`18010 IF GUI THEN PRINT (OSGUI.CHAN)'HIDE'(1040,4040,14040),`
`'ENABLE'(4000,14000),'DISABLE'(4010,4020,4030,4050,14050,4060,4070,4080,4090)`
`18015 RETURN`
`18100 REM 18000,5 "----- Enable Fields"`
`18105 ENABLE_FIELDS:`
`18110 IF GUI=0 THEN GOTO 18125`
`18115 IF P1<=3 AND P1>0 THEN PRINT (OSGUI.CHAN)'SHOW'(1040,4040),'ENABLE'(40`
`18115:40);IF P3WIND$<>"" THEN PRINT (OSGUI.CHAN)'SHOW'(14040),'ENABLE'(14040)`
`18115:ELSE PRINT (OSGUI.CHAN)'HIDE'(14040) FI ELSE PRINT (OSGUI.CHAN)'HIDE'`
`18115:(1040,4040)`
`18120 PRINT (OSGUI.CHAN)'DISABLE'(4000,14000),`
`18120:'ENABLE'(4010,4020,4030,4050,14050,4060,4070,4080,4090)`
`18122 IF (O2$(15,1)="1" AND P1<3) OR CUSTOK=0 THEN PRINT (OSGUI.CHAN)'DISABLE'`
`18122:(4050,14050)`
`18125 RETURN`

The DISABLE_FIELDS section disables the Payment Method control and its corresponding F2 Inquiry tool button, and enables all other controls. This example also hides controls 1040, 4040, and 14040, which are the customer ID and bank ID and the associated F2 Inquiry tool button.

The ENABLE_FIELDS section disables the Payment Method control and its corresponding F2 Inquiry button, and enables the remaining fields. Then it checks the payment type to determine which other fields to show and enable, including the GL account, customer ID, or bank account ID and their F2 Inquiry buttons.

Add Code to Hide and Show Controls

Some programs have fields that appears and disappear depending on what is happening in the program. For example, most file maintenance programs contain a Copy From field that is not visible until you enter a new ID. The prompt and the field then appears on the screen. After you enter the Copy From, the field is removed from the screen.

The graphical equivalent for this technique is to include the control for the hidden field, and set the Visible property to invisible. Then when the field is needed, use the ‘SHOW’ mnemonic in the program to make the field visible. When the field is no longer needed, use the ‘HIDE’ mnemonic to remove the field form view.

You can decide to hide optional fields in the resource file, then show them in code, or have them visible in the resource file, then hide them in code. However, you should choose one method or the other for consistency.

If the field was not used when you used the graphical screen creation utility, you must add both the label and the input controls for the hidden field to the resource file. Because the field prompt is usually not built in the 7500 section, you will most likely have to add the label control in any case.

This code is from a pre-6.1 version of ARACC:

`1310 PRINT 'SB',STBL("FTXT"),@(31,2),"Copy from"`
`1400 PRINT @(31,2),FILL(46)`

To convert this to work in graphical mode, check for graphical mode, and then show and hide the controls when necessary:

`1310 IF GUI THEN PRINT (OSGUI.CHAN)’SHOW’(1030,4010,14010) ELSE PRINT`
`1310:'SB',STBL("FTXT"),@(31,2),"Copy from"`
`1400 IF GUI THEN PRINT (OSGUI.CHAN)’HIDE’(1030,4010,14010) ELSE PRINT`
`1400: @(31,2),FILL(46)`

Keep in mind that the user may use the Abandon command in the Copy From field, so similar logic is needed in the 8470 section to clear these prompts also.

You may find other examples of hidden and shown fields (such as the Batch ID fields in AR, SO, AP, and PO). In these cases, the code for hiding and showing the field resides in the GUI_PROMPTS section. Here is a sample from ARENTHDR:

`17550 IF O2$(10,1)="1" THEN PRINT (OSGUI.CHAN)'SHOW'(1000,4000,14000)`

This code checks the batching option, and if it is set, uses the ‘SHOW’ mnemonic on the label, the input field, and the F2 Inquiry tool button.

Convert CALLs to Public Programs

If you are converting a public program that runs in both character and graphical modes, and you specify variables in your CALL/ENTER lists, you must add the OSGUI$ template to the CALL/ENTER list. OSGUI$ is required because it is used by the general routines to determine the mode in which OSAS is running.

After the ENTER statement in the public program, add a line like this:

`0060 IF OSGUI$<>”” THEN IF OSGUI.CHAN THEN LET GUI=1`

While you could also just pass the variable GUI in your CALL/ENTER list, standard OSAS programs use the above method.

Add Code to Destroy or Hide Windows (Forms)

Many programs use more than one graphical screen. Transactions functions, some maintenance functions, some inquiry functions, and some commands (such as Maintenance) display new graphical windows over existing windows.

When the user finishes with the new window, the program must either ‘HIDE’ the window or ‘DESTROY’ it completely (much as the text version uses the ‘POP’ mnemonic).

First, determine whether you should ‘HIDE’ or ‘DESTROY’ the window. In general, if the window will likely be used more than once, you should ‘HIDE’ the window so it does not have to be loaded again later. If the window is used sparingly, ‘DESTROY’ the window to free resources.

This sample from ARACCFM.PUB demonstrates the ‘DESTROY’ mnemonic:

`18400 REM 18400,5 "----- Destroy Window"`
`18405 DESTROY_GUI_WINDOW:`
`18410 IF GUI_POP THEN PRINT (OSGUI.CHAN)'DESTROY'(0) FI; LET OSGUI$=`
`18415:SAVEOSGUI$;PRINT (OSGUI.CHAN)'CONTEXT'`
`18415:(OSGUI.CUR_CONTEXT[OSGUI.CONTEXT_POINTER])`
`18415 RETURN`

This code uses the variable GUI_POP, which is set by the GUI_PROMPTS section of code. If this variable is set, the ‘DESTROY’ mnemonic is used to remove the entire screen from memory. Because the window no longer exists, the OSGUI$ template is then reset to its original value, as is the current context.

To hide the window, substitute the ‘HIDE’ mnemonic for the ‘DESTROY’ mnemonic in the previous example. In addition, you must also save the element of the GUI_WIND[x] array on which this window is open, so you can refer to it when you need to show the screen again.

You can also hide a window in the PROMPTS section. This code sample from ARACC hides the current window and then sets the context back to the initial Customer maintenance screen, if it has already been opened:

`17500 REM 17500 "----- GUI Prompts and Box"`
`17510 GUI_PROMPTS:`
`17515 IF ARACC_POINTER THEN PRINT (OSGUI.CHAN)'HIDE'(0),`
`17515:'CONTEXT'(OSGUI.CUR_CONTEXT[ARACC_POINTER]); LET OSGUI.CONTEXT_POINTER=`
`17515:ARACC_POINTER; GOTO 17545`
`17520 LET OSGUI.SCRNID$="ARACC.BRC",OSGUI.WIND_ID[1]=1,`
`17520:OSGUI.CONTEXT_POINTER=-1,ARACC_POINTER=1`

As a general rule, windows created by F6 Maintenance functions, Shift+F2 Information functions, additional descriptions logic, and other black-box programs are destroyed. In a chain of programs in which the window is used repetitively, such as in file maintenance or daily work functions, windows should be hidden.

Add GUI_ID and GUI Buttons to HLE and Inquiry Programs

If you are working with Inquiry, HLE, or other functions where you use a command line to activate certain tasks, you must add button controls to your resource file, along with a grid control.

For HLE screens, the control ID of the grid must be 7000, 7010, and so on., depending on how many scroll regions are on the screen. For inquiry functions and other programs that use X3=9 keystroke commands, the control ID of the grid must be 4999.

When you convert these programs, you must set GUI_ID each time you CALL GENLINE, or when you set X3=9 before you CALL GENINPUT.

You must also use the BUTTON_KEYS$[ALL] array to tell the GENLINE or GENINPUT routines the values to return in X$ when the user clicks each button. This 2-dimensional array contains control IDs and their X$ value to return if operated. Here is a code sample from ARACC3 that illustrates how to use the array:

`18500 REM 18500,5 "----- Setup Button Keys for HLE's`
`18505 GUI_BUTTONS:`
`18510 IF GUI=0 THEN RETURN`
`18515 DIM BUTTON_KEYS$[1:6,1:2]; LET BUTTON_KEYS$[1,1]="9000",`
`18515:BUTTON_KEYS$[1,2]=$0D$,BUTTON_KEYS$[2,1]="9010",BUTTON_KEYS$[2,2]="A",`
`18515:BUTTON_KEYS$[3,1]="9020",BUTTON_KEYS$[3,2]="H",BUTTON_KEYS$[4,1]="9030"`
`,`
`18515:BUTTON_KEYS$[4,2]="N",BUTTON_KEYS$[5,1]="9040",BUTTON_KEYS$[5,2]="P",`
`18515:BUTTON_KEYS$[6,1]="9050",BUTTON_KEYS$[6,2]="G"`
`18520 RETURN`

This code sets up 6 buttons. The first series of elements holds the control ID of each button, and the second holds the value to be returned in X$ if the user clicks on the button. Use $0D$ to return the Enter key, and $09$ to return the Tab key.

You can assign the values to the BUTTON_KEYS$[ALL] array anywhere within the program (before you CALL GENLINE or GENINPUT). However, it is more convenient to add a subroutine as in the above example.

Add the GUI_LN[ ] Array to HLE Screens

You must tell GENLINE exactly where each column in the LN$[ ] array ends. For example, in the Inventory Price Structures HLE, the LN$[ ] array contains this data from sample data (the column numbers in the first two rows are not in the array, they are only for reference):

1111111111222222222233333333334444444444555555555566666666667777 1234567890123456789012345678901234567890123456789012345678901234567890123

`Cust Lvl` | `Description` | `Adjustment Base` | `%/$` | `Adj Amount`
`NONE` | `Price Structure Default` | `Calc. price` | `$` | `.0000`
`ACE001` | `Ace Builders Contract` | `Base cost` | `%` | `10.0000`
`JOBBER` | `Jobber Customer` | `Calc. price` | `%` | `-10.0000`
`RETAIL` | `Retail Customer Pricing` | `Calc. price` | `$` | `.0000`
`WHSL` | `Wholesale Customer` | `Base cost` | `%` | `10.0000`

Note how the columns are justified and the positions at which they end (include any spaces after character fields unless it followed by a numeric field):

Column Name | End Pos | Justification
Customer Level | 10 | Left
Description | 37 | Left
Adjustment Base | 55 | Left
Type ($/%) | 56 | Center
Adjustment Amount | 73 | Right

Use the GUI_LN[ ] array to pass this information to GENGULIN.PUB, which uses it to determine how to display data in each column of the grid. This sample from the SETUP section of INACPS illustrates the use of the GUI_LN[ ] array:

`1472 LET GUI_LN[1,1]=10,GUI_LN[2,1]=37,GUI_LN[3,1]=55,GUI_LN[4,1]=56,`
`1472:GUI_LN[5,1]=73`
`1474 LET`
`GUI_LN[1,2]=0,GUI_LN[2,2]=0,GUI_LN[3,2]=0,GUI_LN[4,2]=2,GUI_LN[5,2]=1`

GUI_LN[ ] is a two-dimensional array. The first series of elements stores the ending character position for each column. The second set of elements stores what type of justification to use for each column. Use 0 for left-justified, 1 for right-justified, and 2 for centered. If the field is a YES/NO only field, you can also set the second element to 3 for a check box.

As with standard screens, alphanumeric data should be left-justified with the column header, and numeric data is right justified.