Click here to Skip to main content
15,886,063 members
Articles / Desktop Programming / MFC
Article

Using WTL's Built-in Dialog Resizing Class for MFC

Rate me:
Please Sign up or sign in to vote.
4.78/5 (10 votes)
30 Sep 2011CPOL3 min read 19.7K   1.5K   14   1
WTL programming for MFC developers - resizing dialogs & formviews
img_1.JPG

Introduction

Once, I wanted to write resizing dialog in the program written for MFC. Having seen that is ready on this theme, I found the CDialogResize class. The class is good and easy to use, but is written for WTL. I tried to write it in WTL, basically it is quite good, but with MFC it is more habitual. So I decided to copy CDialogResize under MFC. The name didn't change, for my classes I use namespace dimrad.

Adding CDialogResize

You begin by adding CDialogResize to the inheritance list of your dialog class.

C++
// CMFCWTLDLGDlg dialog 
class CMFCWTLDLGDlg : public CDialog, public dimrad::CDialogResize<CMFCWTLDLGDlg>

CDialogResize is declared in mfcdialogresize.h, so add that header to your includes if it isn't there already.

Next, add a new resize map to the dialog class that lists which controls in the dialog will be resized.

C++
#include "mfcdialogresize.h" 

// CMFCWTLDLGDlg dialog 
class CMFCWTLDLGDlg : public CDialog, public dimrad::CDialogResize<CMFCWTLDLGDlg>
{
...
// Resizing map 
	public: 
	BEGIN_DLGRESIZE_MAP(CMFCWTLDLGDlg)
	...
	END_DLGRESIZE_MAP()
...
}

I'll describe how to fill in this map in the "Setting up the resize map" section.

Next, overload function OnInitDialog(), if you haven't done it already. And add function OnSize() to process WM_SIZE message.

C++
#include "mfcdialogresize.h" 

// CMFCWTLDLGDlg dialog 
class CMFCWTLDLGDlg : public CDialog, public dimrad::CDialogResize<CMFCWTLDLGDlg>
{
...
// Resizing map 
public: 
	BEGIN_DLGRESIZE_MAP(CMFCWTLDLGDlg)
	...
	END_DLGRESIZE_MAP()
...

// Overloads 
	virtual BOOL OnInitDialog();
...
// Generated message map functions  
	DECLARE_MESSAGE_MAP()
...
	afx_msg LRESULT OnSize(WPARAM wParam, LPARAM lParam);
...
}

That's all for your dialog header file. Now let's open the implementation file.

First add a new message map entry for WM_SIZE message.

C++
...
BEGIN_MESSAGE_MAP(CMFCWTLDLGDlg, CDialog)
	...
	ON_MESSAGE(WM_SIZE, &OnSize)
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP()
...

Next, add a call of DlgResize_Init() function to OnInitDialog() function definition.

C++
...
BOOL CMFCWTLDLGDlg::OnInitDialog()
{ 
	CDialog::OnInitDialog();
	...
	// TODO: Add extra initialization here 
	DlgResize_Init();
	return TRUE; // return TRUE unless you set the focus to a control
 }
...

And at last, add an implementation of OnSize() function.

C++
...
LRESULT CMFCWTLDLGDlg::OnSize(WPARAM wParam, LPARAM lParam)
{
	BOOL bHandled = FALSE;
	return dimrad::CDialogResize<CMFCWTLDLGDlg>::OnSize
			(WM_SIZE, wParam, lParam, bHandled);
}
...

Ok the class is ready. It does nothing, but you can use it many times from this point. Usually it is necessary to change only a class name also in a template CDialogResize<>.

Initializing CDialogResize

CDialogResize is initialized by calling DlgResize_Init(). Its prototype is:

C++
void DlgResize_Init(
	bool bAddGripper = true,
	bool bUseMinTrackSize = true,
	DWORD dwForceStyle = WS_CLIPCHILDREN,
	bool bUseScrollView = false,
	SIZE *pszMin = NULL,
	int client_cx = 0,
	int client_cy = 0); 		

The parameters are:

  • bAddGripper: This controls whether CDialogResize adds a size box to the bottom-right corner of the dialog. Pass true to add the size box, or false to not add it.
  • bUseMinTrackSize: This parameter controls whether CDialogResize restricts the minimum size of the dialog. If you pass true, the dialog is not allowed to be sized smaller than its initial size (as stored in the resource file). Pass false if you don't want to restrict the dialog's minimum size.
  • dwForceStyle: Specifies window styles to apply to the dialog. The default value is usually sufficient.
  • bUseScrollView: Pass true - for scrolling in views, such as CFormView.
  • pszMin: Specifies window minimal size.
  • client_cx: Specifies space size from left.
  • client_cy: Specifies space size from top. Used when dialog has a menu or another unresizable window.

Setting Up the Resize Map

The dialog resize map tells CDialogResize which controls to move or size. An entry looks like this:

C++
DLGRESIZE_CONTROL(ControlID, Flags)		

ControlID is the ID of the dialog control. The possible flags and their meanings are:

  • DLSZ_SIZE_X: Resize the width of the control as the dialog resizes horizontally.
  • DLSZ_SIZE_Y: Resize the height of the control as the dialog resizes vertically.
  • DLSZ_MOVE_X: Move the control horizontally as the dialog resizes horizontally.
  • DLSZ_MOVE_Y: Move the control vertically as the dialog resizes vertically.
  • DLSZ_REPAINT: Invalidate the control after every move/resize so it repaints every time.

Note that you cannot move and size a control in the same dimension. If you specify, say DLSZ_MOVE_X and DLSZ_SIZE_X together, the size flag is ignored.

You can also group controls together so that they move and size proportionally to each other.

C++
BEGIN_DLGRESIZE_GROUP()
...
END_DLGRESIZE_GROUP()

Features of resize map:

  • The control can meet more than once.
  • The control not included in group moves rather its current position.
  • The control included in group is resized taking into account its initial position, but without a current position.
  • It is possible to include the control in several groups. Though its position will be affected only by the last group, this reception allows to influence with difficulty others controls. But it is not necessary to forget about sense of proportion.
  • There cannot be enclosed groups of controls.
Resize map for sample project:

C++
// Resizing map 
public: 
BEGIN_DLGRESIZE_MAP(CMFCWTLDLGDlg)
	DLGRESIZE_CONTROL(IDC_TAB1, DLSZ_SIZE_X | DLSZ_SIZE_Y)
	DLGRESIZE_CONTROL(IDC_BUTTON1, DLSZ_MOVE_X)
	DLGRESIZE_CONTROL(IDC_BUTTON2, DLSZ_MOVE_X)
	DLGRESIZE_CONTROL(IDC_BUTTON3, DLSZ_MOVE_X)
	DLGRESIZE_CONTROL(IDC_STATIC1, DLSZ_MOVE_Y)
	DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X | DLSZ_MOVE_Y)
	DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y) 
END_DLGRESIZE_MAP()

Reference

I have taken some information from the article, Using WTL's Built-in Dialog Resizing Class because it was the basis of my work.

History

  • 30th September, 2011: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionthe dlgsize is not right Pin
mrx_jims6-Jun-13 17:12
mrx_jims6-Jun-13 17:12 
In The mfcdialogresize.h at line 188

I think tha code modify can prefer
because when resize dlg, can be right most

C#
//pT->GetClientRect(&rectDlg);
pT->GetWindowRect(&rectDlg);

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.