TRIGGER and POST are two PowerBuilder keywords commonly used to control the sequence of execution within an application. In both cases, the script for the event or function associated with the keyword is executed at the developer's request; however, the actual Windows message corresponding to that event is not sent. (The TriggerEvent() and PostEvent() functions serve the same purposes as the analogous keywords; however, they are limited in that they do not allow you to directly pass arguments to the event.) To send or post an actual Windows message and have the corresponding event executed, use the Send() or Post() functions instead.
Please note that posting method calls among PowerBuilder components and clients to achieve asynchronous behavior in the EAServer (Jaguar) environment is not supported. Facilities such as the MessageService and ThreadManager interfaces in EAServer can be used to implement such functionality.
PowerBuilder, Windows and Messages
Windows is a messaging-based system which queues events, taking messages off the front of the queue for processing and adding them to the back of the queue for future processing when new events occur. As of PowerBuilder 6.0, PowerBuilder maintains its own event queue in addition to placing items on the Windows event queue; however, PowerBuilder always processes events in its own queue first.
There are standard Windows messages which have predefined functionality like WM_CLOSE, and custom Windows messages like WM_USER which have no intrinsic meaning but can be programmed to be meaningful. If WM_CLOSE is sent to a window, it will set off a chain of events which will close the window. If WM_USER is sent to a window, what will happen depends on how the programmer defined the message in his or her code. PowerBuilder developers use a similiar concept when creating custom user events and mapping them to PBM_..functions like PBM_CLOSE and PBM_CUSTOM01. PBM_CLOSE maps to Windows' WM_CLOSE and PBM_CUSTOM01 maps to Windows' WM_USER.
In addition to putting messages at the back of the message queue, events can be forced to happen immediately, jumping to the front of the queue. Both methods of controlling execution are explored below.
TRIGGER, POST, TriggerEvent( ) and PostEvent( )
When TRIGGER, POST, TriggerEvent() or PostEvent() are used, the script tied to the event is executed as if it were a function call; however, the corresponding event may not actually fire immediately. The difference between the two lies in timing. POST/PostEvent( ) puts a message at the back of the queue where it awaits its turn for execution. TRIGGER/TriggerEvent( ), on the other hand, programmatically causes code to be executed before the next message is processed. The default behavior for event processing is TRIGGER.
There are important reasons to use one or the other. To cancel a print job, for example, triggering (versus posting) the cancellation will cause the print job to terminate immediately, before the printing is finished, thus cancelling the job. If you tried to post the cancellation, the print job would complete before the posted request was processed and be essentially a meaningless operation.
To display a logon window from the open script of a window, POST/PostEvent( ) would wait until the initial window opened before starting to open the logon window, while TRIGGER/TriggerEvent( ) would start to open the logon window, possibly before the initial window was fully opened.
As another example, if a menu item calls TriggerEvent(w_win, close!), the script of the close event of that window will be executed immediately, but the window will NOT close. While the script will execute, the Windows message that normally causes that script to execute has not been sent. If, however, the menu item calls TriggerEvent(w_win.cb_exit, clicked!) and the clicked script for the button includes the Close(parent) function call, the script executes AND the window closes.
In the example above, the clicked script on the menu would execute to completion. Any further commands in the menu's clicked script would potentially refer to objects on the window which has just closed. This would result in a null object reference error! If there is no script beyond the TriggerEvent() call, or if the menu script never refers to an object on w_win, no error will occur, but the potential for future errors would remain.
To understand why the window was not closed when its closed event was triggered, we must examine the relationship between Windows messages and PowerBuilder. When the user clicks the exit button, a BN_CLICKED message is sent. The Windows message BN_CLICKED is mapped to the PowerBuilder message PBM_BNCLICKED. That message causes the clicked event to happen, and the clicked script is part of that event. When TriggerEvent(cb_exit, clicked!) is called, the clicked script is executed, but no BN_CLICKED or PBM_CLICKED message is sent. Likewise, the Windows message WM_CLOSE is mapped to PBM_CLOSE. The close event has a script that can be accessed when a WM_CLOSE message is sent to the window or when TriggerEvent(w_win, close!) occurs or PostEvent(w_win, close!) puts the PowerBuilder message on the queue. When either of these latter two methods is invoked, the close script is executed, but the WM_CLOSE message is not sent.
Post( ) and Send( )
To actually send a Windows message and make an action take place, PowerBuilder has two other functions: Post( ), which puts the Windows message at the end of the Windows message queue, and Send( ), which puts the message at the front of the Windows queue.
These PowerBuilder function calls require the following parameters:
To actually send a Windows message and, for instance, have the window close and not just trigger the close script, Send( ) or Post( ) must be used. Windows.h, the Windows header file lists message names and their accompanying numbers. For instance:
#define WM_CLOSE 0x0010
is the entry for the close message. Hex 0x0010 equals decimal 16 so the following code would close the window:
The last two parameters to Post() are set to zero since they are not used in this context.
Posting this message puts the real message at the end of the Windows message queue. When it is processed, the close script would be executed AND the window will be closed. It is usually not necessary to use Post() or Send() since there are PowerBuilder functions which send the message behind the scenes. Close(parent) is much easier than Post(hdl,16,0,0), for example.
Note: Windows.h is available through the Microsoft Windows SDK and other Windows development environments such as Visual C/C++. Additionally, Sybase Technical Support does not support Windows SDK development issues.