Click here to Skip to main content
16,016,227 members
Articles / Programming Languages / C++

EasySize - Dialog Resizing in No Time!

Rate me:
Please Sign up or sign in to vote.
4.95/5 (213 votes)
23 Mar 20074 min read 1.2M   28K   290   185
An easy way to position controls in resizable dialogs or property pages using just a few macros
In this article, you will learn to design your dialog the way you want it to look in the resource editor, and then define how the controls will behave when the dialog is resized using one single macro for each control.

Image 1

Image 2

Image 3

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:

  1. #include EasySize.h to your stdafx.h (or put it in your include directory and #include <EasySize.h> , which I recommend).
  2. Add DECLARE_EASYSIZE anywhere in your class declaration:
    C++
    class CEasySizeDemoDlg : public CDialog
    {
    DECLARE_EASYSIZE
    ...
  3. Create an OnInitDialog handler if it doesn't already exist, and put this in the end of it: "INIT_EASYSIZE;":
    C++
    BOOL CEasySizeDemoDlg::OnInitDialog()
    {
        CDialog::OnInitDialog();
    ...    
        INIT_EASYSIZE;
        return TRUE; // return TRUE  unless you set the focus to a control
    } 
  4. Create an OnSize handler and add the UPDATE_EASYSIZE; macro to it:
    C++
    void CEasySizeDemoDlg::OnSize(UINT nType, int cx, int cy) 
    {
        CDialog::OnSize(nType, cx, cy);
        UPDATE_EASYSIZE;
    } 
  5. Optional - If you want your dialog to have a minimum size, then create an OnSizing handler and add the EASYSIZE_MINSIZE macro as below:
    C++
    void CEasySizeDemoDlg::OnSizing(UINT fwSide, LPRECT pRect) 
    {
        CDialog::OnSizing(fwSide, pRect);
        EASYSIZE_MINSIZE(280,250,fwSide,pRect);
    }
    //(in this example, 280 is the minimum width and 250 the 
    //minimum height we want our dialog to have)
  6. 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:
    C++
    BEGIN_EASYSIZE_MAP(class_name)
        ...
        EASYSIZE(control,left,top,right,bottom,options)
        ...
    END_EASYSIZE_MAP

    The map from the demo application looks like this:

    C++
    ...
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    BEGIN_EASYSIZE_MAP(CEasySizeDemoDlg)
        EASYSIZE(IDC_TITLE,ES_BORDER,ES_BORDER,
            ES_BORDER,ES_KEEPSIZE,ES_HCENTER)
        EASYSIZE(IDC_RADIO1,ES_BORDER,ES_BORDER,
            ES_KEEPSIZE,ES_KEEPSIZE,0)
        EASYSIZE(IDC_RADIO2,ES_BORDER,ES_BORDER,
            ES_KEEPSIZE,ES_KEEPSIZE,0)
        EASYSIZE(IDC_CONTENT,ES_BORDER,ES_BORDER,
            ES_BORDER,ES_BORDER,0)
        EASYSIZE(IDC_STATUSFRAME,ES_BORDER,ES_KEEPSIZE,
            ES_BORDER,ES_BORDER,0)
        EASYSIZE(IDC_STATUS,ES_BORDER,ES_KEEPSIZE,
            ES_BORDER,ES_BORDER,0)
        EASYSIZE(IDOK,ES_KEEPSIZE,ES_KEEPSIZE,
            ES_BORDER,ES_BORDER,0)
        EASYSIZE(IDCANCEL,ES_KEEPSIZE,ES_KEEPSIZE,
            ES_BORDER,ES_BORDER,0)
        EASYSIZE(IDC_MYICON1,ES_BORDER,IDC_RADIO2,IDC_CONTENT,
            IDC_STATUSFRAME,ES_HCENTER|ES_VCENTER)
        EASYSIZE(IDC_MYICON2,ES_BORDER,ES_BORDER,IDC_TITLE,
            ES_KEEPSIZE,ES_HCENTER)
    END_EASYSIZE_MAP
    
    ///////////////////////////////////////////////////////////////
    // CEasySizeDemoDlg message handlers
    ...

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:

C++
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 your 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 cannot 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 that you will not even notice it.

History

  • 11th December, 2001: Initial version

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.

A list of licenses authors might use can be found here.


Written By
Engineer Nokia
Denmark Denmark
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

 
GeneralNeed help! Pin
Arrin27-Oct-10 0:31
Arrin27-Oct-10 0:31 
GeneralTwo controls side by side Pin
Jonnster13-Oct-10 5:37
Jonnster13-Oct-10 5:37 
GeneralRe: Two controls side by side Pin
walster25-Jul-11 6:54
walster25-Jul-11 6:54 
Questioncan it work at CFormView? Pin
batsword8-Sep-10 21:30
batsword8-Sep-10 21:30 
AnswerRe: can it work at CFormView? Pin
jj0021-Sep-10 11:29
jj0021-Sep-10 11:29 
GeneralRe: can it work at CFormView? Pin
batsword11-Nov-10 15:11
batsword11-Nov-10 15:11 
GeneralRe: can it work at CFormView? Pin
magicpapacy24-Dec-10 0:59
magicpapacy24-Dec-10 0:59 
AnswerRe: can it work at CFormView? Pin
michaelsoros13-Jul-13 1:44
michaelsoros13-Jul-13 1:44 
when the view is being created, a WM_SIZE message will be sent; however at that time the window handle has yet to be initialized. Test the window handle using a "if" clause.
GeneralMy vote of 5 Pin
jiejue19862-Aug-10 16:50
jiejue19862-Aug-10 16:50 
GeneralMy vote of 5 Pin
xiongmao3471210-Jul-10 17:59
xiongmao3471210-Jul-10 17:59 
Generalvery brilliant Pin
Anu Koshy27-May-10 0:15
Anu Koshy27-May-10 0:15 
QuestionHow to set all controls is proportional to the size of dialog Pin
PeterHo38626-May-10 22:05
PeterHo38626-May-10 22:05 
GeneralUpgrade to 2008 Pin
Sara Novick17-Feb-10 0:09
Sara Novick17-Feb-10 0:09 
GeneralCFormView Resolution Pin
a_kiani13-Jul-09 23:49
a_kiani13-Jul-09 23:49 
GeneralRe: CFormView Resolution Pin
brightown9-Aug-09 2:58
brightown9-Aug-09 2:58 
Generalthanks for sharing. Pin
Sameerkumar Namdeo9-Jul-09 0:58
Sameerkumar Namdeo9-Jul-09 0:58 
GeneralControls Disappear Pin
jj0029-Jun-09 11:57
jj0029-Jun-09 11:57 
GeneralRe: Controls Disappear Pin
jj006-Jul-09 6:32
jj006-Jul-09 6:32 
GeneralAdjusting the size of column in List Control Pin
John Pinto16-Jun-09 2:19
John Pinto16-Jun-09 2:19 
GeneralExcellent Pin
Milan121220-May-09 7:13
Milan121220-May-09 7:13 
Questionhow to resize child dialogs in the tab control Pin
comberti14-Apr-09 23:20
comberti14-Apr-09 23:20 
AnswerRe: how to resize child dialogs in the tab control Pin
bolonglx28-Aug-10 1:12
bolonglx28-Aug-10 1:12 
GeneralRe: how to resize child dialogs in the tab control Pin
jamesprite14-Feb-12 22:50
professionaljamesprite14-Feb-12 22:50 
QuestionUpper Left resize not working Pin
Mitch Faatz3-Dec-08 12:24
Mitch Faatz3-Dec-08 12:24 
QuestionWhy I can not do it? Pin
tunnel11516-Oct-08 3:47
tunnel11516-Oct-08 3:47 

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.