Kbase P150232: LEAVE event is not generated in ABL window when moving focus from ABL window to .NET form in same se
Autor |
  Progress Software Corporation - Progress |
Acesso |
  Público |
Publicação |
  4/6/2010 |
|
Status: Verified
SYMPTOM(s):
LEAVE event is not generated in ABL window when moving focus from ABL window to .NET form in same session
LEAVE triggers in ABL window do not fire when user shifts focus to .NET form in the same application.
FACT(s) (Environment):
Application uses both .NET forms and ABL windows.
ABL window is initiated with a RUN command from the .NET form.
ABL window is not embedded in the .NET form.
LEAVE events are generated when focus is moved between ABL windows.
Windows
OpenEdge 10.2A
CAUSE:
Bug# OE00189260
CAUSE:
Bug# OE00194659
CAUSE:
The LEAVE event of an ABL window is only generated when another ABL window is given focus. Moving focus to a .NET form is treated as though the form were part of another Windows application, rather than part of the ABL application. The ABL window remains as it was, waiting for the user to return to itself or another window it recognizes as part of the ABL application.
FIX:
To work around this problem, the application must keep track of which forms or windows have had focus. If the starting point of the application is a .NET form, a convenient place to do so is in the PRIVATE-DATA attribute of the form class. The handle for this class is stored in the LAST-CHILD attribute of the SESSION system handle, so it is accessible to both the .NET form and the ABL windows. A chain of handles to the forms and window that have had focus is maintained, and LEAVE events are applied by the application when focus is shifted from an ABL window to the .NET form. This workaround can be implemented as follows (code snippets are examples only; the example assumes that the .NET form runs only one ABL window procedure, zero or more times):
Store a string representation of the .NET form class handle in the class handle's PRIVATE-DATA:
cFirst = STRING(SESSION:LAST-CHILD).
SESSION:LAST-CHILD:PRIVATE-DATA = cFirst.
This will be the start of a comma-separated list of items that have had focus (called here the "focus chain").
Add an ENTRY trigger to the ABL window that adds a character representation of the window procedure handle (NOT the window object handle) to the focus chain:
SESSION:LAST-CHILD:PRIVATE-DATA = STRING(THIS-PROCEDURE) + ',' + SESSION:LAST-CHILD:PRIVATE-DATA.
Add an internal procedure to the ABL window procedure that applies a LEAVE event to the window.
Subscribe the .NET form to its Activated event (equivalent to an ABL widget's ENTRY event).
In the event handler for the Activated event, check the focus chain for the handle of the last form or window to have focus. If it was not the form itself, run the internal procedure to apply the LEAVE event to the window, and add the form class handle to the focus chain:
cLast = ENTRY(1, SESSION:LAST-CHILD:PRIVATE-DATA).
hLast = HANDLE(cLast).
IF VALID-HANDLE(hLast) THEN
IF hLast <> SESSION:LAST-CHILD THEN
DO:
RUN applyLeave IN hLast.
SESSION:LAST-CHILD:PRIVATE-DATA = cFirst + ',' + SESSION:LAST-CHILD:PRIVATE-DATA.
END.
Add a LEAVE trigger to the ABL window procedure that performs the desired action.
Add to the WINDOW-CLOSE trigger of the ABL window procedure code that removes the procedure handle from the focus chain:
cFocusChain = SESSION:LAST-CHILD:PRIVATE-DATA.
iNumEntries = NUM-ENTRIES(cFocusChain).
cThisHandle = STRING(THIS-PROCEDURE:HANDLE).
DO i = 1 TO iNumEntries:
cChainHandle = ENTRY(i, cFocusChain).
IF (cChainHandle <> cThisHandle) THEN
DO:
IF (cNewChain <> '') THEN
cNewChain = cNewChain + ','.
cNewChain = cNewChain + cChainHandle.
END.
END.
SESSION:LAST-CHILD:PRIVATE-DATA = cNewChain.
FIX:
Upgrade to OpenEdge release 10.2B01 or later