Adding the second WAIT-FOR statement is very awkward, and it is pretty close to an absolute rule in ABL that your entire application, not just a single procedure, should have only a single WAIT-FOR statement. This rule is summarized in the saying: “One world, one WAIT-FOR.” Multiple WAIT-FOR statements can easily get tangled up in each other if they are not satisfied in the exact reverse order from the order they are defined in, and this can result in a WAIT-FOR that does not terminate properly.

So how else do you establish a trigger inside an internal procedure or a trigger block, or for that matter inside another external procedure that you call, and have that trigger persist beyond the scope of its declaration?

ABL provides a special statement to let you do this:

PERSISTENT RUN procedure-name [ (input-parameters ) ].

The persistent trigger definition can have only this one RUN statement (not a DO-END block with any other statements). You can pass optional INPUT parameters to the procedure you run but no OUTPUT or INPUT-OUTPUT parameters. If you pass parameters, the parameter values are evaluated once when the trigger is defined. They are not re-evaluated each time the trigger executes.

To see how you write a persistent trigger and what its effects are, change the ChooseProc procedure and add the new procedure PersistProc, as follows:

PROCEDURE ChooseProc.
  ON CHOOSE OF bButton IN FRAME fFrame
    PERSISTENT RUN PersistProc.
END PROCEDURE.

PROCEDURE PersistProc:
  iCount = iCount + 1.
  bButton:LABEL IN FRAME fFrame = "Internal " + STRING(iCount).
END PROCEDURE.

Now when you run the procedure and click the button you get a very different result. The next figure shows the results of the first three button presses.

Figure 1. Results of running the PersistProc procedure

Once you have established the persistent trigger, it remains in effect as long as the object it is associated with exists, just as a definitional trigger would.