Release 10.1A: OpenEdge Development:
Progress 4GL Handbook

> ## Applying events in your application

> You have already seen cases where a procedure causes an event to fire “artificially” by using the `APPLY` statement. In the `CustOrders` procedure, each button trigger has to `APPLY` the `VALUE-CHANGED` event to the Order browse to get it to run the internal procedure to display related data for the Order, such as this code for the Next button trigger:

>     DO:
>       GET NEXT CustQuery.
>       IF AVAILABLE Customer THEN
>       DO:
>         DISPLAY {&FIELDS-IN-QUERY-CustQuery}
>             WITH FRAME CustQuery IN WINDOW CustWin.
>         {&OPEN-BROWSERS-IN-QUERY-CustQuery}
>         APPLY "VALUE-CHANGED" TO OrderBrowse.
>       END.
>     END.

> The `APPLY` statement causes whatever trigger is currently active for the event and object to fire. Unlike the `ON` statement, you must place the name of the event in quotation marks in an `APPLY` statement, if it is a literal value. This makes it possible to `APPLY` the value of a character variable instead. In this way, you can define a `CHARACTER` variable, assign it a value of an event name during program execution, and then use that value in an `APPLY` statement, adding flexibility to your programming. For example:

>     DEFINE VARIABLE cEvent AS CHARACTER NO-UNDO.
>          .
>          .
>          .
>     cEvent = “VALUE-CHANGED”.
>          .
>          .
>          .
>     APPLY cEvent TO <some object>.

> By contrast, Progress must know the event for an `ON` statement at compile time to prepare the trigger properly. For this reason the event name can’t be a variable, so you can specify it with or without quotation marks in the `ON` statement.

> As another example, here’s a little procedure that transfers keystrokes from one fill-in field to another:

>     DEFINE VARIABLE cFillFrom AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE cFillTo   AS CHARACTER  NO-UNDO.
>     ENABLE cFillFrom cFillto WITH FRAME fFrame.
>     ON ANY-PRINTABLE OF cFillFrom
>          APPLY LAST-KEY TO cFillto.
>     WAIT-FOR CLOSE OF THIS-PROCEDURE.

> The `LAST-KEY` keyword is a built-in function that returns the value of the last keystroke the user pressed. Every time you enter a letter into the first fill-in field, `cFillFrom`, the `ANY-PRINTABLE` trigger fires which, as its name suggests, responds to any printable character typed on the keyboard, and this trigger retrieves that keystroke and applies it to the other fill-in field, `cFillTo`. So you can apply not just the standard events but even keyboard characters to an object like a fill-in field, if is enabled for input. Figure 8–12 shows the effect of typing Text into `cFillFrom`.

> Figure 8–12: Result of typing into cFillFrom

> ##### Using NO-APPLY to suppress default processing for an event

> When you type a letter such as A in a field, it naturally appears in the field on the screen. This is called the default processing for the event. If there were a trigger `ON “A” OF cFillTo`, then you could `APPLY` that event to the fill-in field, the trigger would fire, and the letter would appear. This is the normal result of applying an event: both the default processing and any trigger on the event occur. However, some event-object pairs do not get Progress default processing using the `APPLY` statement. For example, applying the `CHOOSE` event programmatically to a button executes the trigger on that button but does not give focus to the button in the way that clicking it would.

> As another twist to this relationship between events and their actions, consider the action on the object that initiates the event, not the one that receives it and does its default processing for the event. Sometimes you want only the trigger action on the target object to occur and not the default processing for the object that initiated the event. In this case, you can use the special `RETURN NO-APPLY` statement at the end of the trigger definition to suppress the default processing on the object that initiated it.

> | To suppress the default processing for an event in your test procedure:

> 1. Add the `RETURN NO-APPLY` statement (along with the `DO-END` statements to turn the trigger into a block of code):

>     DEFINE VARIABLE cFillFrom AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE cFillTo   AS CHARACTER  NO-UNDO.
>     ENABLE cFillFrom cFillto WITH FRAME fFrame.
>     ON ANY-PRINTABLE OF cFillFrom
>     DO:
>         APPLY LAST-KEY TO cFillto.
>         RETURN NO-APPLY.
>     END.
>     WAIT-FOR CLOSE OF THIS-PROCEDURE.

> 2. Run the procedure and type some text into cFillFrom:

> When you type, the keystrokes are applied to cFillTo, that is its default processing. But the `RETURN NO-APPLY` statement suppresses the default processing the cFillFrom, so it remains blank.

> 3. Add this statement to the trigger:

>     ON ANY-PRINTABLE OF cFillFrom
>     DO:
>         APPLY LAST-KEY TO cFillto.
>         APPLY '*' TO cFillFrom.
>         RETURN NO-APPLY.
>     END.

> 4. Run the procedure.You get asterisks in cFillFrom for each keystroke you type:

> The trigger first applies the keystroke to the second fill-in, which causes the character to be displayed. It then applies the literal ‘*’ to the first fill-in, causing it to be displayed there. Finally, it does a `RETURN NO-APPLY` to suppress the display of the character you actually typed into the first fill-in. You could use this sort of code for a password field, for example.

> ##### Applying a nonstandard event

> With the `APPLY` statement, you can actually send any event to any object that has a trigger for that event. Progress executes the trigger even if there is no default handling for the event associated with that object type. Thus, you can use this feature to extend the repertoire of developer events (predefined events with the names U1 through U10) to include any event not normally associated with an object. For example, you could apply `CHOOSE` to a fill-in field, which does not normally support that event.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095