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

access resize form window
ms access resize form vba
cwnd movewindow
access form size too big
mfc onsize
mfc modifystyle
qwidget signals
cdialog::create

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.

NOTE: Steps 2 and 3 could be reversed.

The above three things appear to happen correctly when I use DeferSetWindowPos() in combination with the dialog resource marked as WS_CLIPCHILDREN.

I'd get an additional small benefit if I could do the above to a memory DC, and then only do a single bitblt at the end of the WM_SIZE handler.

I have played with this for a while now, and I cannot escape two things:

  1. I still am unable to suppress Windows from doing a 'predictive bitblt'. Answer: See below for a solution that overrides WM_NCCALCSIZE to disable this behavior.

  2. I cannot see how one can build a dialog where its child controls draw to a double buffer. Answer: See John's answer (marked as answer) below for how to ask Windows OS to double buffer your dialog (note: this disallows any GetDC() in-between paint operations, according to the docs).


My Final Solution (Thank you everyone who contributed, esp. John K.):

After much sweat and tears, I have found that the following technique works flawlessly, both in Aero and in XP or with Aero disabled. Flicking is non-existent(1).

  1. Hook the dialog proc.
  2. Override WM_NCCALCSIZE to force Windows to validate the entire client area, and not bitblt anything.
  3. Override WM_SIZE to do all of your moves & resizes using BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos for all visible windows.
  4. Ensure that the dialog window has the WS_CLIPCHILDREN style.
  5. Do NOT use CS_HREDRAW|CS_VREDRAW (dialogs don't, so generally not an issue).

The layout code is up to you - its easy enough to find examples on CodeGuru or CodeProject of layout managers, or to roll your own.

Here are some code excerpts that should get you most of the way:

LRESULT ResizeManager::WinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    switch (msg)
    {
    case WM_ENTERSIZEMOVE:
        m_bResizeOrMove = true;
        break;

    case WM_NCCALCSIZE:
        // The WM_NCCALCSIZE idea was given to me by John Knoeller: 
        // see: http://stackoverflow.com/questions/2165759/how-do-i-force-windows-not-to-redraw-anything-in-my-dialog-when-the-user-is-resiz
        // 
        // The default implementation is to simply return zero (0).
        //
        // The MSDN docs indicate that this causes Windows to automatically move all of the child controls to follow the client's origin
        // and experience shows that it bitblts the window's contents before we get a WM_SIZE.
        // Hence, our child controls have been moved, everything has been painted at its new position, then we get a WM_SIZE.
        //
        // Instead, we calculate the correct client rect for our new size or position, and simply tell windows to preserve this (don't repaint it)
        // and then we execute a new layout of our child controls during the WM_SIZE handler, using DeferWindowPos to ensure that everything
        // is moved, sized, and drawn in one go, minimizing any potential flicker (it has to be drawn once, over the top at its new layout, at a minimum).
        //
        // It is important to note that we must move all controls.  We short-circuit the normal Windows logic that moves our child controls for us.
        //
        // Other notes:
        //  Simply zeroing out the source and destination client rectangles (rgrc[1] and rgrc[2]) simply causes Windows 
        //  to invalidate the entire client area, exacerbating the flicker problem.
        //
        //  If we return anything but zero (0), we absolutely must have set up rgrc[0] to be the correct client rect for the new size / location
        //  otherwise Windows sees our client rect as being equal to our proposed window rect, and from that point forward we're missing our non-client frame

        // only override this if we're handling a resize or move (I am currently unaware of how to distinguish between them)
        // though it may be adequate to test for wparam != 0, as we are
        if (bool bCalcValidRects = wparam && m_bResizeOrMove)
        {
            NCCALCSIZE_PARAMS * nccs_params = (NCCALCSIZE_PARAMS *)lparam;

            // ask the base implementation to compute the client coordinates from the window coordinates (destination rect)
            m_ResizeHook.BaseProc(hwnd, msg, FALSE, (LPARAM)&nccs_params->rgrc[0]);

            // make the source & target the same (don't bitblt anything)
            // NOTE: we need the target to be the entire new client rectangle, because we want windows to perceive it as being valid (not in need of painting)
            nccs_params->rgrc[1] = nccs_params->rgrc[2];

            // we need to ensure that we tell windows to preserve the client area we specified
            // if I read the docs correctly, then no bitblt should occur (at the very least, its a benign bitblt since it is from/to the same place)
            return WVR_ALIGNLEFT|WVR_ALIGNTOP;
        }
        break;

    case WM_SIZE:
        ASSERT(m_bResizeOrMove);
        Resize(hwnd, LOWORD(lparam), HIWORD(lparam));
        break;

    case WM_EXITSIZEMOVE:
        m_bResizeOrMove = false;
        break;
    }

    return m_ResizeHook.BaseProc(hwnd, msg, wparam, lparam);
}

The resizing is really done by the Resize() member, like so:

// execute the resizing of all controls
void ResizeManager::Resize(HWND hwnd, long cx, long cy)
{
    // defer the moves & resizes for all visible controls
    HDWP hdwp = BeginDeferWindowPos(m_resizables.size());
    ASSERT(hdwp);

    // reposition everything without doing any drawing!
    for (ResizeAgentVector::const_iterator it = m_resizables.begin(), end = m_resizables.end(); it != end; ++it)
        VERIFY(hdwp == it->Reposition(hdwp, cx, cy));

    // now, do all of the moves & resizes at once
    VERIFY(EndDeferWindowPos(hdwp));
}

And perhaps the final tricky bit can be seen in the ResizeAgent's Reposition() handler:

HDWP ResizeManager::ResizeAgent::Reposition(HDWP hdwp, long cx, long cy) const
{
    // can't very well move things that no longer exist
    if (!IsWindow(hwndControl))
        return hdwp;

    // calculate our new rect
    const long left   = IsFloatLeft()   ? cx - offset.left    : offset.left;
    const long right  = IsFloatRight()  ? cx - offset.right   : offset.right;
    const long top    = IsFloatTop()    ? cy - offset.top     : offset.top;
    const long bottom = IsFloatBottom() ? cy - offset.bottom  : offset.bottom;

    // compute height & width
    const long width = right - left;
    const long height = bottom - top;

    // we can defer it only if it is visible
    if (IsWindowVisible(hwndControl))
        return ::DeferWindowPos(hdwp, hwndControl, NULL, left, top, width, height, SWP_NOZORDER|SWP_NOACTIVATE);

    // do it immediately for an invisible window
    MoveWindow(hwndControl, left, top, width, height, FALSE);

    // indicate that the defer operation should still be valid
    return hdwp;
}

The 'tricky' being that we avoid trying to mess with any windows that have been destroyed, and we don't try to defer a SetWindowPos against a window that is not visible (as this is documented as "will fail".

I've tested the above in a real project that hides some controls, and makes use of fairly complex layouts with excellent success. There is zero flickering(1) even without Aero, even when you resize using the upper left corner of the dialog window (most resizable windows will show the most flickering and problems when you grab that handle - IE, FireFox, etc.).

If there is interest enough, I could be persuaded to edit my findings with a real example implementation for CodeProject.com or somewhere similar. Message me.

(1) Please note that it is impossible to avoid one draw over the top of whatever used to be there. For every part of the dialog that has not changed, the user can see nothing (no flicker whatsoever). But where things have changed, there is a change visible to the user - this is impossible to avoid, and is a 100% solution.

You can't prevent painting during resizing, but you can (with care) prevent repainting which is where flicker comes from. first, the bitblt.

There a two ways to stop the bitblt thing.

If you own the class of the top level window, then just register it with the CS_HREDRAW | CS_VREDRAW styles. This will cause a resize of your window to invalidate the entire client area, rather than trying to guess which bits are not going to change and bitblting.

If you don't own the class, but do have the ability to control message handling (true for most dialog boxes). The default processing of WM_NCCALCSIZE is where the class styles CS_HREDRAW and CS_VREDRAW are handled, The default behavior is to return WVR_HREDRAW | WVR_VREDRAW from processing WM_NCCALCSIZE when the class has CS_HREDRAW | CS_VREDRAW.

So if you can intercept WM_NCCALCSIZE, you can force the return of these values after calling DefWindowProc to do the other normal processing.

You can listen to WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE to know when resizing of your window starts and stops, and use that to temporarily disable or modify the way your drawing and/or layout code works to minimize the flashing. What exactly you want to do to modify this code will depend on what your normal code normally does in WM_SIZE WM_PAINT and WM_ERASEBKGND.

When you paint the background of your dialog box, you need to not paint behind any of the child windows. making sure that the dialog has WS_CLIPCHILDREN solves this, so you have this handled already.

When you do move the child windows, Make sure that you use BeginDeferWindowPos / EndDefwindowPos so that all of the repainting happens at once. Otherwise you will get a bunch of flashing as each window redraws their nonclient area on each SetWindowPos call.

Resize/Reposition the Controls in a Dialog at your Pleasure , You can resize or reposition the controls in your dialog derived from In many cases, it's also used as the main window of the project. Some are not very convenient for secondary developers to use. Now I will discuss something about how to avoid control flicker when moving the dialog as far as  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

If I understood the question properly, it's exactly the question Raymond addressed today.

Make controls stretch, shrink, or move as you resize a form, To change this behavior, you can use the Anchoring command. The control is anchored to the upper-left corner of the form, and does not change size. resize the form window (or, if the form is maximized, when you resize the Access window). If you have set your database to display objects as document tabs (the default  That is, when a user clicks on the edge of the window and starts to re-size it, i don't want to re-draw the entire contents until he lets go. This is because for some reason it's currently choppy at resizing probably because everything is re-docking and what not.

For some controls, you can use WM_PRINT message to make the control draw into a DC. But that doesn't really solve your primary problem, which is that you want Windows to NOT draw anything during resize, but to let you do it all.

And the answer is that you just can't do what you want as long as you have child windows.

The way I ended up solving this eventually in my own code is to switch to using Windowless Controls. Since they have no window of their own, they always draw at the same time (and into the same DC) as their parent window. This allows me to use simple double buffering to completely remove flicker. I can even trivially suppress painting of the children when I need to just by not calling their draw routine inside the parent's draw routine.

This is the only way I know of to completely get rid of flicker and tearing during resize operations.

CWnd Class, If a CWnd object is not attached to the handle, a temporary CWnd object is created and attached. When the user terminates your child window, destroy the CWnd resize dialog to client's size void CMyDlg::OnSizeToClient() { CRect 0) { pMenu->DeleteMenu(0, MF_BYPOSITION); // force a redraw of the  [ ] Do not resize and reposition my windows when system awakes from sleep state. Anything short of this is really not helpful at all -- it's a hack and a workaround that might screw up other things in my system and send me down an infinite loop of system tweaks from which I might never recover.

Here's a 2018 update, since I just ran through the very same gauntlet as you.

The "final solution" in your question, and the related answers, that mention tricks with WM_NCCALCSIZE and CS_HREDRAW|CS_VREDRAW are good for preventing Windows XP/Vista/7 from doing the BitBlt that molests your client area during resizing. It might even be useful to mention a similar trick: you can intercept WM_WINDOWPOSCHANGING (first passing it onto DefWindowProc) and set WINDOWPOS.flags |= SWP_NOCOPYBITS, which disables the BitBlt inside the internal call to SetWindowPos() that Windows makes during window resizing. This has the same eventual effect of skipping the BitBlt.

And some people mentioned that your WM_NCCALCSIZE trick no longer works in Windows 10. I think that might be because the code you wrote returns WVR_ALIGNLEFT|WVR_ALIGNTOP when it should be returning WVR_VALIDRECTS in order for the two rectangles you constructed (nccs_params->rgrc[1] and nccs_params->rgrc[2]) to be used by Windows, at least according to the very skimpy dox in the MSDN pages for WM_NCCALCSIZE and NCCALCSIZE_PARAMS. It's possible that Windows 10 is more strict about that return value; I would try it out.

However, even if we assume that we can convince Windows 10 not to do BitBlt inside SetWindowPos(), it turns out there's a new problem...

Windows 10 (and possibly also Windows 8) adds another layer of client area molestation on top of the old legacy molestation from XP/Vista/7.

Under Windows 10, apps do not draw directly to the framebuffer, but instead draw into offscreen buffers that the Aero Window manager (DWM.exe) composites.

It turns out that DWM will sometimes decide to "help" you by drawing its own content over your client area (sort of like a BitBlt but even more perverse and even further out of your control).

So in order to be free of client area molestation, we still need to get WM_NCCALCSIZE under control but we also need to prevent DWM from messing with your pixels.

I was fighting with exactly the same problem and created a roundup Question/Answer which brings together 10 years of posts on this topic and offers some new insights (too long to paste the content here in this question). The BitBlt mentioned above is no longer the only problem, as of Windows Vista. Enjoy:

How to smooth ugly jitter/flicker/jumping when resizing windows, especially dragging left/top border (Win 7-10; bg, bitblt and DWM)?

PC Mag, Action buttons force objects to have the same height and/or width, to exhibit the same angle of When you edit one part of your drawing, these logical links kick in and flagship drawing package, IntelliDraw does not offer a named styles palette. To complete an animation, you must use two different dialog boxes and​  I have a Win32, dialog-based app that contains a dialog which must perform a long-running [several seconds] operation before allowing user input. I would like to force the dialog to draw itself before performing the operation, however, I cannot find a satisfactory way to do this. My current code is as follows: OnInitDialog() {

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.

QWidget Class, The QWidget class is the base class of all user interface objects. If your widget only contains child widgets, you probably do not need to implement wider set of events to handle mouse movement, button presses, and window resizing. Window flags are a combination of a type (e.g. Qt::Dialog) and zero or more hints to  AliRafiee's solution leaves "dirt" when user moves borders back and forth during resizing, and does not eliminate flickering on tabs. My solution is to also put UPDATE_EASYSIZE in the OnExitSizeMove handler and to use a Boolean flag, say m_bSizing_es, that's set to FALSE in the OnInitDialog handler, set to TRUE in the OnSizing handler, and set to FALSE in the OnExitSizeMove handler.

Solving Common Painting Problems (The Java™ Tutorials , This Swing Java Tutorial describes developing graphical user interfaces (GUIs) Problem: I don't know where to put my painting code. Check whether repaint is invoked on your component whenever its appearance needs to be updated. JPanel s, for example, are opaque by default in many but not all look and feels. The modal dialog is triggered from a button's dynamic action (calling Javascript) The modal dialog contains classic report, which may have more or less data, that's why I need the window length to be dynamic.

Settings, Git Extensions will not allow you to checkout a branch if you have An option on the command line dialog window displayed allows this setting to be turned off. Use patience diff algorithm ¶. Use the Git 'patience diff' algorithm instead of the default. This can be any command that your system can run e.g. an executable​  The app is portable, has no interface, and sits in the system tray. All you have to do is to run the program and try resizing the window. For example, the Screensaver dialog in Windows cannot be resized. After running the app, we can easily resize it as you can see from the screenshot below.

PySimpleGUI, I went from not even being able to load a window in Tkinter reliably to making Use this solution for your Pi projects that don't have anything connected in If configured as an Open File Popup then (save_as is not True) the dialog box will look like this. Call to force a window to go through the final stages of initialization. Please follow the steps given below on how to turn off Auto refresh in Internet Explorer 10. a) Open Internet Explorer. Click on Tools and then Internet Options. b) In the Internet Options dialog box, click on the Security tab and then select Internet Zone. Click on the button below labeled Custom Level.

Comments
  • This technique no longer works under Win10 (and probably didn't under Win8). Sad. We're right back to watching the controls "walk" across the screen to where they should be, instead of instantly jumping to their correct position.
  • Since you asked, sure, I would like to see a real example implementation. This is something that interests me, especially if it's a full winapi (i.e., non-MFC) solution. MFC would be interesting to read too. Any updates for Windows 10?
  • @jrh Sadly, Windows 8+ broke this technique, and I haven't been inspired to figure out how to make it work again (if it is even possible). The above worked from XP, Vista, Win 7. But 8+ just makes it as stupid as it was without all of this effort.
  • Is there a technique for choosing a windows class when you create a modal dialog box, instead of having the OS choose the standard one? I can certainly hook the dialog box's wndproc, but is there a better way?
  • Okay, I'm not sure that this is going to help. The options available to me seem to be "preserve the window thusly (there are several alignment options), or redraw it all". I don't want windows to redraw it at all, but I don't want it to necessarily redraw it all either - just let me do it (maybe I can validate things in WM_SIZE handler to counteract the WVR_REDRAW.
  • @Mordachai: You can create a window class, and use DefDialogProc instead of DefWindowProc, but its something no-one ever does, I'm not sure why but I suspect that when you do that, subtle things go wrong.
  • Well, I'm not sure what to make of it, but I seem to have a solution to my initial motivation: flicker free resizing. If I use DeferSetWindowPos when moving the child controls during the WM_SIZE handler, then the window resizes almost perfectly (I also force the dialog itself to have WS_CLIPCHILDREN). I still find all of this to be a bit of a black art. Why is it so difficult to manage the order that child windows redraw? Why does the DeferSetWindowPos loop succeed where manually moving the controls, then invalidating them fail? Sigh...
  • @John - I hooked WM_NCCALCSIZE, and looked at what the base proc returned - and it always returns 0 for a dialog. If I override it to return WVR_REDRAW during a resize, then the controls on the dialog "drift away"... its bizarre.
  • Unfortunately, The technique Raymond describes assumes that the window has no child windows.
  • @John: Couldn't it be applied even if there are child windows? Windows doesn't automatically know how to resize child windows. The application could choose to defer those resizes.
  • @jamesdlin: The painting of child windows is not under control of the parent, so no, the technique doesn't work if there are child windows unless you do tricky things like hiding them when resize starts.