The following is an article sent by Dinesh Omkar to me sometime back: --- Dinesh Omkar To: Subject: Events and Precedence in PowerBuilder Event Driven Programming ------------------------ Events and Precedence The order in which events happen within a PowerBuilder application is, in most cases, very predictable and should be made clear to the application developer. For instance, when focus is shifted from one object to another object, the first object will experience the Modified and LoseFocus events before the second object experiences a GetFocus event. To understand this further, consider the following scenarios and the resulting events. An Application starts and window "A" is opened APPLICATION OPEN WINDOW "A" OPEN WINDOW "A" ACTIVATE CHILD OBJECT GET FOCUS (First object in tab order) Window "B" is opened (Window "A" stays open) WINDOW "A" CURRENT OBJECT LOSE FOCUS WINDOW "A" DEACTIVATE WINDOW "B" OPEN WINDOW "B" ACTIVATE WINDOW "B" CHILD OBJECT GET FOCUS (First object in tab order) Window "B" closed, return to Window "A". WINDOW "B" CLOSEQUERY WINDOW "B" CURRENT OBJECT LOSE FOCUS WINDOW "B" CLOSE WINDOW "B" DEACTIVATE WINDOW "A" ACTIVATE OBJECT GET FOCUS (Last object that had focus) "Click" on new object within Same Window OBJECT 1 MODIFIED (if changed) OBJECT 1 LOSE FOCUS OBJECT 2 GET FOCUS OBJECT 2 CLICKED "Tab" to new object within Same Window OBJECT 1 MODIFIED (if changed) OBJECT 1 LOSE FOCUS OBJECT 2 GET FOCUS (next object in tab order) Interestingly enough, events can and will occur even when no actions are performed by the user! If you are using a screen saver, such as the one in Windows, the following will happen. Flip to screen saver (After period of inactivity) WINDOW DEACTIVATE OBJECT LOSE FOCUS Return from screen saver WINDOW ACTIVATE OBJECT GET FOCUS DataWindows and Events ---------------------- A DataWindow is a single object within a window. As such, events happen to the DataWindow as a single object and not to the individual items that are within the DataWindow. In order to make up for this, there are a number of special events that exist only for DataWindows. These events are not quite the same as those of other Window objects and therefore must be considered on their own. Consider the following scenario: The User Clicks on a field in a data window, keys something, clicks on another field within the data window, keys something and then clicks on a Command Button (outside of the DataWindow). The sequence of DataWindow events is as follows: DW GET FOCUS DW CLICKED DW EDIT CHANGED (once for each keystroke) DW CLICKED DW ITEMCHANGED DW ITEM FOCUS CHANGED DW EDIT CHANGED (once for each keystroke) DW LOSE FOCUS COMMAND BUTTON GET FOCUS COMMAND BUTTON CLICKED A number of significant points must be made. There was only one get focus and one lose focus event. Only one item changed event occurred (even though two items were changed). A clicked event occurred two times. One edit changed event occurred for every keystroke made within the DataWindow. If DataWindow edits were behind the two modified fields, only the first field would have been edited. For all intents and purposes, the second field has nothing in it! Now let us insert the ACCEPTTEXT() function into the command button Clicked script. Now the sequence of events is as follows: DW GET FOCUS DW CLICKED DW EDIT CHANGED (once for each keystroke) DW CLICKED DW ITEMCHANGED DW ITEM FOCUS CHANGED DW EDIT CHANGED (once for each keystroke) DW LOSE FOCUS COMMAND BUTTON GET FOCUS COMMAND BUTTON CLICKED DW ITEMCHANGED The last item changed event was triggered by the AcceptText() function! (It might be tempting to put this function in the DataWindow lose focus script, but this makes it very difficult for a user to cancel a transaction when they can not get past the edit!) Events Precedence Table ----------------------- The following is a table that shows the order of events for each object type: Objects Events Order Notes ----------------------------------------------------------- Window Open 1 Activate 2 Also after closing of another Window Key 3 Each Keystroke (not all objects) CloseQuery 4 Close 5 Deactivate 6 Single Line Edit, Multi Line Edit Get Focus 1 Modified 2 LoseFocus 3 List Box, Drop Down List Box GetFocus 1 SelectionChanged 2 When choice made from list Modified 3 DoubleClicked 4 Only possible when "always show list box" is active LoseFocus 5 Static Text, Picture, Picture Button GetFocus 1 Clicked 2 DoubleClicked 3 Always issues a Clicked event first LoseFocus 4 Check Box, Command Button, Radio Button GetFocus 1 Clicked 2 LoseFocus 3 DataWindow GetFocus 1 Clicked 2 DoubleClicked 3 Always issues a Clicked event first EditChanged 4 Once for each keystroke ItemError 5 When item doesn't pass validation ItemChanged 6 When object loses focus within dw RowFocusChanged 7 ItemFocusChanged 8 LoseFocus 9 Events Notes ------------ Triggerevent Function At any time in an application, an event can occur through use of the TRIGGEREVENT() function. This can be a very handy thing to know and use. It can also cause problems if the application is counting on certain events to occur in a certain sequence. DataWindow Clicked Event ------------------------- Often, the clicked event in a data window is used to trigger a choice made by the user. In the script for this event it is always a good policy to check that the clicked row value is greater than zero. If the click is made on the borders or white space of a data window, the GETCLICKEDROW function will return a zero. Although the ItemError! event listed after EditChanged! event under dw events order is a bit confusing, I am sure it is correct as per the 4 phases of validation: . data-change check (Has the data "changed" - at all? Suppose the value was 123 and the user changed it to 12, then changed it to 23 and then changed it BACK to 123 "before" leaving the field, the value was NOT changed at all) . data-type check (Check for the correct data-type & length; ItemError! fires here...) . item-changed check (Data has changed - execute the code in the ItemChanged! event) . validation-rule check (Execute any developer-coded validation-script) Regards, --- PowerObject!