|
![]() |
A: There is no difference !
The cdxCSizingDialog class is a class derived from CDialog
making it very easy to implement sizable dialogs. I really missed
that feature in VC++ (and IMHO it's a shame to the MFC that it doesn't
provide an easy to use way to solve this problem).
However, now it is possible to make your dialogs sizable - you can
add this to an existing dialog in three steps !
In addition to cdxCSizingDialog, you will even find both cdxCSizingPropSheet
and cdxCSizingPropPage in the two files that are part
of the zip, but these are considered to be in beta stadium for
now (they seem to work ... I only have problems with the sizing icon).
The most important features of cdxCSizingDialog are:
- cdxCSizingDialog() - define in which directions your dialog might be resized.
- OnInitDialog() - sets up the minimum size of your dialog.
- AddSzControl() - make a control react if the dialog's size changes (simple version).
- AddSzControlEx() - the same as AddSzControl() but far more powerful (advanced).
- RestoreWindowPosition()/StoreWindowPosition() - load/store window position to registry.
- StrechWindow() - increase window size.
cdxCSizingPropSheet
- cdxCSizingPropSheet() - construct a sizable property sheet.
- OnInitDialog() - sets up the minimum size of your property sheet.
- AddPage() - add a property page derived from cdxCSizingPropPage
- RestoreWindowPosition()/StoreWindowPosition() - load/store window position to registry.
- StrechWindow() - increase window size.
cdxCSizingPropPage
- cdxCSizingPropPage() - construct a sizable property page.
- GetSheet() - get the associated property sheet.
- OnInitDialog() - sets up the minimum size of your property page.
- AddSzControl() - make a control react if the dialog's size changes (simple version).
- AddSzControlEx() - the same as AddSzControl() but far more powerful (advanced).
cdxCSizingDialog::cdxCSizingDialog():
Synopsis:
cdxCSizingDialog(UINT idd, CWnd *pParent = NULL, Freedom fd = fdAll, bool mkSizeIcon = true);
[protected]Task:
Constructs the dialog class with the given Resource ID and parent window (see documentation of CDialog::CDialog() for further details).
Additionally, the freedom parameter allows you to decide whether you want your dialog class being sizable in both x and y direction or in only one of them and the mkSizeIcon boolean enables creation of a windows-style size icon in the lower right corner of your window.Parameters:
UINT idd
The resource ID of the dialog resource.CWnd *pParent
Pointer to the parent window or NULL.Freedom fd
Freedom is an embedded enumerator of cdxCSizingDialog. It may have the following values:fdAll
The dialog's size can be changed in both x and y direction.fdHoriz
The dialog's size can only be changed in width.fdVert
The dialog's size can only be changed in height.bool mkSizeIcon
Set this to false if you don't like/need the icon (just leave it true to see what it is :^).cdxCSizingDialog::OnInitDialog():
Synopsis:
virtual BOOL OnInitDialog(UINT addSzByPcnt);
virtual BOOL OnInitDialog();[protected]
Task:
Sets up the base cdxCSizingDialog object.
Must be called before using AddSzControl()!Some word to the minimum size of your window:
This function sets up various data which it gets from your dialog - it creates the dialog and reads its size which will be taken as the minimum size of the dialog.
This convention had been made in order to allow you to design your dialog in a way that looks great even if the dialog is reduced to its minum size.
On the other hand, this way also has a disadvantage: Most dialogs would look much nicer (and would be more easy to handle) if they get a reasonable bigger size than the minimum one.
To solve this problem, next to the standard OnInitDialog(void) function exported by CDialog, you even find a second form allowing you to pass the addSzByPcnt parameter to the function. This parameter allows you to increase the size of the dialog automatically (thus the dialog won't appear in its minimum width but slightly bigger).OnInitDialog(void) is a short-cut to OnInitDialog(UINT addSzByPcnt) passing cdxCSizingDialog::DEF_STRETCH (which is 10) to it.
Parameters:
- addSzByPcnt
This parameter will be passed to StrechWindow() if non-zero, increasing the size of the window by
newSize = originalSize + (originalSize * addSzByPcnt) / 100.
See StretchWindow() for more information.Remarks:
Since the size of the dialog may change during the call to OnInitDialog() (and to a subsequent call to RestoreWindowposition() if you use this function), I recommend to design your dialog without the WS_VISIBLE flag and to use CDialog::ShowWIndow(SH_SHOW) just before you finish your own OnInitDialog().An example code would could like:
BOOL MyDialog::OnInitDialog()
{
BOOL b = cdxCSizingDialog::OnInitDialog();// add your controls
AddSzControl(m_wndAnyControl,mdRepos,mdRepos);
...// modify controls (add columns to controls etc...)
...
// load window position from registry
RestoreWindowPosition(_T("MyDialog_Position"));
// finally, show window
ShowWindow(SW_SHOW);
return b;
}See also:
cdxCSizingDialog(), AddSzControl(), RestoreWindowPosition(), StretchWindow(), CDialog::ShowWindow()
cdxCSizingDialog::AddSzControl():
Synopsis:
void AddSzControl(CWnd & ctrl, Mode modeX = mdNone, Mode modeY = mdNone);
void AddSzXControl(CWnd & ctrl, Mode modeX);
void AddSzYControl(CWnd & ctrl, Mode modeY);
[protected]
Task:
Tells the underlaying cdxCSizingDialog about a dialog control that should react on changes to the size of the dialog. You have to call this function for each control that should change its position and/or size in x and/or y direction.
AddSzXControl() and AddSzYControl() are simple short-cut inlines for AddSzControl().Parameters:
- CWnd & ctrl
The control.- Mode modeX
Defines the way the control reacts on changes to the dialog's width; for possible values see below.- Mode modeY
Defines the way the control reacts on changes to the dialog's height; for possible values see below.
Mode is an embedded enumerator of cdxCSizingDialog.
It may have the following values (given we talk about the x-dimension, i.e. the width of the dialog):
- mdNone
Nothing. The control remains in its position and size ("control sticks to the left of the dialog").- mdRepos
The control moves to the right if the control's width increases ("control sticks to the right of the dialog").- mdResize
The control's width grows if the dialog's width grows ("sizing the dialog even sizes the control").- mdRelative
The control's position will be kept relative to the dialog's width; its size won't change ("keeps centered controls being centered"): If the dialog's width increases by 100, the control will be moved to the left by 50.Even note the description in the tutorial, if things are not clear yet.Remarks:
- Important:
You have to call cdxCSizingDialog::OnInitDialog() before using this function.- If you call AddSzControl() with both modeX and modeY set to mdNone, this function does nothing (except tracing a warning if you run it in the debugger).
For further details on the Mode parameters, see AddSzControlEx() below.See also:
OnInitDialog(), AddSzControlEx()
cdxCSizingDialog::AddSzControlEx():
Synopsis:
void AddSzControlEx(CWnd & ctrl, BYTE dX1pcnt, BYTE dX2pcnt, BYTE dY1pcnt, BYTE dY2pcnt);
void AddSzXControlEx(CWnd & ctrl, BYTE dX1pcnt, BYTE dX2pcnt);
void AddSzYControlEx(CWnd & ctrl, BYTE dY1pcnt, BYTE dY2pcnt);
[protected]
Task:
This is the advanced version of AddSzControl(), which makes use of this function.AddSzXControlEx() and AddSzYControlEx() are simple short-cut inlines for AddSzControlEx().Parameters:
An example:
- CWnd & ctrl
The control.- BYTE dX1pcnt, BYTE dX2pcnt, BYTE dY1pcnt, BYTE dY2pcnt
These values describe how to manipulate the four position values left (x1), top (y1), right (x2) and bottom (y2) of the control ctrl.
These values are positive percent values. If the dialog changes its size, the difference between its initial (i.e. minimum) size will be calculated (deltaX and deltaY) and the values x1-y2 will be set to their initial values plus pcnt percent of the appropiate delta value.Use the value cdxCSizingDialog::exIgnore(0) to say that a value should not be used (the appropiate position value will stay untouched in all cases) or cdxCSizingDialog::exMaximum(100) to apply the maximum value.
Let's say the initial left position (x1) of the control is 10, the initial size of the dialog is 100 and you set the appropiate pcnt value (dX1pcnt) to 50.
In short, the following formulas are used:
- Now the dialog's widht changes from 100 to 140:
- The difference between the initial widht and the current one is 140-100 = 40.
dX1pcnt percent of 40 means 50 percent of 40 = 20.
=> Therefore the left position of the control will be set to 10(x1) + 20(deltaX*dX1pcnt/100) = 30.Where init_x1,...,init_y2 describe the initial position of the control, dlg_init_hi and dlg_init_wid is the initial and dlg_cur_wid and dlg_cur_hi the current size of the dialog itself (all client-rect).
- x1 = init_x1 + ( (dlg_cur_wid - dlg_init_wid) * dX1pcnt ) / 100
- x2 = init_x2 + ( (dlg_cur_wid - dlg_init_wid) * dX2pcnt ) / 100
- wid = init_wid + ( ( dlg_cur_wid - dlg_init_wid) * (dX2pcnt - dX1pcnt) ) / 100
- y1 = init_y1 + ( (dlg_cur_hi - dlg_init_hi) * dY1pcnt ) / 100
- y2 = init_y2 + ( (dlg_cur_hi - dlg_init_hi) * dY2pcnt ) / 100
- hi = init_hi + ( ( dlg_cur_hi - dlg_init_hi) * (dY2pcnt - dY1pcnt) ) / 100
Remarks:
Here's which values AddSzControl() will pass to AddSzControlEx() depending on the cdxCSizingDialog::Mode modeX value used (explanation for the x dimension; will be similar for y):
dX1pcnt dX2pcnt mdNone 0 0 mdRepos 100 100 mdResize 0 100 mdRelative 50 50 Important:
This function will not check the validity of the values you provide - for example if you set dX1pcnt to 100 and dX2pcnt to 0 and the dialog will be enlarged by more than the initial width of your control, the control will be tried to be sized to a negative width !!!!!
To ensure that your values never cause trouble, I recommend that dX1pcnt is always smaller or eqal to dX2pcnt (similar with dY1pcnt and dY2pcnt, of course :).See also:
OnInitDialog(), AddSzControlEx()
cdxCSizingDialog::RestoreWindowPosition():
cdxCSizingDialog::StoreWindowPosition():Synopsis:
bool RestoreWindowPosition(const CString & profileSec, bool withState = false);
bool StoreWindowPosition(const CString & profileSec);bool RestoreWindowPosition(UINT strId, bool withState = false);
bool StoreWindowPosition(UINT strId);
[public]
Task:
This pair of function might be used to store and load the position and size of the dialog window to allow the user keep its preferred positioning available between two sessions with your program.
As you may guess, StoreWindowPosition() saves the current window's coordinates and RestoreWindowPosition() is able to restore them, later.RestoreWindowPosition():
This function should be used from within your dialog's OnInitDialog() function.
Additionally, you should design your dialog without the WS_VISIBLE style and use CWnd::ShowWindow(SW_SHOW) to make it visible after calling this function (or you use withState = true).StoreWindowPosition():
This function is recommended be used from within OnOK(), OnCancel() and OnClose() to ensure the position is saved in all cases.Parameters:
- const CString & profileSec
A string that identifies the registry-section where the dialog's coordinates might be stored in.
Inside the section, some values like "Left", "Top" etc. will be used. Note that you may even define several sub-sections by providing a string like "Document_1\\Properties\\Window" - see CWinApp::GetProfileString() for further details on profile sections.- UINT strId
Allows you to use a resource string ID instead of profileSec.- bool withState
If true, ResoreWindowPosition() even restores the states of the window (visible, minimized, maximized etc.), otherwise not.Return values:
true if successful, false otherwise.See also:
OnInitDialog()cdxCSizingDialog::StretchWindow():
Synopsis:
void StretchWindow(UINT addSzByPcnt = DEF_STRETCH);
[public]
Task:
This function might be used to increase the window's size by a percentage value.Parameters:
- UINT addSzByPcnt
How many percent of the current widht [heigt] shall be added to the width [height] of the dialog ?
If you use 20, and the dialog is 100 pixels wide it will get 120 pixels wide.
The default is cdxCSizingDialog::DEF_STRETCH, which currently is 10.
A. Setting it up
- We need Visual C++ ready.
- Create a new Workspace with a "dialog-based application" called Test.
Among others, you will get the files TestDlg.h and TestDlg.cpp which describe your main dialog, CTestDlg which is associated to a dialog resource called IDD_TEST_DIALOG.- Compile this project the first time to generate the procompiled header file.
B. Installing the files and preparing the dialog class
- Copy the files cdxCSizingDialog.h and cdxCSizingDialog.cpp into your project's file directory.
- Open your Workspace-List "Files", select the treeview item Test files and use your right mouse-button to "Add files to project...".
- Select cdxCSizingDialog.h and cdxCSizingDialog.cpp.
- Open both TestDlg.h and TestDlg.cpp and open the "Search and replace"-dialog (Ctrl+h).
Replace the string CDialog by cdxCSizingDialog in both files.- Open the dialog's resource IDD_TEST_DIALOG, select the dialog and display its properties.
Switch to the Styles tab and change the border from Dialog frame to Resizing.- Compile your project and run the application - you can size your dialog and you see a little sizing icon in its lower right corner :)
Moreover, the dialog won't be sizable smaller than it has been in the resource editor.C. Moving buttons
- Now we make the OK and Cancel button stick to the right side of your dialog:
Open IDD_TEST_DIALOG in the resource editor (if you closed it before) and run the Class Wizard.- Select the Member variables tab and double-click on the IDOK item to add a member variable:
Name: m_wndOK
Category: Control
Type: CButton- Do the same with IDCANCEL (Name: m_wndCancel).
- Switch to the Message Maps tab and double-click OnInitDialog() in the lower list-view.
- Scroll down until you find the // TO DO comment.
- Past the comment, add the following lines to the function:
- AddSzXControl(m_wndOK,mdRepos);
AddSzXControl(m_wndCancel,mdRepos);- Compile and run your application.... fine, isn't it ??
D. More advanced resizing and repositioning
- Change the lines you just added into:
- AddSzControl(m_wndOK,mdResize,mdRelative);
AddSzControl(m_wndCancel,mdRepos,mdRelative); -- Note that its not AddSzXControl any more !!!- Run...
- What is it doing ?
Well, AddSzControl() (or AddSzXControl()/AddSzYControl()) takes the control and automatically repositiones it in the x and y direction (the first parameter of AddSzControl() describes what to do if the width of the dialog changes, the second what to do if the height changes).
That's what we needed, isn't it ?
Of course, in addition to AddSzControl() there is a much more powerful function AddSzControlEx() which allows more precise positioning and resizing of controls (AddSzControl() takes the types mdNone, mdRepos, mdResize and mdRelative).E. Changing sizing freedom
- Open CTestDlg::TestDlg. It should look like this:
- CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: cdxCSizingDialog(CTestDlg::IDD, pParent)
{
...
}
Now Change the second line into "cdxCSizingDialog(CTestDlg::IDD, pParent, fdHoriz, false)"- Run... now the dialog's size is only changeable horizontally and the little sizing-icon has gone.
F. Storing its position and size
- Open CTestApp::OnInitInstance(), scroll down and before the line that contains "CTestDlg dlg;", add the line:
- CWinApp::SetRegistryKey(_T("codex design")); -- You can of couse chooose another company than codex design :)
- Open CTestDlg::OnInitDialog() again and - past your previously added lines, add the following line:
- RestoreWindowPosition(_T("Main\\Window"));
- Use the Class Wizard (via the resource editor) to add a message handler for IDOK/MB_CLICKED.
- Open CTestDlg::OnOK() and before cdxCSizingDialog::OnOK() is called, add the line
- StoreWindowPosition(_T("Main\\Window"));
- Run your application, resize the window, click OK and restart it ...