Board index » delphi » Double buffering help (flickering)

Double buffering help (flickering)

Hi,

I know that double buffering and flickering images is probably the most
commonly asked question about Delphi graphics, but I'm not sure if answers
supplied before will apply to my case...

I am creating a GUI for my app, I want it to be very touchy feely - very
interative and tangible. Due to this, I have TImages (which i am using as
buttons) scrolling in and out of view on my form at variou times, with a
timer to control them, for example, if i want an image to scroll in from off
the top of the form i've got this happeniing on timer1...

if image1.top<30 then image1.top := image1.top+1;

Simple, but it flickers. Most of the images i want to move around aren't
moving over another image - just over the form background. I also have
TImages that update their positions on the 'OnResize' event of the form, so
they stay flush to the right for example, these also flicker when resizing
the form.

How can I use double buffering to stop all this flickering? One thing I
should note is that my Delphi graphics knowledge is *non-existant* so
*please* bear this in mind if you are kind enough to help.

Many thanks in advance for whatever help you can offer.

-Peter

 

Re:Double buffering help (flickering)


TImage components is not exactly suited for animations...
Have a look at the Graphics32 library, http://g32.org,
it has tools and components to help you sort out every
flickering you have and will encounter, while providing
more quality features (transparency, etc...)

Eric Grange
http://glscene.org

Re:Double buffering help (flickering)


Hi Peter,

Try to set

  DoubleBuffered := True;

in the form's OnCreate event.

If that does not help or is too slow, then try to add this:

// in the object interface
    procedure WMEraseBkgnd(var m: TWMEraseBkgnd); message WM_ERASEBKGND;

// in the implementation:
procedure TForm1.WMEraseBkgnd(var m: TWMEraseBkgnd);
begin
  // No automatic erase of background
  m.Result := LRESULT(False);
end;

This will avoid the background to be redrawn.

Regards,
Nils Haeck
www.abc-view.com

Quote
Peter Laurens <pe...@the{*word*192}edge.net> wrote in message

news:3c7c20d2$1_2@dnews...
Quote
> Hi,

> I know that double buffering and flickering images is probably the most
> commonly asked question about Delphi graphics, but I'm not sure if answers
> supplied before will apply to my case...

> I am creating a GUI for my app, I want it to be very touchy feely - very
> interative and tangible. Due to this, I have TImages (which i am using as
> buttons) scrolling in and out of view on my form at variou times, with a
> timer to control them, for example, if i want an image to scroll in from
off
> the top of the form i've got this happeniing on timer1...

> if image1.top<30 then image1.top := image1.top+1;

> Simple, but it flickers. Most of the images i want to move around aren't
> moving over another image - just over the form background. I also have
> TImages that update their positions on the 'OnResize' event of the form,
so
> they stay flush to the right for example, these also flicker when resizing
> the form.

> How can I use double buffering to stop all this flickering? One thing I
> should note is that my Delphi graphics knowledge is *non-existant* so
> *please* bear this in mind if you are kind enough to help.

> Many thanks in advance for whatever help you can offer.

> -Peter

Re:Double buffering help (flickering)


I try to add

doublebuffered:=true;

under oncreate, but Delphi (3) doesn't seem to want to understand it (i have
'graphics' under uses clause so i don't think i need to add anything else up
there, if i do, please let me know). I also tried
Form1.doublebuffered:=true, Image1.doublebuffered:=true, but again, Delphi
flagged them as errors and had no idea what this doublebuffered stuff was
all about.

(I tried the GM32 component set, but it only supports from Delphi 4 onward,
and there's gotta be a way to sort this out in 3)

Many thanks,

-Peter

Quote
"Nils" <n.ha...@quicknet.nl> wrote in message news:3c7c9f42$1_1@dnews...
> Hi Peter,

> Try to set

>   DoubleBuffered := True;

> in the form's OnCreate event.

> If that does not help or is too slow, then try to add this:

> // in the object interface
>     procedure WMEraseBkgnd(var m: TWMEraseBkgnd); message WM_ERASEBKGND;

> // in the implementation:
> procedure TForm1.WMEraseBkgnd(var m: TWMEraseBkgnd);
> begin
>   // No automatic erase of background
>   m.Result := LRESULT(False);
> end;

> This will avoid the background to be redrawn.

> Regards,
> Nils Haeck
> www.abc-view.com

> Peter Laurens <pe...@the{*word*192}edge.net> wrote in message
> news:3c7c20d2$1_2@dnews...
> > Hi,

> > I know that double buffering and flickering images is probably the most
> > commonly asked question about Delphi graphics, but I'm not sure if
answers
> > supplied before will apply to my case...

> > I am creating a GUI for my app, I want it to be very touchy feely - very
> > interative and tangible. Due to this, I have TImages (which i am using
as
> > buttons) scrolling in and out of view on my form at variou times, with a
> > timer to control them, for example, if i want an image to scroll in from
> off
> > the top of the form i've got this happeniing on timer1...

> > if image1.top<30 then image1.top := image1.top+1;

> > Simple, but it flickers. Most of the images i want to move around aren't
> > moving over another image - just over the form background. I also have
> > TImages that update their positions on the 'OnResize' event of the form,
> so
> > they stay flush to the right for example, these also flicker when
resizing
> > the form.

> > How can I use double buffering to stop all this flickering? One thing I
> > should note is that my Delphi graphics knowledge is *non-existant* so
> > *please* bear this in mind if you are kind enough to help.

> > Many thanks in advance for whatever help you can offer.

> > -Peter

Re:Double buffering help (flickering)


Ah, I don't know about D3! I use D5 and it could very well be only
introduced in D4 or D5.

But try at least to override the erasebkground message. That will probably
already help.

To avoid flicker you could also implement your own FormPaint: use an
offscreen bitmap the size of the client area to draw to and blt it to the
form's canvas in the OnPaint event. In combination with EraseBkground this
should be flicker free.

Nils
www.abc-view.com

Quote
Peter Laurens <pe...@the{*word*192}edge.net> wrote in message

news:3c7d224c$1_1@dnews...
Quote
> I try to add

> doublebuffered:=true;

> under oncreate, but Delphi (3) doesn't seem to want to understand it (i
have
> 'graphics' under uses clause so i don't think i need to add anything else
up
> there, if i do, please let me know). I also tried
> Form1.doublebuffered:=true, Image1.doublebuffered:=true, but again, Delphi
> flagged them as errors and had no idea what this doublebuffered stuff was
> all about.

> (I tried the GM32 component set, but it only supports from Delphi 4
onward,
> and there's gotta be a way to sort this out in 3)

> Many thanks,

> -Peter

> "Nils" <n.ha...@quicknet.nl> wrote in message news:3c7c9f42$1_1@dnews...
> > Hi Peter,

> > Try to set

> >   DoubleBuffered := True;

> > in the form's OnCreate event.

> > If that does not help or is too slow, then try to add this:

> > // in the object interface
> >     procedure WMEraseBkgnd(var m: TWMEraseBkgnd); message WM_ERASEBKGND;

> > // in the implementation:
> > procedure TForm1.WMEraseBkgnd(var m: TWMEraseBkgnd);
> > begin
> >   // No automatic erase of background
> >   m.Result := LRESULT(False);
> > end;

> > This will avoid the background to be redrawn.

> > Regards,
> > Nils Haeck
> > www.abc-view.com

> > Peter Laurens <pe...@the{*word*192}edge.net> wrote in message
> > news:3c7c20d2$1_2@dnews...
> > > Hi,

> > > I know that double buffering and flickering images is probably the
most
> > > commonly asked question about Delphi graphics, but I'm not sure if
> answers
> > > supplied before will apply to my case...

> > > I am creating a GUI for my app, I want it to be very touchy feely -
very
> > > interative and tangible. Due to this, I have TImages (which i am using
> as
> > > buttons) scrolling in and out of view on my form at variou times, with
a
> > > timer to control them, for example, if i want an image to scroll in
from
> > off
> > > the top of the form i've got this happeniing on timer1...

> > > if image1.top<30 then image1.top := image1.top+1;

> > > Simple, but it flickers. Most of the images i want to move around
aren't
> > > moving over another image - just over the form background. I also have
> > > TImages that update their positions on the 'OnResize' event of the
form,
> > so
> > > they stay flush to the right for example, these also flicker when
> resizing
> > > the form.

> > > How can I use double buffering to stop all this flickering? One thing
I
> > > should note is that my Delphi graphics knowledge is *non-existant* so
> > > *please* bear this in mind if you are kind enough to help.

> > > Many thanks in advance for whatever help you can offer.

> > > -Peter

Re:Double buffering help (flickering)


A technique I have been using successfully lately is similar to what
others have suggested, overriding the WM_ERASEBKGND message but instead
of not allowing any background to be painted (which will not work well
on the form itself) I punch holes in the clipping region where other
controls are that will eventually paint themselves;

For example this is a TWinControl that contains a Border, a
DropDownButton, an Icon image, and a RichEdit in it.  By punching holes
in the clipping region of the DC I all but eliminated flickering during
a resize of the windows.

procedure TCustomExplorerCombobox.WMEraseBkgnd(var Message:
TWmEraseBkgnd);
var
  R: TRect;    
begin
  // Don't paint the background in the border area
  R := BackGroundRect(crBackGround);
  IntersectClipRect(Message.DC, R.Left, R.Top, R.Right, R.Bottom);

  // Don't paint where the button is
  R := BackGroundRect(crDropDownButton);
  ExcludeClipRect(Message.DC, R.Left, R.Top, R.Right, R.Bottom);

  // Don't paint where the icon is
  R := BackGroundRect(crImage);
  ExcludeClipRect(Message.DC, R.Left, R.Top, R.Right, R.Bottom);

  // Don't paint where the RichEdit
  R := BackGroundRect(crRichEdit);
  ExcludeClipRect(Message.DC, R.Left, R.Top, R.Right, R.Bottom);
  inherited;
end;

Jim

Other Threads