One of the most common errors in a WebFOCUS Maintain application is opening forms without ever closing them. As each form is opened in a WebFOCUS Maintain application, it is stacked on top of the previous form. Since each form is displayed in a separate browser page, it is easy to open more and more forms without ever closing them.
This leads to a Stack Overflow error. This error indicates that you have opened too many forms and never closed any of them. Your host platform cannot possibly handle holding that many in memory.
To avoid this problem, we recommend having only one form open at a time. When you open one form, close the previous one. Placing the following syntax in your procedure does not work because WebFOCUS Maintain ignores any code after a Winform Close statement. After closing FORM1, control returns to the command after the command that opened FORM1.
Winform Close FORM1 Winform Show FORM2
To solve this problem, you can implement a driver procedure.
The theory behind the driver procedure is simple. Have a variable (for example, NEXT_FORM) which contains the name of the next form to open. The driver procedure is just a REPEAT loop which opens the form indicated by NEXT_FORM. When you are done with NEXT_FORM, you set NEXT_FORM to contain the name of the next form that you want to open before coding the Winform Close form. This continues until you EXIT the application, or until NEXT_FORM equals EXIT or some other ending string.
Here is an example of some of a driver procedure:
MAINTAIN CASE TOPCASE COMPUTE NEXT_FORM/A66 = 'MAINMENU'; PERFORM DRIVER ENDCASE CASE DRIVER REPEAT WHILE NEXT_FORM NE ' '; IF NEXT_FORM EQ 'MAINMENU' THEN Winform Show MAIN_MENU_FORM ELSE IF NEXT_FORM EQ 'UPDATE' -* call another procedure to show a form THEN CALL UPD_PROC FROM NEXT_FORM INTO NEXT_FORM ELSE IF NEXT_FORM EQ 'DELETE' THEN Winform Show DELETE_FORM ENDREPEAT ENDCASE
Notice that TOPCASE sets NEXT_FORM to be MAINMENU (this is the first form that we show). This form has two buttons: Update and Delete. These two buttons, when clicked, execute the functions UPDATE_CASE and DELETE_CASE, respectively:
CASE UPDATE_CASE COMPUTE NEXT_FORM = 'UPDATE' Winform Close MAIN_MENU_FORM ENDCASE CASE DELETE_CASE COMPUTE NEXT_FORM = 'DELETE' Winform Close MAIN_MENU_FORM ENDCASE
Notice in the above cases, we set NEXT_FORM and then close MAIN_MENU_FORM. The driver loop takes care of showing the next form. Only one form is ever open.
The driver loop handles UPDATE and DELETE in two different ways. DELETE just shows another form (DELETE_FORM), but UPDATE actually calls another procedure called UPD_PROC. Look at UPD_PROC:
MAINTAIN FROM NEXT_FORM INTO NEXT_FORM CASE TOPCASE COMPUTE NEXT_FORM/A10='MAINMENU'; LOCAL_NEXT_FORM/A10='UPD_FORM1'; PERFORM MINI_DRIVER ENDCASE CASE MINI_DRIVER REPEAT WHILE LOCAL_NEXT_FORM NE ' '; IF LOCAL_NEXT_FORM EQ 'GOAWAY' THEN GOTO EXITREPEAT ELSE IF LOCAL_NEXT_FORM EQ 'UPD_FORM1' THEN PERFORM Winform_UPD_FORM1 ELSE IF LOCAL_NEXT_FORM EQ 'UPD_FORM2' THEN PERFORM Winform_UPD_FORM2 ENDREPEAT ENDCASE
The initial procedure passed NEXT_FORM to this procedure from the CALL statement. This way, when UPD_PROC finishes executing and returns to the initial procedure, it knows where to go. Also, UPD_PROC defines a LOCAL_NEXT_FORM variable and a mini driver function within UPD_PROC, so we can control the form flow locally to this procedure too.
Clicking the Delete button on UPD_FORM2 triggers the following function and goes directly to DELETE_FORM in the driver.
CASE DELETE_FORM COMPUTE NEXT_FORM = 'DELETE'; LOCAL_NEXT_FORM = 'GOAWAY'; Winform Close UPD_FORM2 ENDCASE
You can use this driver technique to control the flow of your entire application. It is incredibly useful and guarantees that you do not have a Stack Overflow problem in your application, because you only have one form open at any given time.
It is very easy to write one of these driver loops if you diagram your Form flow.