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


Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

Most Popular Programming Stories

More for Developers

RSS Feeds