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
- I use the STL implementation of vector so you’ll have to
ensure that you add #include <vector> to your stdafx.h
file. - 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. - 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.