Flicker-Free Resizing Dialog

CResizingDialog

This resizing dialog class was inspired by the code contributed by
Hans Buehler
, which
I have used extensively in the past. In writing this class I have attempted to
fix the problem of the excessive flicker that occurs as you resize a dialog and
the controls are dynamically moved around (I assume you have the "Show
window contents while dragging" explorer option set).

Flickering occurs because the dialog erases it’s background during WM_ERASEBKGND
processing and then the control windows are drawn on top. For most controls this
is unnecessary since they erase their window rectangle before drawing themselves
(there are some annoying exceptions which I will get to later). The solution is
to add an OnEraseBkgnd() handler to the sizing
dialog class and exclude the rectangle occupied by the control window from the
clipping region using CDC::ExcludeClipRect().

How to use it

  1. I use the STL implementation of vector so you’ll have to
    ensure that you add #include <vector> to your stdafx.h
    file.
  2. Make your dialog class inherit from CResizingDialog
    instead of CDialog by adding #include
    "ResizingDialog.h"
    to your dialog header file and replacing
    all instances of "CDialog" with
    "CResizingDialog" in your dialog
    header and implementation files.
  3. If you haven’t already done so then add a handler for WM_INITDIALOG
    in your dialog class, as described below.

WM_INITDIALOG

In your OnInitDialog() handler you need to do a
few things. Firstly you must call the base class implementation, and secondly
you need to add the controls that are to be dynamically repositioned as the
dialog is resized. Here’s an example of a minimal OnInitDialog()
implementation.

BOOL CSampleDlg::OnInitDialog()
{
// call the base class, you must do this

    CResizingDialog::OnInitDialog();

// add sizing controls

    AddControl(IDC_EDIT1,sizeResize,sizeNone);
    AddControl(IDC_EDIT2,sizeResize,sizeNone);

    AddControl(IDOK,sizeRelative,sizeRepos);
    AddControl(IDCANCEL,sizeRelative,sizeRepos);

// OK

    return TRUE;
}

The members of CResizingDialog that you can call are as follows. 

void AddControl(const UINT resID,const eSizeType xsize,const eSizeType ysize,const bool bFlickerFree=true)

Adds a control to the list of those that will be dynamically resized. resID
is the integer resource identifier of the control. xsize and
ysize govern how
the control will be resized or repositioned in the horizontal and vertical
directions when the dialog is resized by the user. Their values are taken from
the following enumeration.

sizeNone Don’t resize at all 
sizeResize The control will be stretched in the appropriate direction
sizeRepos The control will be moved in the appropriate direction
sizeRelative The control will be moved proportionally in the appropriate
direction

If you want the control to be resized in a flicker-free way then leave the
last parameter as true. Some controls, such as
group boxes and static rectangles, do not erase their own backgrounds and hence
cannot be sized in a flicker free way. If you find that a control in your dialog
is leaving ‘trails’ behind it when you resize it then set bFlickerFree
to false.

void AllowSizing(const eSizeType xsize,const eSizeType ysize);

The default implementation allows resizing in both horizontal and vertical
directions. You can call this function to disable sizing in any particular
direction. Set xsize or ysize
to either sizeNone or sizeResize
to disable or enable resizing in that direction.

void HideSizeIcon(void)

The default implementation displays a small sizing icon in the bottom right
corner of the dialog in order to give the user a visual cue that this dialog is
resizable. If you don’t want that icon to be displayed then call this function.

Downloads

Download demo project – 15 Kb
Download source – 4 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read