Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Simple and more powerful resizable dialog

0.00/5 (No votes)
26 Sep 2004 1  
A simple resizable dialog which resizes in NONE, RESIZE, REPOS, RELATIVE, ZOOM, DELTA_ZOOM mode and behaves differently in different directions(left, top, right, bottom)

The Sample Dialog

  1. Original Dialog
  2. Dialog after sized bottom-right
  3. 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:

  1. 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.
  2. Zoom control as dialog is zoomed.
  3. 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

  1. Add ResizeDlg.cpp and ResizeDlg.h to your project or makefile;
  2. Add "#Include ResizeDlg.h" to stdafx.h file or your dialog header file;
  3. 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.
  4. 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.

//

// the minimal work you have to do in your OnInitDialog handler.

//

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.
    //

    // in x direction, where deltaX is 

    // dialog's changed-width.

    //

    ctrlRect.right += deltaX;
CST_REPOS reposition controls as much as dialog's change-size in this direction.
    //

    // in x direction, where deltaX is dialog's 

    // changed-width.

    //

    ctrlRect.left += deltaX;
    ctrlRect.right += deltaX;
CST_RELATIVE reposition controls with user-defined proportion (make controls always at the same proportional position in dialog).
    //

    // in x direction, where m_xRatio is 

    // user-defined proportion

    // pnRect is dialog's new ClientRect

    //

    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
    //

    // in x direction, where pnRect is 

    // dialog's new ClientRect.

    // pR0 is dialog's original ClientRect

    // (NOT previous width).

    //

    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.
    //

    // in x direction, where deltaX0 is 

    // the dialog's chenged-width

    // compared with its original width(NOT 

    // previous width, otherwise error 

    // will mess the result).

    // m_xRatio is user defined X-reposition 

    // proportion and

    // m_cxRatio is user defined X-size proportion.

    //

    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

  1. keep a edit control resize horizontally as dialog sized.
    AddControl(edit-ID, CST_RESIZE, CST_RESIZE,
     CST_NONE, CST_NONE, 1);
  2. keep a top-right button at the same top-right position.
    AddControl(button-ID, CST_REPOS, CST_REPOS,
     CST_NONE, CST_NONE, 1);
  3. 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);
  4. 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);
  5. 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

  1. 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.
  2. Do not set flicker-free for group-controls in dialog (set bFlickerFree to 0 in calling AddControl).

History

  1. Sep 26, 2004 -Initial public release.

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