About/Contact

Steve Trefethen

Steve Trefethen is a Director of Engineering at Reply. Contact me

View my LinkedIn profile


Powered by discountASP.NET
referal ID: sdtref
Why recommend discountASP.NET?
$720 in referrals so far!


Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar

Disclaimer

The posts on this weblog are provided AS IS with no warranties, and confer no rights. The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.



Quick Tip #2: Fixing flicker caused by WM_ERASEBKGND in a Delphi VCL app

February 01 2007 5:10PM

In Delphi's VCL framework there is a property on TWinControl called DoubleBuffered which can help reduce or eliminate window flicker. To see a simple example of it's effectiveness try the following:

  1. Create a new VCL application
  2. Drop a TMemo control
  3. Set Align on Memo1 to alClient
  4. Using the Lines property add some text to the memo
  5. Run the application and resize the form

Notice how the text in the control flickers. Now add an OnCreate event to Form1 and put the following code:

Memo1.DoubleBuffered := True;

Run the application again and resize the form. Notice that the flicker is gone. In a future release we'll publish the DoubleBuffered property to allow you to set it directly from the Object Inspector but until then writing a little code is necessary.

You might be wondering why isn't DoubleBuffered set to true by default? The reason is performance though the average PC's processing power has significantly increased since we added this feature to the VCL. A machine that's capable of running Windows Vista with the Areo Glass UI will easily be able to handle DoubleBuffering.

Finally, let's to the reason I wrote this post which is handling WM_ERASEBKGND. If you've written your own components that handle their own painting you should consider the affect of DoubleBuffering in your message handling code. An example is in the default implementation of TWinControl's WMERASEBKGND method which contains the following:

{ Only erase background if we're not doublebuffering or painting to memory. } if not FDoubleBuffered or (TMessage(Message).wParam = TMessage(Message).lParam) then FillRect(Message.DC, ClientRect, FBrush.Handle);

Consider doing something similar in your code to support DoubleBuffering. I have been working on reducing flicker within the Delphi IDE itself and there were a few WM_ERASEBKGND handlers which were not written with DoubleBuffering in mind (but that's fixed now). We're not quite down to a flick-free IDE but it's getting very close.

[UPDATE Feb 1]: Fix the property name in the first sentence, it's "DoubleBuffered" not "DoubleBuffering"
[UPDATE May, 2008] Related posts:

Quick Tip: FullRepaint and fixing flicker in a Delphi VCL app
Using the WS_EX_COMPOSITE window style to eliminate flicker on Windows XP

FacebookDel.icio.usDigg It!

Tags: ,

Comments (12) -

2/1/2007 6:17:53 PM #

Thanks for the tip.  I've created this little procedure to set some of these preferences.  Simply call ReplicatePreferences from the OnCreate event of a form and set the initial parameter to form e.g. ReplicatePreferences(MainForm).  Maybe someone else will find it useful. Steve

procedure TMainForm.ReplicatePreferences(c: TComponent);
var
  i : integer;
begin
  if (c is TWinControl) then
    TWinControl(c).DoubleBuffered := true;
  if (c is TPanel) then
    TPanel(c).FullRepaint := false;
  if c.ComponentCount > 0 then
  begin
    for i := c.ComponentCount - 1 downto 0 do
      ReplicatePreferences(c.Components[i]);
  end;
end;

Steve Maughan

2/1/2007 6:19:49 PM #

Awesome info.

I do a lot of graphics programming and although I knew about the DoubleBuffered property I wasn't aware of the WM_ERASEBKGND considerations.

Thanks!

Eddie Lotter

2/1/2007 8:09:01 PM #

Nice.

If you set DoubleBuffered on a TRichEdit, it will stop paiting though. Not nice.

Will you also fix the flicker of TPageControls?
The tab pages flicker like crazy when you resize the form.

Lasse Jari Hansen

2/2/2007 8:10:24 AM #

Thanks, Steve!

I guess making DoubleBuffered property published is a good idea.

Michael Skachkov

2/2/2007 9:26:12 AM #

Lasse,

take a look at andy.jgknet.de/.../...er-for-aligned-controls.html

It's not perfect, but it might still be useful for you.

Holger Dors

2/2/2007 11:40:37 AM #

I'm already working on a complete rewrite of the FlickerReduce unit. And at the moment I have only two issues left (TScrollbox containing a TPanel containing a TGroupbox, and TRadioButton). And my technique doesn't use double buffering.

BTW: The PageControl flicker because the TPageControl erases its complete ClientRect, including the Tabsheet with the Brush.Color. Using ExcludeClipRect(ActiveTabSheet.BoundsRect) in the TPageControl.WM_ERASEBKGND handler removes the flicker.

Andreas Hausladen

2/2/2007 12:54:15 PM #

Hi,

You are saying:
"A machine that's capable of running Windows Vista with the Areo Glass UI will easily be able to handle DoubleBuffering."

And let that be the case that double buffering might not be needed:

see blogs.msdn.com/.../549310.aspx
(look for double buffer)

Tjipke van der Plaats

2/2/2007 5:55:08 PM #

Hi Tjipke,
No sooner had I posted that, that I thought the same thing. The Vista window manager is now essentially double buffering anyway though there are still uses for double buffering as we've found working with the Glass UI. Thanks for the link!

Steve Trefethen

2/2/2007 5:56:04 PM #

Hi Andreas,
Thanks for the info about TPageControl! I just started looking at that late yesterday before heading home. I'll have a closer look today.

Steve Trefethen

2/2/2007 5:56:31 PM #

Hi Holger,
Thanks for the link!

Steve Trefethen

2/3/2007 7:29:18 PM #

Andreas,
I've been investigating the issues with the page control and it certainly has many problems when it comes to double buffering. It not only suffers from the problem mentioned in this post TTabSheet has several problems as well including:

- not setting DoubleBuffered when TPageControl.DoubleBuffered is set
- not overriding WM_ERASEBKGND and handling client area painting correctly when DoubleBuffered is true

FWIW, I've fixed these problems in our R&D build but I'd be interested to see what you did as well. I tried your suggestion above but didn't see the desired improvements.

Steve Trefethen

7/23/2008 6:20:26 AM #

I set the double buffered property to True in form create event....but still i get flickering of the controls...........

Can any body suggest , to avoid the flickering........

Note: Mainly the form has scollbox and inside the scrollbox i have dynamically building the controls

Roopa

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading