Project

General

Profile

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.