gdi flickering

G

Guest

hi, i created a paint program for my c++ class using a global GraphicsPath
variable. i the, in the onpaint method, draw the line the users draws with
the mouse. simple. the only problem is that when i invalidate the panel im
drawing on in order to see the line, it flickers, even with double buffering.
if i only invalidate a rectangle around teh mouse, if the user mouse the
mouse too fast the line wont be drawn in certain intervals because the paint
event cant fire enough times. how can i either eliminate the flickering or
invalidate a part of the panle enough that it will show the entire line at
draw time. (if i bring anything in front of the panel or minimize the
program, the windows repaint method shows the graphics)

i also tried using a Graphics variable to draw on a surface on a mousedown
event, but then if you minimized the program or brought anything in front of
the graphics, youd lose what you drew. how can i sto this from happeneing?

which ever question is easier to answer, if any, would be helpful. ive been
researching this for weeks but i cant seem to find an answer, thanks
 
D

David Wilkinson

iwdu15 said:
hi, i created a paint program for my c++ class using a global GraphicsPath
variable. i the, in the onpaint method, draw the line the users draws with
the mouse. simple. the only problem is that when i invalidate the panel im
drawing on in order to see the line, it flickers, even with double buffering.
if i only invalidate a rectangle around teh mouse, if the user mouse the
mouse too fast the line wont be drawn in certain intervals because the paint
event cant fire enough times. how can i either eliminate the flickering or
invalidate a part of the panle enough that it will show the entire line at
draw time. (if i bring anything in front of the panel or minimize the
program, the windows repaint method shows the graphics)

i also tried using a Graphics variable to draw on a surface on a mousedown
event, but then if you minimized the program or brought anything in front of
the graphics, youd lose what you drew. how can i sto this from happeneing?

which ever question is easier to answer, if any, would be helpful. ive been
researching this for weeks but i cant seem to find an answer, thanks

iwdu15:

You probably need to do something with the WM_ERASEBKGND message. What I
usually do is return TRUE from the handler and draw everything,
including the backround, in OnPaint().

HTH,

David Wilkinson
 
D

David Wilkinson

iwdu15 said:
how would i do that? and what is "the WM_ERASEBKGND message"...thanks for
your help

iwdu15:

If this is a Win32 or MFC application this is a Windows message like any
other. For MFC you can add message handlers by going to the appropriate
class in ClassView and Selecting Properties->Events.

If this is a .NET application then my suggestion may not be relevant.
You will need to ask someone else to help you.

David Wilkinson
 
B

Brian Muth

Flickering is usually due to erasing the background. But if you erase using
the null background brush, you won't see that flash of white.

Brian
 
T

Tamas Demjen

WM_ERASEBKGND is a system message. Normally a control responds to it by
painting a gray rectangle. That's what you want to disable. You simply
catch that message and swallow it (override WndProc do not call the base
class' WndProc). But it depends which GUI framework you're using.

I'm not sure if this helps, but this is what I usually put in my
constructors (my owner-draw controls are usually inherited from Panel).
This should take care of the flicker problem, provided you're
implementing your own double buffering:
SetStyle(ControlStyles::Opaque, true);

This turns off the system painting of the control. It means if you don't
paint it on your own, there's going to be a hole in your window, which
gets corrupted as you work. So it's essencial that you do your own
painting by overriding the OnPaint method. Create an off-screen bitmap,
paint your contents on there, then show the off-screen bitmap on the
screen in a single statement. That should be the only painting you're
doing to the screen.

Tom
 
G

Guest

so then how would i do that using the onpaint method? i have colored lines on
my form and every mousemove i invalidate the panel...if thta helps any
 
B

Brian Muth

You would register the NULL brush at the time the window is registered. This
is basic windows programming. If this is unclear, see the first few chapters
of Charles Petzold's "Programming Windows" Fifth edition.

Brian
 
G

Guest

Yes, In MFC:

What you need to do is have your drawing/painting go to a memory device
context (CDC) instead of the screen device context in OnDraw( ). Then paint
to the screen using a bitblt to the screen DC from the mem DC.

You need to:
Create a memory Device Context: new CDC( );
Create a bitmap and make it compatible with the screen DC.
Assign the bitmap to the memory DC.
In OnDraw(), draw to the memDC instead of the screen DC using normal GDI
calls as always.
Then at the end, bitblt the Mem DC to the Screen DC.

Also to handle erase:
Write your own erase that does a FillRect (for example) to the Mem DC.
Override the OnEraseBkgnd( ) and don't call the base class.

It sounds complex and it is a bit, but once you get the idea that your
really just drawing to memory then bitblt'ing to the screen all at once, it's
not so bad.

Plus, no more flicker.
 
G

Guest

I realize that you are probably referring to .NET so my previous MFC guidance
may not be helpful.

However, I also have addressed flicker in .NET, I'll have to check my code
but it know it required two settings not just one. I think they are:

ControlStyles.DoubleBuffer
ControlStyles.AllPaintingInWmPaint
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top