#21 Windows Ghosting in XP, Vista and 7
Posted: Wed Aug 08, 2012 10:32 am
Windows Ghosting in XP, Vista and 7
Ghosting is a feature of Microsoft Operating Systems that occurs when an application becomes unresponsive. Its displayed window is overlaid with a light-grey ‘ghost’ pane to let the user know the application is unresponsive. Once the application recovers, regains focus and functionality the ‘ghost’ pane disappears.
Until now, a non-responsive JADE window would ‘ghost’ and not repaint as the result of any window events.
An update in JADE 6.3.11 and 7.0.05 will now automatically disable this ghosting feature for all JADE processes. As a result, a non-responsive form will no longer show 'Not Responding' and will not have the ghosting effect applied by Windows.
Combating Ghosting in 6.3.11/7.0.05
JADE 6.3.11 and 7.0.05 have two new methods that can be called while performing a long processing loop to address the repainting issue:
1) Application::paintIfRequired()
This causes all forms of the application to be repainted if a paint is required.
A refreshNow() event is performed on that part of the form that needed refreshing.
If paints are not required, the result is no action.
This method will perform any repainting required without having to perform an app.doWindowEvents() and therefore does not allow the user interface to be active.
Other than any paint events, no other events, notifications or timer events will be processed as a result of this call.
2) Form::paintIfRequired()
This performs exactly the same action as the Application version of this method except only the form on which the call is made will be affected.
Note: That after a repaint, any clicked button that initiated a processing loop will be drawn in the up position. So it will be important that the application user is given a visual indication that the processing is still progressing by some other means, for example via app.mousePointer := 11 (busy).
It will be necessary to add a call to one of these methods inside the logic loop; for example, call it when the Cancel button is checked for a click event, when a progress bar update ticks over a percentage, or at a specified number of seconds, as shown in the following code fragment.
Combating Ghosting Prior to 6.3.11/7.0.05
To implement this functionality in versions of JADE prior to 6.3.11 and 7.0.05 define the following external function to directly call the Microsoft API - DisableProcessWindowsGhosting().
disableGhosting() is DisableProcessWindowsGhosting in user32 presentationClientExecution;
Then disableGhosting() can be called from the initialization method of the application for which ghosting is to be disabled.
Forms will still not automatically paint themselves when the presentation thread is busy processing JADE logic. This will only be an issue if the user covers the form with another window and then uncovers it again on Windows XP or Vista. In Windows 7, the OS automatically redraws any part of the window that needs refreshing from a saved copy of the previously painted image.
To address this perform a self.refreshNow() regularly during the processing loop. Note though, this is less efficient than paintIfRequired() as the form may not need painting.
Ghosting is a feature of Microsoft Operating Systems that occurs when an application becomes unresponsive. Its displayed window is overlaid with a light-grey ‘ghost’ pane to let the user know the application is unresponsive. Once the application recovers, regains focus and functionality the ‘ghost’ pane disappears.
Until now, a non-responsive JADE window would ‘ghost’ and not repaint as the result of any window events.
An update in JADE 6.3.11 and 7.0.05 will now automatically disable this ghosting feature for all JADE processes. As a result, a non-responsive form will no longer show 'Not Responding' and will not have the ghosting effect applied by Windows.
Combating Ghosting in 6.3.11/7.0.05
JADE 6.3.11 and 7.0.05 have two new methods that can be called while performing a long processing loop to address the repainting issue:
1) Application::paintIfRequired()
This causes all forms of the application to be repainted if a paint is required.
A refreshNow() event is performed on that part of the form that needed refreshing.
If paints are not required, the result is no action.
This method will perform any repainting required without having to perform an app.doWindowEvents() and therefore does not allow the user interface to be active.
Other than any paint events, no other events, notifications or timer events will be processed as a result of this call.
2) Form::paintIfRequired()
This performs exactly the same action as the Application version of this method except only the form on which the call is made will be affected.
Note: That after a repaint, any clicked button that initiated a processing loop will be drawn in the up position. So it will be important that the application user is given a visual indication that the processing is still progressing by some other means, for example via app.mousePointer := 11 (busy).
It will be necessary to add a call to one of these methods inside the logic loop; for example, call it when the Cancel button is checked for a click event, when a progress bar update ticks over a percentage, or at a specified number of seconds, as shown in the following code fragment.
Code: Select all
cancelled := false;
while not cancelled do
.... logic
btnCancel.doWindowEvents(0); // the click event sets the cancelled property
app.paintIfRequired(); // or self.refreshNow() pre 6.3.11 / 7.0.05
endwhile;
To implement this functionality in versions of JADE prior to 6.3.11 and 7.0.05 define the following external function to directly call the Microsoft API - DisableProcessWindowsGhosting().
disableGhosting() is DisableProcessWindowsGhosting in user32 presentationClientExecution;
Then disableGhosting() can be called from the initialization method of the application for which ghosting is to be disabled.
Forms will still not automatically paint themselves when the presentation thread is busy processing JADE logic. This will only be an issue if the user covers the form with another window and then uncovers it again on Windows XP or Vista. In Windows 7, the OS automatically redraws any part of the window that needs refreshing from a saved copy of the previously painted image.
To address this perform a self.refreshNow() regularly during the processing loop. Note though, this is less efficient than paintIfRequired() as the form may not need painting.