Look at the main block
- Last Updated: December 20, 2023
- 5 minute read
- OpenEdge
- Version 13.0
- Documentation
So far most of the code you looked at has been set-up code. It is either definitions of objects and variables or triggers to execute when events happen later on.
Finally you arrived at the part of the procedure that is actually executed when you run the procedure. This is the main block of the procedure. Note that main block is not an ABL syntax element or a required structure in any way. It is really just a convention observed by the Section Editor. After all the definitions and triggers, you write the executable code for the procedure itself.
The main block of an AppBuilder-generated procedure that creates a window is entirely standard. You can add more initialization code to the block if you wish, but normally you do not want to remove what it already does. A few of these statements will not mean a lot to you yet, but for now take a quick look at this block to see a bit more about how events are set up for a typical GUI application.
CURRENT-WINDOW. As the comment on the statement explains, this
determines defaults for proper parenting of dialog boxes and frames to the windows with
which they are associated:
|
WINDOW-CLOSE event, then another trigger for when
the user clicks on the close button in the upper-right corner of a window. This event in
turn applies the CLOSE event to the executing procedure
itself:
|
|
When the user clicks the close button in the window, a trigger applies a
CLOSE event to the procedure. Now here in the main block is another
trigger block that defines the action for that CLOSE event, namely to
run an internal procedure called disable_UI. This AppBuilder-generated
procedure is the counterpart of enable_UI. It deletes the
C-Win structure that defines the window and then deletes the
procedure itself.
So now the AppBuilder has set up all the actions necessary to clean up when the window and the procedure that created it are no longer needed.
The next statement, PAUSE 0 BEFORE-HIDE, sets up a standard GUI default
for automatically hiding windows and frames when the user selects some other object that
is on top of them.
Now you get to the main block itself. The AppBuilder emphasizes this by giving the header
name MAIN-BLOCK to the DO-END block, which is the
heart of the procedure:
|
The qualifiers on the DO statement are not important for now. They simply
assure that on an error, a cancel, or an escape request from the user, the block
terminates. You learn more about undoing blocks in Manage Transactions.
The first action the block takes is to run the internal procedure
enable_UI. You have seen that enable_UI opens the
queries, gets a Customer, displays it and its Orders,
and enables all the fields. Remember that enable_UI does not have to
create the window because one of the few executable statements in all the code you
looked through before you got to the main block was the CREATE WINDOW
statement. So that has already happened before this point in the code.
Do not worry about the meaning of THIS-PROCEDURE:PERSISTENT just yet.
This condition is not true for this window when you run it by itself, as you are doing.
So the AVM executes the statement WAIT-FOR CLOSE OF THIS-PROCEDURE.
The WAIT-FOR statement is the crux of any event-driven application. A
standard procedure in an older application, or any procedure that simply performs a task
and then returns to its caller, proceeds through its list of statements and then ends.
When the AVM gets to the final executable statement in a procedure like that, it
automatically destroys the procedure (giving back the memory its variables used) and
returns to the caller.
But in our event-driven procedure, all that really has happened when this last statement is reached is to create a window, set up a few triggers, open two queries, display a record and a browse, and enable some fields. If the procedure were to terminate as soon as that was done, the user would have no chance to interact with the window.
To experiment and see what happens with and without the WAIT-FOR
statement:
- Highlight the two-line statement with the
WAIT-FORkeyword in it:
- From the AppBuilder menu, select .
This option puts comment markers around the text you selected. The Comment and Indent options are a handy way to try things out with and without bits of code you are testing.
- Click the Save button or select from the menu to save h-CustOrderWin1.w back to the operating system.
Now comes the tricky part. If you simply run the window procedure now from the
AppBuilder, it works perfectly well. That is, the window comes up and stays up until the
user closes it. How come? The AppBuilder is smart enough to realize that whenever you
run any procedure that has a window, it has to persist so that the user can interact
with it. So it effectively adds a WAIT-FOR statement for you for
testing purposes.
To see the actual effect of your change in a run-time environment:
- To bring up a separate editor window, select from the AppBuilder menu.
- Type the statement:
RUN h-CustOrderWin1.w. - Press F2 to run this procedure.
The test window flashes almost imperceptibly and then disappears. All the initialization
actions happen but then the procedure terminates. That is why you need the
WAIT-FOR.
To correct this code:
- Highlight the two lines you commented out and select .
- Click the Save button to resave the procedure.
- Select your Editor window and press F2.
Now the window comes up and stays up, waiting for the events that fire its trigger code, as you click buttons, and then finally the close event that terminates the procedures and destroys the window.
This exercise illustrates why you have to tell the AVM not to terminate the procedure
until the user is done with it. This is what the WAIT-FOR statement
does. And when you write a WAIT-FOR statement, you have to tell the AVM
to wait for some particular event, because otherwise the procedure would never end.
So the statement says to wait for the CLOSE event on the procedure. And
when will this happen? It will be when the user closes the window, as you saw. So at
that point the main block ends, the CLOSE trigger fires, which executes
the disable_UI code to clean up the resources the procedure and the
window use, and everything goes away.