Skip to main content
Email Password   helpLost your password?

Introduction

Recently I've been reading up on WTL, and I came across a rather interesting class that I hadn't seen mentioned anywhere, CDialogResize. Given the large number of MFC implementations of resizable dialogs, it's great that WTL provides its own, so you only have to learn one class and one way of specifying what gets resized. In this article, I will outline WTL's resizing support and provide a sample program to illustrate some of the features. You should already be familiar with WTL and how to install it. If you need help with this, there are articles on those subjects in the WTL section.

Using CDialogResize

The basics

As with many other WTL features, you begin by adding CDialogResize to the inheritance list of your dialog class. So, if you make a dialog-based app with the WTL AppWizard, you would add the line listed here in red:

class CMainDlg : public CAxDialogImpl<CMainDlg>,
                 public CDialogResize<CMainDlg>

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

The next step is to initialize the CDialogResize code in your dialog's OnInitDialog handler:

    LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        // Init the CDialogResize code

        DlgResize_Init();
    ...
    }

DlgResize_Init() has a few optional parameters, which I'll cover later.

Next, add an entry in the dialog's message map that passes sizing messages to CDialogResize:

    BEGIN_MSG_MAP(CMainDlg)
        MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
        ...
        CHAIN_MSG_MAP(CDialogResize<CMainDlg>)
    END_MSG_MAP()

Finally, add a new map to the dialog class that lists which controls in the dialog will be resized:

class CMainDlg : public CAxDialogImpl<CMainDlg>, public CDialogResize<CMainDlg>
{
...
public:
    BEGIN_DLGRESIZE_MAP(CMainDlg)
    END_DLGRESIZE_MAP()
...
};

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

Initializing CDialogResize

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

void CDialogResize::DlgResize_Init (
    bool bAddGripper = true,
    bool bUseMinTrackSize = true,
    DWORD dwForceStyle = WS_THICKFRAME | WS_CLIPCHILDREN );

The parameters are:

Setting up the resize map

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

    DLGRESIZE_CONTROL(ControlID, Flags)

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

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. I will cover this subject later.

Sample Project

The sample project included with this article is a simple dialog-based app that functions as a browser (using the WebBrowser ActiveX control). The control IDs are listed below; you should refer back to this diagram later when I discuss moving and resizing these controls.

 [Dlg control IDs - 17K]

The controls will move and size according to these rules:

The browser's OnInitDialog() function initializes CDialogResize like this:

    LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, 
                         BOOL& /*bHandled*/)
    {
        // Init the CDialogResize code

        DlgResize_Init();
        ...
    }

This uses the default parameters to DlgResize_Init(), which results in a size box being added. Also, the dialog cannot be sized smaller than its initial size. Here's what the dialog looks like on startup:

 [Main dialog - 28K] \

Here is the resize map, which lists the moving and sizing behavior for the controls. Note the new macros - BEGIN_DLGRESIZE_GROUP() and END_DLGRESIZE_GROUP() - that put the four browser control buttons into a resizing group.

    BEGIN_DLGRESIZE_MAP(CMainDlg)
        // Location edit box

        DLGRESIZE_CONTROL(IDC_URL, DLSZ_SIZE_X)

        // Go, Exit, About buttons

        DLGRESIZE_CONTROL(IDC_GO, DLSZ_MOVE_X)
        DLGRESIZE_CONTROL(IDC_EXIT, DLSZ_MOVE_X)
        DLGRESIZE_CONTROL(ID_APP_ABOUT, DLSZ_MOVE_X)

        // IE control buttons

        BEGIN_DLGRESIZE_GROUP()
            DLGRESIZE_CONTROL(IDC_BACK, DLSZ_SIZE_X)
            DLGRESIZE_CONTROL(IDC_FORWARD, DLSZ_SIZE_X)
            DLGRESIZE_CONTROL(IDC_STOP, DLSZ_SIZE_X)
            DLGRESIZE_CONTROL(IDC_REFRESH, DLSZ_SIZE_X)
        END_DLGRESIZE_GROUP()

        // WebBrowser control

        DLGRESIZE_CONTROL(IDC_BROWSER, DLSZ_SIZE_X|DLSZ_SIZE_Y)
    END_DLGRESIZE_MAP()

Here is the dialog after being resized:

 [Bigger dialog - 61K]

Notice how the edit box is wider, and the browser control is wider and taller. The behavior of the four grouped buttons is a bit tough to put into words, and the WTL code offers little guidance since there are few comments. But the basic idea is: imagine a bounding rectangle that surrounds all four buttons. That rectangle resizes like any other control, and all the buttons are sized proportionally so they remain within the bounding rectangle. If the buttons were to be moved, instead of resized, they would be positioned to always be evenly spaced apart. Note that all the controls in a group should have the same DLSZ_* flags to produce meaningful behavior.

Bugs and Problems with CDialogResize

So far, I've only seen two problems. One is that there seems to be an off-by-one bug somewhere, because the first time you resize the dialog, some of the controls shift the wrong direction by one pixel. The other, more serious problem, is a bug in the WTL AppWizard that is exposed when you add CDialogResize as a base class of your dialog. The AppWizard-generated code that displays the dialog looks like this:

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, 
                     LPTSTR lpstrCmdLine, int nCmdShow)
{
    // ...

    CMainDlg dlgMain;
    int nRet = dlgMain.DoModal();

    _Module.Term();
    ::CoUninitialize();

    return nRet;
}

The trouble with that is the CMainDlg destructor is called after _Module.Term(). This causes a crash in a release build if it is built with the _ATL_MIN_CRT symbol defined. The solution is to put the CMainDlg object in an enclosing block:

int nRet;

    {
    CMainDlg dlgMain;
    nRet = dlgMain.DoModal();
    }
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralWould not resize until I added WS_THICKFRAME style Pin
jaylb
10:01 29 Oct '07  
GeneralRe: Would not resize until I added WS_THICKFRAME style Pin
Michael Dunn
9:56 6 Jan '08  
GeneralRe: Would not resize until I added WS_THICKFRAME style Pin
Ason
21:52 14 Feb '08  
GeneralDoes new AppWizard fix CDialogResize bug ? Pin
Defenestration
14:20 2 May '06  
GeneralRe: Does new AppWizard fix CDialogResize bug ? Pin
Michael Dunn
16:37 2 May '06  
GeneralRe: Does new AppWizard fix CDialogResize bug ? Pin
Defenestration
16:52 2 May '06  
GeneralVery useful Pin
Anna-Jayne Metcalfe
5:36 18 Jan '05  
GeneralCentering controls? Pin
Maks Pyatkovskiy
18:13 9 Sep '04  
GeneralDynamically creating controls placing problem? Pin
Daredevil
8:19 21 Jun '04  
GeneralRe: Dynamically creating controls placing problem? Pin
Michael Dunn
9:49 21 Jun '04  
GeneralRe: Dynamically creating controls placing problem? Pin
Daredevil
3:05 22 Jun '04  
GeneralJust Show Scroll Bars? Pin
Rick Pingry
6:30 3 Apr '04  
GeneralWebBrowser control drawed out of dialog in multithreaded COM apps Pin
Krotow
0:04 9 Feb '04  
GeneralRe: WebBrowser control drawed out of dialog in multithreaded COM apps Pin
Krotow
5:12 16 Feb '04  
GeneralUpdate Problems Pin
labrador
5:17 27 Nov '03  
GeneralRe: Update Problems Pin
Michael Dunn
8:37 27 Nov '03  
GeneralCTabCtrl Pin
Bard
3:51 26 Sep '03  
GeneralRe: CTabCtrl Pin
Dr Bob.
6:53 11 May '06  
GeneralRe: CTabCtrl Pin
Fernando A. Gomez F.
17:55 20 Apr '08  
GeneralSetting initial dialog size Pin
Robert Edward Caldecott
23:58 28 Apr '03  
GeneralRe: Setting initial dialog size Pin
Eric Niemisto
4:45 9 May '03  
GeneralStrange XP behaviour Pin
Rodger Bernstein
5:10 23 Apr '03  
GeneralVery good! Pin
Adrian Bacaianu
4:01 14 Apr '03  
GeneralRe: Very good! Pin
joyjjjz
0:27 23 Sep '08  
GeneralExcellent article Pin
Robert Edward Caldecott
2:06 3 Mar '03  


Last Updated 20 Jul 2001 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009