Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel
By Captain C | Thursday, 24 September 2009 09:15 | 0 Comments
While recently adding a new window into our internal admin system we ran into a subtle problem with the CHANGED event and the NOTIFYPOS property.

NOTIFYPOS is an EditTable property that is always updated to contain the coordinates of the last cell to raise an event, but this is not restricted to the CHANGED event: Any EditTable event that is cell-oriented will also update NOTIFYPOS when triggered, common examples being DBLCLK and POSCHANGED.

In our case the sequence of events ran like so:
  1. The user edited data in a cell and hit the down arrow to move to the cell beneath.

  2. The EditTable registered that the data had changed and set NOTIFYPOS to the edited cell position.

  3. The EditTable raised a CHANGED event.

  4. The EditTable registered that the cell position had changed and set NOTIFYPOS to the position of the 'new' cell.

  5. The EditTable raised a POSCHANGED event.

  6. The Basic+ event handler for the CHANGED event executed - but now NOTIFYPOS was pointing to the 'new' cell, not the edited one - and our code mangled the data!

Now you'd think that step (6) would actually have taken place straight after step (3) but unfortunately that's not the case due to the way that OpenInsight communicates with OpenEngine to run Basic+ event handlers.

Normal Basic+ event handlers are executed in an asynchronous fashion, i.e. they are not executed directly when the notification is received, but are placed into a queue and executed when the queue is processed by the application's "message pump" (For those of you familiar with the Windows API they are dispatched via the PostMessage function).

The solution to the problem was to ensure that our Basic+ event handler ran in a synchronous fashion instead - i.e. it should be executed as soon as OpenInsight is notified by the EditTable that the CHANGED event has taken place. That way we know that NOTIFYPOS will still contain the correct coordinates when our handler runs.

Doing this was simply a matter of qualifying the CHANGED event with the synchronous flag in the window CREATE event handler like so:

0001     * // This is from the CREATE event handler for the window
0002       
0003     * // Set the synchronous flag for the CHANGED event 
0004     * // of the EDT_DETAILS edit table.
0005     
0006     tmp    = TRUE$ ; * // .. to ensure event is registered.
0007     tmp<4> = TRUE$ ; * // Sync flag -> TRUE$  == Synchronous
0008                    ; * //              FALSE$ == Asynchronous
0009     
0010     call send_Message( @window : ".EDT_DETAILS", |
0011                        "QUALIFY_EVENT",          |
0012                        "CHANGED",                |
0013                        tmp )


The new sequence of events now ran like this:
  1. The user edited data in a cell and hit the down arrow to move to the cell beneath.

  2. The EditTable registered that the data had changed and set NOTIFYPOS to the edited cell position.

  3. The EditTable raised a CHANGED event.

  4. The Basic+ event handler for the CHANGED event executed

  5. The EditTable registered that the cell position had changed and set NOTIFYPOS to the position of the 'new' cell.

  6. The EditTable raised a POSCHANGED event.


Labels: , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home

Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel