Introduction

Have you ever thought of how annoying it actually was to spend a lot of time
doing a basic GUI for your simple applications instead of focusing on the actual
'content'? Take for example a resizing dialog or property page. You need to write code
for each control that will tell it where to go when the thing is resized, and this can take up a lot of time. Now I know that I'm not the first one to give a solution to this
(CResizableDialog), but this article is on my approach.

Description

Basically, all you need to do is design your dialog the way you want it to
look in the resource editor (don't forget to make it resizable), and then define how the
controls will behave when the dialog is resized using one single macro for each control.

Usage

Note that all this works exactly the same way with both CDialog and
CPropertyPage

#include EasySize.h to your stdafx.h
(or put it in your include directory and
#include <EasySize.h> , which I recommend)

Add DECLARE_EASYSIZE anywhere in your class declaration:

class CEasySizeDemoDlg : public CDialog
{
DECLARE_EASYSIZE
...

Create an OnInitDialog handler if it doesn't already exist,
and put this in the end of it: "INIT_EASYSIZE;" :

BOOL CEasySizeDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...
INIT_EASYSIZE;
return TRUE; // return TRUE unless you set the focus to a control
}

Now you have to create the "EasySize Map" (or whatever you want to call it) in which you will specify
the behavior of each dialog item. It can be placed anywhere inside your class implementation.
The map looks like this:

Looks confusing? It's not once you get the point (and I know I'm not good at explaining it) Read on.

EASYSIZE Macro

The EASYSIZE macro is used in the EasySize Map
to specify what behavior your controls will have on dialog resize.
It looks like this:

EASYSIZE(control,left,top,right,bottom,options)

control is the ID of the dialog item you want
re-positioned (which will be referred to as the 'current control' further on).

left, top, right and bottom can be either the ID of
another control in the dialog (not the current control), or one of the
special values, ES_BORDER and ES_KEEPSIZE.

Basically, if you specify an ID, the distance from the current control and
the item designated by the ID will remain the same when the dialog is
resized: The current control will 'stick' to the other item. ES_BORDER
works the same way as if you had specified a control ID, except that it's the distance
between the current control and the dialog border that will be kept constant.
Specifying ES_KEEPSIZE in, let's say left, will keep
the width of the current control the same, and will make the current control
right-aligned to whatever you specified in right.
The width (or height, if you specified ES_KEEPSIZE in
top or bottom) of the current control will
always remain what it is in the dialog resource. (I know this explanation sucks,
but look at the demo application if you are confused or post you question in the board below).
Obviously ES_KEEPSIZE cannot be specified in both "left and right" or "top and bottom".

options can be a combination of ES_HCENTER,
ES_VCENTER and 0 (use 0
if you don't want any of the other).
ES_HCENTER horizontally centers the control between
the two items specified in left and right
(both of those can not be ES_KEEPSIZE!). The width of the
current control will always remain the same as in the dialog resource.
ES_VCENTER works the same way, but for vertical centering
(using top and bottom, and where the height will remain constant).

Conclusion

Well I hope you figured out how this works, because it really can make your life easier.
Note that using these macros will probably make your compiled code slightly
bigger and slower than if you had coded the resizing routines manually, but in
most cases the change is so small not even you will notice.

Last Update - Just corrected a few typos.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

My programming experience started a long time ago in QBasic (on a 25MHz 486).I'm now mainly using Java, C++, C, MFC, Perl and PHP, but have used quite a number of other languages as well for various projects.

Comments and Discussions

AliRafiee's solution leaves "dirt" when user moves borders back and forth during resizing, and does not eliminate flickering on tabs. My solution is to also put UPDATE_EASYSIZE in the OnExitSizeMove handler and to use a Boolean flag, say m_bSizing_es, that's set to FALSE in the OnInitDialog handler, set to TRUE in the OnSizing handler, and set to FALSE in the OnExitSizeMove handler. In the OnSize handler, condition UPDATE_EASYSIZE like so:

if (m_bSizing_es) UPDATE_EASYSIZE;. These could be incorporated into the macros.

Logic here is to postpose UPDATE_EASYSIZE until user finishes resizing, but to still trigger UPDATE_EASYSIZE when the dialog is maximized.

Very good, but the final explanation that is the most interesting part is a bit inconsistent... you should describe some specific example such as: no resizing aligned bottom right, no resizing.. , resizing with control 1, and so on...thanks anyway, very good.

I can use it to change the size of control.i want to realize the maximization of the dialog box at the same time,however, i can't do it.Once i realize the maximization of the dialog box, all controls are missing.The whole layout is in a complete mess.what should i do?please help me! Thank you very much

We are facing an issue while using easy size api, which we want to share with you. We are using MFC for dialog based GUI in c++ and inserting multiple controls on the GUI.

We have placed four controls, i.e. First one would be alligned Left Top, Second one will be in front of First but aligned Top Right, Third one will be below the first control an aligned left and fourth control would be placed below the Second control aligned right. Each of them are equally spaced with each other.

The requirement is to re size the GUI at run time in such a way that all the controls are also re sized and spacing between them should remain consistent.

We were trying to do so but the controls were overlapping in our case.

We would request you guide us at code level, as to how we should handle such a scenario and how the parameters should be set that equal spacing and resizing of controls are maintained.

I am saving the size of my dialog when I close it. So when I re-open it I want to retain the last size it was sized to. When I re-open the dialog the size is retained but it is not updating the controls inside my dialog. How can I make it do this?

Thank God let me meet EasySize.h!It is a very good job! But I have met a fatal error:I include EasySize.h to my project as the article says,but I am told by the computer that: e:\try\first\stdafx.h(20) : fatal error C1083: Cannot open include file: 'EasySize.h': No such file or directory Being a green hand on using MFC I don't kown how to resolve it .Maybe it is very easy,but difficult for me!Waitting For you quick answer! Thank you!

Hi,for first thanks for this article and i try to add two CEdit controls do dialog but its only one is resized! :(

IDC_EDIT1 IDC_EDIT2

here is my map:

BEGIN_EASYSIZE_MAP(CsizedemoDlg)
EASYSIZE(IDC_EDIT1,ES_BORDER,ES_BORDER,IDC_EDIT2,ES_BORDER,0) // IDC_EDIT2 is on the right side from IDC_EDIT1
EASYSIZE(IDC_EDIT2,IDC_EDIT1,ES_BORDER,ES_BORDER,ES_BORDER,0)
END_EASYSIZE_MAP

but ony one control is resized, i dont understand how to use this params! :(

Is it possible to have 2 controls side by side where the two resize themselves so they resize to the width of the dialog and always "meet in center"? If you see what I mean. So the right side of the left control and the left side of the right control are always in the middle of the dialog (minus a small space between them).

Imagine my surprise when I went to this site this morning trying to get a CFormView to work and find your message front and center. If you browse through the comments you'll find a post by "AliRafiee" titled "FormView Solution".

I followed his instructions (not the one about the window opened at max) and they seemed to work better than some of the other suggestions. I'm not sure if this code is hosted anywhere or if a permanent fix can be found, but I'm still finding this it useful.

I have been using this EasySize and it is great in Visual 6.0. I had to upgrade one of my projects to Visual Studio C++ 2008. I couldn't get the code to compile until I commented all the EasySize code. Can I use EasySize in 2008?

I think I could solve the problem of using EasySize in CFormView classes.By experiment I detected that problems occur in case the size of child view is smaller than Parent Frame.Therefore, you can solve the problem by increasing size of parent frame so that its dimensions are greater than that of child view.You can do it in PreCreateWindow method of CMainFrame class.Hope this helps

I've looked through the documentation and downloaded and ran the sample. For some reason when I use this code in my project all the controls just disappear as soon as I try to resize the dialog. The sample/demo works fine. I'm using VS 2005.

I'd post some code, but it looks very similar to the sample code. There are a couple differences between my project and the demo, but I'm not sure any of them really matter:

I include "easysize.h" in my class header instead of StdAfx.h

My Dialog is a member of another class (CView), and I'm using a multi-doc configuration with MFC

I'm using a few controls from Ultimate Toolbox (also on this site)

My only guesses are that it's somehow hiding all the controls on resize, or it's is using the a parent frame as it's reference point. I'm not the biggest C++ guru, so I'm not sure how I would determine what is going wrong.