Alex Rivera | Logout

How do I force windows NOT to redraw anything in my dialog when the user is resizing my dialog?

Asked 2010-01-29T22:48:12.053
33

When the user grabs a corner of a resizable window, and then moves it, windows first moves the contents of the window around, then issues a WM_SIZE to the window being resized.

Thus, in a dialog where I want to control the movement of various child controls, and I want to eliminate flickering, the user first sees what windows OS thinks the window will look like (because, AFAICT, the OS uses a bitblt approach to moving things around inside the window before sending the WM_SIZE) - and only then does my dialog get to handle moving its child controls around, or resize them, etc., after which it must force things to repaint, which now causes flicker (at the very least).

My main question is: Is there a way to force windows NOT to do this stupid bitblt thing? Its definitely going to be wrong in the case of a window with controls that move as the window is resized, or that resize themselves as their parent is resized. Either way, having the OS do a pre-paint just screws the works.

I thought for a time that it might be related to CS_HREDRAW and CSVREDRAW class flags. However, the reality is that I don't want the OS to ask me to erase the window - I just want to do the repainting myself without the OS first changing the contents of my window (i.e. I want the display to be what it was before the user started resizing - without any bitblit'ing from the OS). And I don't want the OS to tell every control that it needs to be redrawn either (unless it happened to be one that was in fact obscured or revealed by the resize.

What I really want:

  1. To move & resize child controls before anything gets updated onscreen.
  2. Draw all of the moved or resized child controls completely so that they appear without artifacts at their new size & location.
  3. Draw the spaces inbetween the child controls without impacting the child controls themselves.

NO

Edit
Report

2 Answers

0

If you can find a place to plug it in, CWnd::LockWindowUpdates() will prevent any drawing from occuring until after you unlock the updates.

But keep in mind this is a hack, and a fairly ugly one at that. Your window will look terrible during resizes. If the problem you are having is flickering during resizes, then the best thing to do is diagnose the flickering, rather than hiding the flickering by blocking paints.

One thing to look for are redraw commands that get called too often during the resize. If you r window's controls are calling RedrawWindow() with the RDW_UPDATENOW flag specified, it is going to repaint then and there. But you can strip out that flag and specify RDW_INVALIDATE instead, which tells the control to invalidate the window without repainting. It will repaint at idle time, keeping the display fresh without spazzing out.

answered 2010-01-29T23:01:21.387
0

There are various approaches, but I found the only one that can be used generally is double buffering: draw to an offscreen buffer, then blit the entire buffer to screen.

That comes for free in Vista Aero and above, so your pain might be shortlived.

I am not aware of a general double-buffering implementation for windows and system controls under XP, However, here are some things to explore:

Keith Rule's CMemDC for double-buffering anything you draw yourself with GDI
WS_EX_COMPOSITED Window style (see the remarks section, and something here on stackoverflow)

answered 2010-01-29T23:17:30.407

Your Answer