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

Resizing Dialogs in WTL: Port of Paolo Messina's MFC ResizableLib.

0.00/5 (No votes)
20 Oct 2005 2  
An article on how to make resizable dialogs with WTL.

Introduction

First, a few words about the window resizing problem. For example, we have a dialog window with some child controls in it (fig.1).

Fig.1

And we want the following behavior: when the dialog size is changed some of the child controls must change their sizes too. In this example the GroupBox labeled "Static" must have the same spaces from left, top, right and bottom edges of the window and the ListBox must have the same behavior as the GroupBox. "OK" button must stay at the left-bottom corner of the window, "About..." button must stay at the right-bottom corner and the "Cancel" button must stay at the center of the window. Resized dialog is shown in the next picture (fig.2).

Fig.2

There is no simple way to make child controls resize as described above. The most simple method is to handle the WM_SIZE message and setup every control position in the message handler. This method is good, when the count of controls is not so big. If we have a more complicated dialog then we need some standard methods for description of the controls reposition behavior.

Some time ago I found a perfect library for MFC that helps to design resizable dialog that has no flickering and a very simple description of resize behavior. The library is ResizableLib. It was created by Paolo Messina and you can find it here. I decided to make a port of this library on WTL and here is the result of this work.

WTL also has the implementation of resizing: CDialogResize<> template, but ResizableLib has more features:

  • Anti-flickering support for most part of the controls.
  • Support for MinMaxInfo for any window.
  • Support for Save/Restore window size and position.
  • Support for resizable property sheets and wizards.
  • Resizing mechanism can be attached to any window (not just dialogs).
  • Simple control behavior description.
  • Minimum code needed to make the dialog resizable.

Library content

Files included in this library.
ResizableDialog.h

Implementation of resizable dialog.

ResizableGrip.h Implementation of resizable grip control and template for windows that own grip.
ResizableLayout.h Resize layout manager implementation. Handles resizing, child clipping and so on.
ResizableMinMax.h Minimum and maximum window size support.
ResizablePage.h Implementation of resizable property page.
ResizableSheet.h Implementation of resizable property sheet.
ResizableState.h Support for size and position store.
ResizableMsgSupport.h For custom controls we can use messages to determine how it must be clipped and refreshed.
ResizableVersion.h Support file for correctly determining the Windows and shell versions.
RegisteredMsg.h Support file for user registered messages.
ResizableLib.h This file includes all of the above.

Using the code

If you want to use WTL ResizableLib you must complete the following steps:

  • Extract library to a folder named ResizableLib or any other name.
  • In your project add library path to include search paths.
  • In your stdafx.h insert #include "ResizableLib.h".
  • See the next sample of this article to make resizing simple.

There is a small code sample which uses ResizableLib with WTL dialog presented above:

#pragma once
#include <ResizableLib.h>


// MainDlg class

class CMainDlg:
  public CResizableDialogImpl<CMainDlg>,
// Your inherited classes

  public CUpdateUI<CMainDlg>,
  public CMessageFilter, 
  public CIdleHandler
{
  typedef CResizableDialogImpl<CMainDlg> baseClass;
public:
  enum { IDD = IDD_MAINDLG };

  virtual BOOL PreTranslateMessage(MSG* pMsg);
  virtual BOOL OnIdle();

  BEGIN_UPDATE_UI_MAP(CMainDlg)
  END_UPDATE_UI_MAP()

  BEGIN_MSG_MAP(CMainDlg)
    CHAIN_MSG_MAP(baseClass) // First hadle messages 

                             // in base class message map

    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
    COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
    COMMAND_ID_HANDLER(IDOK, OnOK)
    COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
  END_MSG_MAP()

  LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, 
             LPARAM /*lParam*/, BOOL& /*bHandled*/);
  LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, 
              HWND /*hWndCtl*/, BOOL& /*bHandled*/);
  LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, 
              HWND /*hWndCtl*/, BOOL& /*bHandled*/);
  LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, 
             HWND /*hWndCtl*/, BOOL& /*bHandled*/);
  // Your methods here

};

In the implementation of OnInitDialog you must add the following lines:

// GrouBox behavior

AddAnchor(IDC_S1, TOP_LEFT, BOTTOM_RIGHT);
// ListBox behavior

AddAnchor(IDC_LIST1, TOP_LEFT, BOTTOM_RIGHT);
// OK Button behavior

AddAnchor(IDOK, BOTTOM_LEFT);
// Cancel Button behavior

AddAnchor(IDCANCEL, BOTTOM_CENTER);
// About Button behavior

AddAnchor(ID_APP_ABOUT, BOTTOM_RIGHT);

The last step: if you want to save and restore the dialog size and position you must add the following line:

EnableSaveRestore(HKEY_CURRENT_USER, "Software\\AlexTheBoss\\Settings\\", 
                                             PLACEMENT_ENT, "MainDlg");
// HKEY_CURRENT_USER: registry root key
// Software\\AlexTheBoss\\Settings\\: your application registry key
// PLACEMENT_ENT: define for windowplacment subkey
// MainDlg: your dialog name for storing placement in registry

That's all you need to make your dialog resizable!

Limitations and problems

  • Due to WTL architecture you must manually set WS_THICKFRAME in your dialog template.
  • Groupboxes still flicker with WinXP themed dialogs.
  • With XP themes enabled and if the themed window frame is not rectangle then you can see the invalid window frame while changing the size.

Downloads

To build the demo project create a new folder and extract both the archives in that folder, then open ResizeTest.sln and then build it. Simple demo project contains a very simple dialog resizing sample that you can see in the screenshots above.

In full demo you can see the most powerful features of ResizableLib:

  • Resizable dialog with proportional resizing.
  • Resizable property sheet and wizard.
  • Splitter window with dialog in its right pane.
  • Mainframe contains load and save for window placement.
  • Mainframe handles MinMaxInfo.

History

  • 18th February 2005
    • Initial public release.
  • 24th February 2005
    • WM_NCCALCSIZE handle in CResizableLayout<T> bug fixed.
    • New big sample added.
    • Article updated.

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