The Sample Dialog
- Original Dialog
- Dialog after sized bottom-right
- Dialog after sized left-top
Introduction
This resizable dialog class can automatically adjusts controls position
and/or size as dialog is sized. the reposition and resize is direction sensitive
(left and right, top and bottom can be handled differently respectively) and
behave one of six ways: NONE, RESIZE, REPOS, RELATIVE, ZOOM, DELTA_ZOOM (see
below for more information).
Background
This class was derived from the Flicker-Free
Resizing Dialog (thanks Andy Brown). Andy Brown had solved the flicker
problem (which really puzzled me once) and his class supports resizing in NONE,
RESIZE, REPOS, RELATIVE mode.
However I need more controllable reposition and/or resize handler, I think
someone else need it too. So I enhanced Andy Brown's class and wrote this class
which added the following features:
- Reposition and resize is direction sensitive. e.g. Andy Brown's class treat
dialog's sizing left and right as the same sizing (x-direction). This class can
treat them differently.
- Zoom control as dialog is zoomed.
- Be able to adjust more than one controls' position and/size respectively,
which are at the same X-/y-level. e.g. this class can resize two controls which
are at the same horizontal line as 50% as dialog's changed-width, in another
words, if dialog's width is increased 10 pixels, this class increase each
control's width 5 pixels.
Using the code
- Add ResizeDlg.cpp and ResizeDlg.h to your project or makefile;
- Add "#Include ResizeDlg.h" to stdafx.h file or your dialog
header file;
- Make your dialog-derived class inherit from
CResizeDlg
instead
of CDialog
by replacing all instances of "CDialog
"
with "CResizeDlg
" in your dialog header and implementation files.
- Add a handler for
WM_INITDIALOG
in your dialog class if you
haven't done so, as described below.
WM_INITDIALOG (OnInitDialog)
In your OnInitDialog
handler you should call the base class's
OnInitDialog
and call AddControl
for those controls
that are to be automatically repositioned and/or sized when the dialog is sized.
here is an example.
BOOL CMyDialog::OnInitDialog()
{
CResizeDlg::OnInitDialog();
AddControl(IDOK, CST_REPOS, CST_REPOS, CST_NONE, CST_NONE, 1);
AddControl(IDCANCEL, CST_REPOS, CST_REPOS, CST_NONE, CST_NONE, 1);
return TRUE;
}
How Controls Reposition and/or Size
This class allow controls dynamically repositioned and/or sized in each
direction (left, top, right, bottom) as one of the following ways.
CST_NONE |
do not reposition and size in this direction; |
CST_RESIZE |
size controls as much as dialog's changed-size in this
direction.
ctrlRect.right += deltaX; |
CST_REPOS |
reposition controls as much as dialog's change-size in this
direction.
ctrlRect.left += deltaX;
ctrlRect.right += deltaX; |
CST_RELATIVE |
reposition controls with user-defined proportion (make controls
always at the same proportional position in dialog).
newCx = ctrlRect.Width();
ctrlRect.left = (int)(m_xRatio *
pnRect->Width() - newCx / 2.0);
ctrlRect.right = ctrlRect.left + newCx; |
CST_ZOOM |
reposition and size controls automatically
ctrlRect.left = (int)(1.0 * ctrlRect.left
* (double)pnRect->Width() / pR0->Width());
ctrlRect.right = (int)(1.0 * ctrlRect.right
* (double)pnRect->Width() / pR0->Width()); |
CST_DELTA_ZOOM |
reposition and size controls proportionally, both proportion can
be set respectively.
newCx = ctrlRect.Width();
ctrlRect.right = (int)(ctrlRect.left +
deltaX0 * m_xRatio + newCx + deltaX0 * m_cxRatio);
ctrlRect.left += (int)(deltaX0 * m_xRatio); |
Usage of AddControl
You should call AddControl
to set how controls behave as dialog
is sized in OnInitDialog
. It's prototype as below:
void AddControl( UINT nID, int xl, int xr, int yt,
int yb, int bFlickerFree = 0,
double xRatio = -1.0, double cxRatio = -1.0,
double yRatio = -1.0, double cyRatio = -1.0 );
where
nID |
control's resource ID |
xl |
how controls reposition and/or resize when dialog resize left.
set it one of CST_xx. |
xr |
how controls reposition and/or resize when dialog resize right.
set it one of CST_xx. |
yt |
how controls reposition and/or resize when dialog resize top.
set it one of CST_xx. |
yb |
how controls reposition and/or resize when dialog resize bottom.
set it one of CST_xx. |
bFlickerFree |
whether try to avoid flickering when reposition and/or resize
this control |
xRatio |
user-defined x-direction reposition proportion. valid only when
xl or xr is CST_RELATIVE or CST_DELTA_ZOOM. set it to 0.0~1.0. |
cxRatio |
user-defined x-direction resize proportion. valid only when xl
or xr is CST_DELTA_ZOOM. set it to 0.0~1.0. |
yRatio |
user-defined y-direction reposition proportion. valid only when
yt or yb is CST_RELATIVE or CST_DELTA_ZOOM. set it to 0.0~1.0. |
cyRatio |
user-defined y-direction resize proportion. valid only when yt
or yb is CST_DELTA_ZOOM. set it to 0.0~1.0. |
Typical use of AddControl
- keep a edit control resize horizontally as dialog sized.
AddControl(edit-ID, CST_RESIZE, CST_RESIZE,
CST_NONE, CST_NONE, 1);
- keep a top-right button at the same top-right position.
AddControl(button-ID, CST_REPOS, CST_REPOS,
CST_NONE, CST_NONE, 1);
- Keep a button at the fixed distance to bottom and horizontal-center.
AddControl(button-ID, CST_RELATIVE, CST_RELATIVE,
CST_REPOS, CST_REPOS, 1, 1.0);
- two edit controls are in a horizontal-line, make left edit control resize
and right one keep the same size when dialog left-sized, or left one keep the
same size and right one resize when dialog size right.
AddControl(left-edit-ID, CST_RESIZE,
CST_NONE, CST_NONE, CST_NONE, CST_NONE, 1);
AddControl(right-edit-ID, CST_REPOS,
CST_RESIZE, CST_NONE, CST_NONE, 1);
- two edit controls as example 4. make them size share the same of dialog's
changed-width. In another words, if dialog's width increase 10 pixels, then each
of the edit-control increase its width 5 pixels respectively.
AddControl(left-edit-ID, CST_DELTA_ZOOM, CST_DELTA_ZOOM,
CST_NONE, CST_NONE, 1, 0.0, 0.5);
AddControl(right-edit-ID, CST_DELTA_ZOOM, CST_DELTA_ZOOM,
CST_NONE, CST_NONE, 1, 0.5, 0.5);
where 0.0, 0.5
means
left-edit control do not change its position and resize as 50% as dialog's
changed-width. 0.5, 0.5
means right-edit control change its
position as 50%, because left control resize, so it must reposition, and resize
as 50% as dialog's changed-width.
Attention
- Resize-grip (
, at the bottom-right of dialog) 's resource ID (IDC_DLGSIZEBOX) is
defined in ResizeDlg.h. You should set it another unused resource ID if you have
used it in somewhere else.
- Do not set flicker-free for group-controls in dialog (set
bFlickerFree
to 0 in calling AddControl
).
History
- Sep 26, 2004 -Initial public release.