%StandardWindowCode #GROUP 

Top  Previous  Next

This #GROUP actually generates all the source code for the Window template. This includes all the local data declarations, standard window handling code, and provides all the "hooks" for all the control and extension templates to attach into the generated procedure.

#GROUP(%StandardWindowCode)

#IF(NOT %Window)

 #ERROR(%Procedure & ' Error: No Window Defined!')

 #RETURN

#ENDIF

#DECLARE(%FirstField)

#DECLARE(%LastField)

#DECLARE(%ProgressWindowRequired)

#INSERT(%FieldTemplateStandardButtonMenuPrompt)

#INSERT(%FieldTemplateStandardEntryPrompt)

#INSERT(%FieldTemplateStandardCheckBoxPrompt)

#EMBED(%GatherSymbols,'Gather Template Symbols'),HIDE

#INSERT(%FileControlInitialize)

%Procedure %ProcedureType%Parameters

 

#FOR(%LocalData)

%[20]LocalData %LocalDataStatement

#ENDFOR

#INSERT(%StandardWindowGeneration)

#IF(%ProgressWindowRequired)

#INSERT(%StandardProgressWindow)

#ENDIF

 CODE

 PUSHBIND

 #EMBED(%ProcedureInitialize,'Initialize the Procedure')

 LocalRequest = GlobalRequest

 OriginalRequest = GlobalRequest

 LocalResponse = RequestCancelled

 ForceRefresh = False

 CLEAR(GlobalRequest)

 CLEAR(GlobalResponse)

 #EMBED(%ProcedureSetup,'Procedure Setup')

 IF KEYCODE() = MouseRight

   SETKEYCODE(0)

 END

 #INSERT(%StandardFormula,'Procedure Setup')

 #INSERT(%FileControlOpen)

 #INSERT(%StandardWindowOpening)

 #EMBED(%PrepareAlerts,'Preparing Window Alerts')

 #EMBED(%BeforeAccept,'Preparing to Process the Window')

 #MESSAGE('Accept Handling',3)

 ACCEPT

   #EMBED(%AcceptLoopBeforeEventHandling,'Accept Loop, Before CASE EVENT() handling')

   CASE EVENT()

   #EMBED(%EventCaseBeforeGenerated,'CASE EVENT() structure, before generated code')

   #INSERT(%StandardWindowHandling)

   #EMBED(%EventCaseAfterGenerated,'CASE EVENT() structure, after generated code')

   END

   #EMBED(%AcceptLoopAfterEventHandling,'Accept Loop, After CASE EVENT() handling')

   #SUSPEND

   #?CASE ACCEPTED()

   #INSERT(%StandardAcceptedHandling)

   #?END

   #RESUME

   #EMBED(%AcceptLoopBeforeFieldHandling,'Accept Loop, Before CASE FIELD() handling')

   #SUSPEND

   #?CASE FIELD()

   #EMBED(%FieldCaseBeforeGenerated,'CASE FIELD() structure, before generated code')

   #INSERT(%StandardControlHandling)

   #EMBED(%FieldCaseAfterGenerated,'CASE FIELD() structure, after generated code')

   #?END

   #RESUME

   #EMBED(%AcceptLoopAfterFieldHandling,'Accept Loop, After CASE FIELD() handling')

 END

 DO ProcedureReturn

!---------------------------------------------------------------------------

ProcedureReturn ROUTINE

!|

!| This routine provides a common procedure exit point for all template

!| generated procedures.

!|

!| First, all of the files opened by this procedure are closed.

!|

!| Next, if it was opened by this procedure, the window is closed.

!|

!| Next, GlobalResponse is assigned a value to signal the calling procedure

!| what happened in this procedure.

!|

!| Next, we replace the BINDings that were in place when the procedure initialized

!| (and saved with PUSHBIND) using POPBIND.

!|

#IF(%ReturnValue)

!| Finally, we return to the calling procedure, passing %ReturnValue back.

#ELSE

!| Finally, we return to the calling procedure.

#ENDIF

!|

 #INSERT(%FileControlClose)

 #INSERT(%StandardWindowClosing)

 #EMBED(%EndOfProcedure,'End of Procedure')

 #INSERT(%StandardFormula,'Procedure Exit')

 IF LocalResponse

   GlobalResponse = LocalResponse

 ELSE

   GlobalResponse = RequestCancelled

 END

 POPBIND

 #IF(%ProcedureType='FUNCTION')

 RETURN(%ReturnValue)

 #ELSE

 RETURN

 #ENDIF

!---------------------------------------------------------------------------

InitializeWindow ROUTINE

!|

!| This routine is used to prepare any control templates for use. It should be called

!| once per procedure.

!|

 #EMBED(%WindowInitializationCode,'Window Initialization Code')

 DO RefreshWindow

!---------------------------------------------------------------------------

RefreshWindow ROUTINE

!|

!| This routine is used to keep all displays and control templates current.

!|

 IF %Window{Prop:AcceptAll} THEN EXIT.

 #EMBED(%RefreshWindowBeforeLookup,'Refresh Window routine, before lookups')

 #INSERT(%StandardFormula,'Before Lookups')

 #INSERT(%StandardSecondaryLookups)

 #INSERT(%StandardFormula,'After Lookups')

 #EMBED(%RefreshWindowAfterLookup,'Refresh Window routine, after lookups')

 #EMBED(%RefreshWindowBeforeDisplay,'Refresh Window routine, before DISPLAY()')

 DISPLAY()

 ForceRefresh = False

!---------------------------------------------------------------------------

SyncWindow ROUTINE

 #EMBED(%SyncWindowBeforeLookup,'Sync Record routine, before lookups')

 #INSERT(%StandardFormula,'Before Lookups')

 #INSERT(%StandardSecondaryLookups)

 #INSERT(%StandardFormula,'After Lookups')

 #EMBED(%SyncWindowAfterLookup,'Sync Record routine, after lookups')

!---------------------------------------------------------------------------

#EMBED(%ProcedureRoutines,'Procedure Routines')

#EMBED(%LocalProcedures,'Local Procedures'),HIDE

 

This starts with the required #GROUP statement which identifies the group for use in #INSERT statements.

The #IF(NOT %Window) error check detects whether the programmer has forgotten to create a window for the procedure. The #ERROR statement alerts the programmer to the mistake and #RETURN immediately aborts any further source generation for the procedure. The #DECLARE statements declare two template symbols for internal use by other #GROUPs that are called to generate source for the procedure, and a "flag" that determines whether a "progress" window is required by the procedure.

The next three #INSERT statements insert #GROUPs that contain #FIELD structures to define the standard prompts that appear on the Actions tab for BUTTON, ENTRY and CHECK controls placed on the procedure's window. These prompts allow the programmer to specify the standard actions these controls can take from this procedure.

The %GatherSymbols #EMBED statement has the HIDE attribute. This means that it will not appear in the list of available embed points for the programmer to insert code, making the embed point only available for internal use (for Code, Control, or Extension templates to generate code into).

The #INSERT(%FileControlInitialize) statement inserts a #GROUP that updates the symbols that keep track of the files used in the application with the files used by this procedure.

The %Procedure %ProcedureType%Parameters statement generates the first Clarion language source code for the procedure. It generates the procedure's PROCEDURE statement, with or without a parameter list, as appropriate.

The #FOR(%LocalData) loop generates all the local variable declarations for the procedure. The %[20]LocalData syntax means that the %LocalData symbol expands to fill at least 20 spaces before the %LocalDataStatement symbol expands. This aligns the data types for each variable declaration starting in column 22.

The #INSERT(%StandardWindowGeneration) statement generates the procedure's WINDOW or APPLICATION data structure. This #GROUP also contains two #EMBED statements that allow the programmer to embed code either before or after the window structure.

The #IF(%ProgressWindowRequired) statement conditionally #INSERTs the %StandardProgressWindow group, which generates the ProgressWindow WINDOW structure for the procedure.

Next, the CODE statement generates, to begin the procedure's executable code section, whcih starts with a PUSHBIND statement to eliminate any BIND scoping problems. The %ProcedureInitialize #EMBED statement is the first programmer-available embed point in the executable code portion of the procedure.

The next six Clarion language statements are directly generated into the procedure to set it up for the action it should perform, as signaled to the procedure through the GlobalRequest variable. The %ProcedureSetup #EMBED statement is the next programmer-available embed point in the executable code portion of the procedure.

The IF KEYCODE() = MouseRight structure detects when the procedure has been called as a result of a RIGHT-CLICK popup menu. If so, it ensures that the keycode is cleared to prevent multiple execution.

The %StandardFormula #INSERT statement generates all the "Procedure Setup" class formulas. Following that, the #INSERT(%FileControlOpen) generates the code to open all the files used in the procedure (if they are not already open). This #GROUP also contains two #EMBED statements that allow the programmer to embed code either before or after the files are opened.

The #INSERT(%StandardWindowOpening) generates the OPEN(window) statement, and the .INI file handling code (if the programmer has checked the Use .INI file to save and restore program settings box). This #GROUP also includes two #EMBED statements that allow the programmer to embed code either before or after opening the window.

The next two #EMBED statements allow the programmer to embed code before entering the procedure's ACCEPT loop. #MESSAGE displays its message during source generation.

The ACCEPT loop is Clarion's event handling structure. The next #EMBED (%AcceptLoopBeforeEventHandling) allows the programmer to add code that will be the first to "see" any event that ACCEPT passes on. The CASE EVENT() structure contains all the code to handle field-independent events, generated from the #INSERT(%StandardWindowHandling) statement. This #GROUP is discussed in detail in its own section. The two #EMBED statements that surround this #INSERT and the one following the CASE EVENT structure all give the programmer the opportunity to explicitly handle anyt field-independent event not covered by the generated code.

The #SUSPEND statement means that conditional code statements (those prefaced with #?) will only generate if an explicit code statement (without #?) is also generated for the event, or if the programmer has placed some embedded source or used a Code template in an embed point associated with the event being processed. This is the mechanism that allows Clarion's Template Language to only generate code that is actually required for the procedure, eliminating unnecessary generated code.

The #?CASE ACCEPTED() structure contains all the code to handle all the Accepted events for menu items. Since menu items only generate Accepted events, this structure keeps the following CASE FIELD() structure from becoming unwieldy. This line of code, since it is prefaced with #?, will only generate if there is some other code generated within it, eliminating an empty CASE structure. The code for the CASE structure is generated by the #INSERT(%StandardAcceptedHandling) statement. This #GROUP is also discussed in detail in its own section. The #?END statement will only generate an END statement if other code has already been generated.

The #RESUME statement terminates the #SUSPEND section. If no source code has actually been generated, none of the conditional source statements (prefaced by #?) between the #SUSPEND and the #RESUME generate.

The #?CASE FIELD() structure (also bracketed within #SUSPEND and #RESUME statements) contains all the code to handle all the field-specific events. The code for the CASE structure is generated by the #INSERT(%StandardControlHandling) statement (between its two #EMBED statements). This #GROUP is also discussed in detail in its own section. The #?END statement will only generate an END statement if other code has already been generated. The #EMBED immediately following #RESUME provides an embed point at the bottom of the ACCEPT loop.

The END statement terminates the ACCEPT loop. This statement is always generated (as is the ACCEPT) because every window requires an ACCEPT loop directly associated with it to process the events for that window. The DO ProcedureReturn statement calls the "cleanup code" for the procedure.

The ProcedureReturn ROUTINE begins with a comment block that generates into the Clarion code to explain the ROUTINE's purpose. The first line of code in the ROUTINE is the #INSERT(%FileControlClose) statement. This generates the code to close the files that were opened by the procedure. This #GROUP also contains two #EMBED statements that allow the programmer to embed code either before or after the files are closed.

The #INSERT(%StandardWindowClosing) generates the CLOSE(window) statement , and the .INI file handling code (if the programmer has checked the Use .INI file to save and restore program settings box). This #GROUP also includes two #EMBED statements that allow the programmer to embed code either before or after closing the window.

The next #EMBED allows the programmer to embed code before closing the procedure's window. The next #INSERT statement generates all the "Procedure Exit" class formulas. The next five Clarion language statements set up the procedure to alert the calling procedure to the action it performed, signaled back to the calling procedure through the GlobalRequest variable. The POPBIND statement eliminates any BIND scoping problems. The #IF structure then determines whether the procedure returns a value and generates the correct RETURN statement.

The InitializeWindow ROUTINE is a standard routine in all of Clarion's shipping Templates. It starts with a comment block, then the #EMBED allows the programmer to perform any initialization code for themselves, and provides Code, Control ,and Extension templates a place to generate their window initialization code. The DO RefreshWindow statement calls the routine to display the current contents of all the controls' USE variables at the time the window is initialized.

The RefreshWindow ROUTINE is another standard routine in all of Clarion's shipping Templates that performs the procedure's MANY:1 lookups and refreshes the screen to ensure any changed data correctly displays to the user at all times. The ROUTINE starts with a comment block then the IF %Window{PROP:AcceptAll} THEN EXIT. statement. This detects when the procedure is on "non-stop" mode performing all data validity checks prior to writing a record to disk, and aborts the re-display.

The first #EMBED allows the programmer to embed code before the lookups. The next #INSERT generates all the "Before Lookups" class formulas, then #INSERT(%StandardSecondaryLookups) generates the code to get all the related records for the procedure. The next #INSERT generates all the "After Lookups" class formulas, then comes a #EMBED to allow the programmer to embed code after the lookups. The DISPLAY statement puts any changed values on screen, and ForceRefresh = False turns off the procedure's screen refresh flag.

The SyncWindow ROUTINE is also a standard routine in all of Clarion's shipping Templates. It performs the same lookups as the RefreshWindow ROUTINE, with similar embed points, but does not refresh the screen. Instead, it ensures all record buffers contain correct data. This ROUTINE is usually called before executing some action that may require the currently highlighted record in a LIST.

The next to last #EMBED statement allows the programmer to embed any ROUTINEs they have called from their code within other embed points. The last #EMBED statement allows any other templates to embed any local PROCEDUREs that are called from their code.