There are two methods for setting the input focus in OpenInsight, and there is a subtle implementation difference that can impact your applications if you’re not careful how you apply them.
The first method is to use an object’s own FOCUS property and set it to TRUE$ like so:
Call Set_Property_Only( @Window : ".EDL_SURNAME", "FOCUS", TRUE$ )
This moves the focus to the specified object, but the event queue will be flushed both before and after the focus has been set, thereby preventing any events raised as a result of the focus being moved from being processed. This method was originally designed for use with validation routines so the focus could be reset to an invalid control “safely”.
The second method is to use the SYSTEM object’s FOCUS property:
Call Set_Property_Only( "SYSTEM", "FOCUS", @Window : ".EDL_SURNAME" )
This moves the focus, but any events triggered as a result of moving the focus (like LOSTFOCUS and GOTFOCUS events) will be processed.
That all sounds straightforward enough, but using the first method can lead to unexpected results if you are relying on an event already in the queue that you subsequently need – not a common situation but one we encountered recently while converting an old form to v10. In our case we had a menu failing to show when the focus was on a specific control, and it turned out that the LOSTFOCUS event for the control was setting it’s FOCUS property to TRUE$. This had the effect of killing a pending MENUDROPDOWN event (new in v10) that created the menu to display, hence no menu.
In this case the solution is to use the SYSTEM BLOCKEVENTS property to turn off events being triggered while the focus is moved and then restore event processing afterwards:
Call Set_Property_Only( "SYSTEM", "BLOCKEVENTS", TRUE$ ) Call Set_Property_Only( "SYSTEM", "FOCUS", @Window : ".EDL_SURNAME" ) Call Set_Property_Only( "SYSTEM", "BLOCKEVENTS", FALSE$ )
This prevented any LOSTFOCUS and GOTFOCUS events from being raised, but the MENUDROPDOWN event was still in the queue.
Using the SYSTEM FOCUS and BLOCKEVENTS properties in this way is a far “safer” alternative when moving the focus because you have full control over how events are handled, and I would always advocate using this method over using a control’s own FOCUS property.
Good advice for OI v9 applications as well!
Great information … thanks