views:

3926

answers:

5

I have a dialog that resizes. It also has a custom background which I paint in response to a WM_ERASEBKGND call (currently a simple call to FillSolidRect).

When the dialog is resized, there is tremendous flickering going on. To try and reduce the flickering I enumerate all child windows and add them to the clipping region. That seems to help a little -- now the flickering is mostly evident in all of the child controls as they repaint.

How can I make the dialog flicker-free while resizing? I suspect double-buffering must play a part, but I'm not sure how to do that with a dialog with child controls (without making all child controls owner-draw or something like that).

I should note that I'm using C++ (not .NET), and MFC, although pure Win32-based solutions are welcomed :)

NOTE: One thing I tried but which didn't work (not sure why) was:

CDC memDC;
memDC.CreateCompatibleDC(pDC);
memDC.FillSolidRect(rect, backgroundColor);

pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
+1  A: 

Double buffering is indeed the only way to make this work.

Child controls will take care of themselves so long as you make sure CLIPCHILDREN.

Frank Krueger
+3  A: 

Do nothing in the WM_ERASEBKGND handling and do the erase as part of your main WM_PAINT. You can either paint smarter so that you only redraw the invalid areas, or more easily, double-buffer the drawing.

By not doing anything in the erase background, you have all your drawing code in one location which should make it easier for others to follow and maintain.

Jeff Yates
+1  A: 

Try adding the following line to your OnInitDialog function:

    ModifyStyle(0, WS_CLIPCHILDREN, 0);
Adam Pierce
+3  A: 

Assuming that "FillSolidRect" is the erase of your background then return TRUE from the WM_ERASEBKGND.

To do the double buffering that you are almost doing in your code fragment, you will need to use CreateCompatibleBitmap and select that into your memDC.

David L Morris
+1  A: 

If you are targeting WinXP or higher, you can also use the WS_EX_COMPOSITED style to enable double-buffering by default for top-level windows with this style. Bear in mind this has its own set of limitations -- specifically, no more drawing out of OnPaint cycles using GetDC, etc.

adzm