Introduction

Many developers use Commuter Modules as an efficient method for managing most event handlers for their OpenInsight forms. Typically, Commuter Modules are called from the form's Script Event or QuickEvent handlers. SRP FrameWorks leverages the power of their unique Promoted Event architecture to automate the execution of Commuter Modules while giving the developer tighter control over the entire event flow.

Commuter Modules and the OpenInsight Event Chain

SRP FrameWorks does not alter the way OpenInsight executes the internal event chain. In fact, it really just exploits the functionality that has been built into the product from the inception of the product. However, because of the way Promoted Events and Commuter Modules are integrated into SRP FrameWorks, there appears to be a modification in the way the event chain is executed. Most of this is detailed in the Promoted Event subject page but some explanation on how Commuter Modules fit within this new event paradigm should be given.

First, let's take a look at the standard OpenInsight event chain. As pictured below, when an event occurs this triggers a chain of events which starts with the Script Event handler (a control specific event handler) and ends with the QuickEvent handler (which is really called by the SYSPROG application level event handler). Thus, there is a flow that goes from the most specific event handler down to the most generic event handler.

Since developers only have access to the Script Event and QuickEvent handlers, this is where Commuter Module routines are called from. Because of the cumbersome nature of Script Event handlers, QuickEvent handlers are used the majority of the time. Even if the application uses Promoted Events, the execution of Commuter Modules from QuickEvent handlers always forces the relevant event logic to be executed at the very end of the event chain. Consequently, event though Commuter Modules handle control specific event handling, the more generic event handlers (i.e. the Promoted Events) are executed first. Not only does this work against the natural design of OpenInsight, it works contrary to the Object Oriented concept of inheritance.

In order to salvage the advantages of Commuter Module methodology and restore their order of execution to be at the beginning of the event chain, SRP FrameWorks will call Commuter Modules first and then pass control to the rest of the event chain (Note: Commuter Modules decide if and how the event chain will continue. This is explain in further detail below in the Event Flow section.) Thus, the SRP FrameWorks event chain appears to flow in this manner:

Therefore, the developer can anticipate that their Commuter Module will always be called ahead of any Promoted Event logic and the system event handler. As documented below, the developer even has the ability to decide if the Promoted Event logic should execute and/or if the system event handler should execute.

Anatomy of a Commuter Module

Because Commuter Modules behave as extensions to event handlers they are designed as functions. This provides the ability for special event chaining operations to take place. In SRP FrameWorks, Commuter Modules should always follow the same basic four-part structure as described below.

Signature Line

Due to the automated processes that call Commuter Modules the signature line should use the standard naming convention and argument list:

 Function FormName_Events(CtrlEntId, Event, Param1, Param2, ..., Param15)

Insert Block

SRP FrameWorks provides two standard inserts for Commuter Modules:

$insert APP_INSERTS
$insert EVENT_SETUP

APP_INSERTS declares common subroutine and function names and also combines common equates such as those found in LOGICAL and COLORS. EVENT_SETUP populates important variables that are necessary for Commuter Modules to function properly.

Body

After the insert block has been executed the main body of the Commuter Module is ready for action. Between the signature arguments and the variables populated by the EVENT_SETUP insert a great deal of information is available to the developer so that proper calling of specific event handling logic can be performed. Here are a few of the more common variables that are pre-populated:

VariablePurpose
CtrlEntIdThe fully qualified name of the control that is connected to the current event.
EventTypically, the name of the event as OpenInsight sees it (e.g. CLICK, GOTFOCUS, CREATE). Note: For ActiveX controls, SRP FrameWorks substitutes the generic OpenInsight OLE event with the event as the ActiveX control sees it (e.g. OnClick, OnDblClick). This provides a more uniform event management model for the developer within the Commuter Module.
EventTypeThe true name of the event as OpenInsight sees it. The Get_Current_Event() function is used to populate this variable. For example, if an ActiveX control is being used and an OnClick event is generated. The Event variable will contain OnClick but the EventType variable will contain OLE. For native OpenInsight controls, Event and EventType will always have the same value.
EventActionA concatenation of the Event and Control variables. The format is Event.Control (e.g. CLICK.PUB_OK).
WindowThe core name of the form (window) that is active. The @WINDOW system variable is used but any instance references are removed. Thus, if @WINDOW has the value DBW_CUSTOMERS*2 then Window would have the value DBW_CUSTOMERS.
ControlThe core name of the control that is connected to the current event. If the control is the form then Control will have the same value as the Window variable. Otherwise, it will be the name of the control as it appears in the Form Designer. Thus, if CtrlEntId has the value DBW_CUSTOMERS*5.PUB_OK then Control will have the value DBW_OK.

These variables provide the developer with enough information to properly route event handler requests to specific blocks of code within the Commuter Module. In SRP FrameWorks, Commuter Modules utilize Case statements to broker these event handler requests. Here is a simple example of what this looks like:

 Begin Case 
   Case Control EQ Window 
   // This event is window specific. 
              
       Begin Case 
           Case Event EQ "CREATE"              ; GoSub CREATE 
           Case Event EQ "VSCROLL"             ; GoSub VSCROLL 
           Case Event EQ "FORMOPTS"            ; GoSub FORMOPTS 
           Case Event EQ "READ"                ; GoSub READ 
           Case Event EQ "WRITE_PRE"           ; GoSub WRITE_PRE 
           Case Event EQ "CLEAR"               ; GoSub CLEAR 
       End Case 
       
       Case Control EQ "OLE_TAB" 
       
       Begin Case 
           Case Event EQ "SelChanged"          ; GoSub SelChanged.OLE_TAB 
       End Case 
       
       Case Control EQ "OLE_EDITTABLE" 
          
           Begin Case 
               Case Event EQ "BeforeUpdate"        ; GoSub BeforeUpdate.OLE_EDITTABLE 
               Case Event EQ "AfterUpdate"         ; GoSub AfterUpdate.OLE_EDITTABLE 
               Case Event EQ "PosChanging"         ; GoSub PosChanging.OLE_EDITTABLE 
               Case Event EQ "PosChanged"          ; GoSub PosChanged.OLE_EDITTABLE 
               Case Event EQ "AfterDeleteRecords"  ; GoSub AfterDeleteRecords.OLE_EDITTABLE 
               Case Event EQ "OnOptionClick"       ; GoSub OnOptionClick.OLE_EDITTABLE 
               Case Event EQ "LostFocus"           ; GoSub LostFocus.OLE_EDITTABLE 
           End Case 

 End Case

The developer is free to use their own preferred method of code branching (e.g. some developers use the On...GoSub' statement.) While other methods might be more efficient in terms of processing cycles, Case statements tend to be easier to read and manage as the number of event handler requests grows.

Return Line

When the Commuter Module is finished executing the event handler request it will need to return control back to the calling process (i.e. basically, the event chain). Therefore, the value of the return variable is important for determining if and how the event chain should continue. Here is a standard way SRP FrameWorks Commuter Modules structure their return line sections:

If Assigned(EventFlow) else EventFlow = EVENT_CONTINUE$
Return EventFlow

The EventFlow return variable should be set to 0, 1, 2, or 3. 0 and 1 are traditional values known to OpenInsight developers. The other values are unique to SRP FrameWorks and are described below:

ValueEquate Name (from EVENT_INSERTS)Purpose
0EVENT_STOP$Event flow should stop.
1EVENT_CONTINUE$Event flow should continue until a later process changes this value.
2EVENT_CONTINUE_NO_PROMOTED$Event flow should by-pass the promoted (generic) logic but allow the system event handler to execute.
3EVENT_CONTINUE_NO_SYSTEM$Event flow should execute the promoted (generic) logic but stop the system event handler from executing.

In the vast majority of situations, the event chain will be allowed to continue. Therefore, to make the Commuter Module code easier to manage, the above example checks to see if EventFlow has been assigned a value. If not then it is set to EVENT_CONTINUE$. This way the Commuter Module defaults on the principle that the event chain will continue normally. This frees the developer from having to worry about assigning this variable in normal situations.

Pre and Post System Event Handling

For most event requests there is no need to process the request before the System Event handler. This is either because the event does not have an associated System Event handler or there is no benefit from having the ability to prevent the System Event handler from continuing. Therefore, most event requests passed into the Commuter Module will technically execute after System Event handler. However, for some events having the ability to handle the request before the System Event handler is critical.

In order to distinguish between an event request which is occurring before the System Event handler versus after the System Event handler, SRP FrameWorks adds a "_PRE" suffix to the Event argument. Otherwise, it is simply left alone. Thus, the logic in the Body of the Commuter Module could look like this:

 Begin Case 
   Case Control EQ Window 
   // This event is window specific. 
              
       Begin Case 
           Case Event EQ "CREATE"              ; GoSub CREATE 
           Case Event EQ "WRITE_PRE"           ; GoSub WRITE_PRE 
           Case Event EQ "WRITE"               ; GoSub WRITE 
           Case Event EQ "READ_PRE"            ; GoSub READ_PRE 
           Case Event EQ "READ"                ; GoSub READ 
       End Case 
      
 End Case

In the above block there is a pre and post System Event handler check for the WRITE and READ events. It should be noted that if the developer returns a 0 (EVENT_STOP$) or a 3 (EVENT_CONTINUE_NO_SYSTEM$) during a pre System Event event block of code (e.g. WRITE_PRE, READ_PRE) then neither the System Event handler itself or the post System Event handler logic in the Commuter Module will be executed. This is the equivalent of returning a 0 in the Script event handler which then prevents the System Event and QuickEvent handlers from executing.

Adding or Removing Event Handlers

Normally, changing event handlers require the use of the Form Designer. After loading the form in design mode, Script event or QuickEvent handlers are added or removed as needed. Since SRP FrameWorks automatically calls a form's Commuter Module for all possible event combinations all that is required is for the developer to add or remove a check for the specific control and event combination in the Commuter Module. This provides a very convenient and flexible way for developers to manage events. For example, even while a form is running, a developer can add a GOTFOCUS event to any control and test it immediately.

Commuter Module Examples

SRP FrameWorks provides three sample forms with associated Commuter Modules to serve as starting examples: DBW_SAMPLE1_EVENTS, DBW_SAMPLE2_EVENTS, and DBW_SAMPLE3_EVENTSDBW_SAMPLE3_EVENTS is more complicated than the other two because of the ActiveX control events that are included. Using the SRP Form Copy utility is an easy way to take advantage of these sample forms.

  • No labels