This article is for all of us, who work with OPEN_FORM instead of CALL_FORM.
OPEN_FORM has benefits and problems. The user can easily switch between all open forms, but when he closes one of the forms, he only closes the current form.
Solution: Normally all applications have a start form, from where all other forms were opened. When the user is in this form and he presses exit-form, then he wants to close the whole application and not only the start form. In this case we need a method, which loops through all open forms and closes them.
Finding all open forms is a hard job. So, the best way is to store all of them in a global list named GLOBAL.OPEN_FORMS. Values are separated by semicolons, like: ;STARTFORM;EMP;DEPT;
We need a PRE-FORM and a POST-FORM-trigger for all forms, except the startform. The Pre-Form appends the name of the current form to the list, the Post-Form erases an entry.
PRE-FORM :
OPEN_FORM has benefits and problems. The user can easily switch between all open forms, but when he closes one of the forms, he only closes the current form.
Solution: Normally all applications have a start form, from where all other forms were opened. When the user is in this form and he presses exit-form, then he wants to close the whole application and not only the start form. In this case we need a method, which loops through all open forms and closes them.
Finding all open forms is a hard job. So, the best way is to store all of them in a global list named GLOBAL.OPEN_FORMS. Values are separated by semicolons, like: ;STARTFORM;EMP;DEPT;
We need a PRE-FORM and a POST-FORM-trigger for all forms, except the startform. The Pre-Form appends the name of the current form to the list, the Post-Form erases an entry.
PRE-FORM :
DEFAULT_VALUE (';', 'GLOBAL.OPEN_FORMS'); :GLOBAL.OPEN_FORMS := :GLOBAL.OPEN_FORMS || :SYSTEM.CURRENT_FORM || ';';
POST-FORM :
:GLOBAL.OPEN_FORMS := REPLACE (:GLOBAL.OPEN_FORMS, ';' || :SYSTEM.CURRENT_FORM || ';', ';');
Now we have the names of all open forms in a global list.
The KEY-EXIT trigger in the startform needs a loop, which closes all other forms and at then startform.
KEY-EXIT in startform :
DECLARE V_Form VARCHAR2 (30); BEGIN One_Time_Timer.Initialize ('EXIT_STARTFORM'); DEFAULT_VALUE (';', 'GLOBAL.OPEN_FORMS'); WHILE :GLOBAL.OPEN_FORMS != ';' LOOP V_Form := Substr (:GLOBAL.OPEN_FORMS, 2, InStr (:GLOBAL.OPEN_FORMS, ';', 1, 2) - 2); COPY ('J', 'GLOBAL.EXIT_IMMEDIATE'); GO_FORM (V_Form); END LOOP; END;
The startform is closed through WHEN-TIMER-EXPIRED :
IF One_Time_Timer.Get_Value = 'EXIT_STARTFORM' THEN EXIT_FORM (no_validate); END IF;
All other forms need a WHEN-FORM-NAVIGATE trigger:
DEFAULT_VALUE ('N', 'GLOBAL.EXIT_IMMEDIATE'); IF :GLOBAL.EXIT_IMMEDIATE = 'J' THEN EXIT_FORM (no_validate); END IF;
Now you have a powerful autoclose-method for all opened forms.
PACKAGE Const IS gbl_One_Time_Timer CONSTANT VARCHAR2 (61) := upper ('global.One_Time_Timer'); END; PACKAGE One_Time_Timer IS FUNCTION Get_Value RETURN VARCHAR2; PROCEDURE Initialize (P_Event IN VARCHAR2); END; PACKAGE BODY One_Time_Timer IS FUNCTION Get_Value RETURN VARCHAR2 IS BEGIN Default_Value (NULL, Const.gbl_One_Time_Timer); RETURN (NAME_IN (Const.gbl_One_Time_Timer)); END; PROCEDURE Initialize (P_Event IN VARCHAR2) IS tm_id timer; tm_name VARCHAR2 (30) := 'ONE_TIME_TIMER'; BEGIN tm_id := Find_Timer (tm_name); IF ID_Null (tm_id) THEN tm_id := Create_Timer (tm_name, 10, NO_REPEAT); COPY (p_Event, Const.gbl_One_Time_Timer); END IF; END; END One_Time_Timer;
No comments:
Post a Comment