Screen Refresh Control¶
- Screen Refresh Control
DISABLE-REDRAW¶
FWD introduces new WINDOW widget writable attribute DISABLE-REDRAW, its type is LOGICAL. The attribute can be used to temporarily disable redraw of a particular window. Note that only the "application" area of the window is affected, that is the area where FRAME and other widgets are placed. Window decorations (window title bar and borders), the message and status areas are not affected.
The usage:
CREATE WINDOW h.
h:DISABLE-REDRAW = TRUE.
/* window redraw is disabled */
/* any changes to the window content or child widgets won't be reflected in the window until DISABLE-REDRAW is set to FALSE again */
h:DISABLE-REDRAW = FALSE.
/* window redraw is enabled */
The motivation for the extension are two patterns commonly used to speed up window visual updates. First based on the WIN32 functions LockWindowUpdate (see example 1 below) and second based on the WM_SETREDRAW WIN32 window message (see example 2 below).
Caveats¶
Adding a PROCESS EVENTS before entering the DISABLE-REDRAW phase¶
When setting h:DISABLE-REDRAW = TRUE., the window will stop repainting.
In cases where there is no WAIT-FOR or similar, but you need to show a frame during the DISABLE-REDRAW phase, you must insert a PROCESS EVENTS. to your source code immediately BEFORE setting h:DISABLE-REDRAW = TRUE..
Why you need to code this yourself¶
The extra process events that you need to code yourself is by design.
That way, the 4GL programmer can detect and work around possible side effects of the process events (like PSTimer event handlers and widget UI event handlers firing).
If FWD would do a process events under the hood automatically, it would steal the program flow control that your application must have at all times, since it is the responsibility of the business logic to handle this correctly.
Dealing with existing PROCESS EVENTS statements during the DISABLE-REDRAW phase¶
Existing ABL code may have process events statements. If that statement fires during the DISABLE-REDRAW phase, this can cause unwanted side effects, like screen pollution or a blank screen.
In Windows, you will not see screen pollution, if you use Windows techniques like Windows API WM_SETREDRAW set to 0. Running in Windows, this happens outside of the OE runtime's control and knowledge.
In FWD, you can sometimes see screen pollution by a process events, because all events (also the 'paint' instructions) are passed via the same Server/Client FWD event queue.
To solve it, you need to skip your process events during the DISABLE-REDRAW phase programmatically.
It is needed to check if the process events being skipped is not actually needed for your OE events. You might use the OE log-manager for your inspection (turn it on before your process events statement, and turn it off right after).
If you find that crucial logic is being missed by not executing process events, you must trigger the logic in a different way (not using the OE event queue).
In FWD, a useful debugging technique is:
Add a temporary log line to the processEvents java method, and check your logfile for log entries during your DISABLE-REDRAW phase.
Example:
Add com.goldencode.p2j.util.logging.CentralLogger.get("CHECK_ME").severe("Hello"); to ThinClient.java:processEvents() , compile, and store the .class file at the existing location in p2j.jar.
If needed, start a debugging session and investigate from there.
Example 1a¶
PROCEDURE LockWindowUpdate EXTERNAL 'user32.dll':
/* pass current-window:hwnd to suspend, set to 0 (zero) to enable again */
DEFINE INPUT PARAMETER intWindowHwnd AS LONG NO-UNDO.
DEFINE RETURN PARAMETER intResult AS LONG NO-UNDO.
END PROCEDURE.
RUN LockWindowUpdate (ACTIVE-WINDOW:HWND,OUTPUT i).
ASSIGN
FRAME f:WIDTH-PIXELS = 100.
FRAME f:HEIGHT-PIXELS = 100.
RUN LockWindowUpdate (0,OUTPUT i).
Example 1b (the above example re-written with the DISABLE-REDRAW extension)¶
ACTIVE-WINDOW:DISABLE-REDRAW = true.
ASSIGN
FRAME f:WIDTH-PIXELS = 100.
FRAME f:HEIGHT-PIXELS = 100.
ACTIVE-WINDOW:DISABLE-REDRAW = false.
Example 2a¶
procedure SendMessageA external "user32.dll":
define input parameter hwnd as long no-undo.
define input parameter wmsg as long no-undo.
define input parameter wparam as long no-undo.
define input parameter lparam as long no-undo.
define return parameter rc as long no-undo.
end procedure.
procedure RedrawWindow external "user32.dll":
def input parameter v-hwnd as long no-undo.
def input parameter v-rect as long no-undo.
def input parameter v-rgn as long no-undo.
def input parameter v-flags as long no-undo.
def return parameter v-ret as long no-undo.
end procedure.
PROCEDURE lockWindow :
define input parameter phWindow as handle no-undo.
define input parameter plLock as logical no-undo.
define variable iRet as integer no-undo.
&GLOBAL-DEFINE WM_SETREDRAW 11
&GLOBAL-DEFINE RDW_ALLCHILDREN 128
&GLOBAL-DEFINE RDW_ERASE 4
&GLOBAL-DEFINE RDW_INVALIDATE 1
if plLock then
do:
run SendMessageA( phWindow:hwnd
, {&WM_SETREDRAW}
, 0
, 0
, output iRet).
end.
else
do:
run SendMessageA( phWindow:hwnd
, {&WM_SETREDRAW}
, 1
, 0
, output iRet).
run RedrawWindow( phWindow:hwnd
, 0
, 0
, {&RDW_ALLCHILDREN} + {&RDW_ERASE} + {&RDW_INVALIDATE}
, output iRet).
end.
END PROCEDURE.
def var hpcbx as handle.
create combo-box hpcbx assign
frame = FRAME f0:handle
INNER-LINES = 14
sensitive = true
visible = true
row = 3
column = 24.
run LockWindow (input active-window:handle, true).
hpcbx:INSERT('A', 'a', '1').
hpcbx:INSERT('B', 'b', '2').
hpcbx:INSERT('C', 'c', '3').
hpcbx:INSERT('B', 'b', '2').
run LockWindow (input active-window:handle, false).
Example 2b (the above example re-written with the DISABLE-REDRAW extension)¶
def var hpcbx as handle.
create combo-box hpcbx assign
frame = FRAME f0:handle
INNER-LINES = 14
sensitive = true
visible = true
row = 3
column = 24.
ACTIVE-WINDOW:DISABLE-REDRAW = true.
hpcbx:INSERT('A', 'a', '1').
hpcbx:INSERT('B', 'b', '2').
hpcbx:INSERT('C', 'c', '3').
hpcbx:INSERT('B', 'b', '2').
ACTIVE-WINDOW:DISABLE-REDRAW = false.
FWD will not automatically convert the example 1a into 1b. Likewise FWD will not convert 2a into 2b. These WIN32 idioms are not automatically translated into the use of DISABLE-REDRAW. Any such changes must be manually written for now.
FWD does provide automated conversion of the 4GL cases 1b and 2b into Java. Any usage of the DISABLE-REDRAW attribute (on a WINDOW widget) will be automatically converted to the use of the method isDisableRedraw() (for reading the attribute) and setDisableRedraw(logical) or setDisableRedraw(boolean) for writing the attribute.
Implementation¶
The server-side implementation can be found in com.goldencode.p2j.ui.WindowWidget.
© 2004-2024 Golden Code Development Corporation. ALL RIGHTS RESERVED.