Click here to Skip to main content
Click here to Skip to main content

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

, 20 Oct 2005
Rate this:
Please Sign up or sign in to vote.
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 <span class="code-keyword"><ResizableLib.h>
</span>

// 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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alexander D. Alexeev
Software Developer (Senior)
Russian Federation Russian Federation
No Biography provided

Comments and Discussions

 
GeneralDownload links are not working, PinmemberIgor Vigdorchik21-Feb-05 4:20 
GeneralRe: Download links are not working, PinmemberAlexTheBoss21-Feb-05 4:32 
GeneralRe: Download links are not working, PinmemberIgor Vigdorchik21-Feb-05 4:40 
GeneralCDialogResize PinmemberIgor Vigdorchik21-Feb-05 4:17 
GeneralRe: CDialogResize PinmemberAlexTheBoss21-Feb-05 4:23 
GeneralRe: CDialogResize PinmemberIgor Vigdorchik21-Feb-05 4:49 
GeneralRe: CDialogResize PinmemberAlexTheBoss21-Feb-05 21:29 
GeneralRe: CDialogResize PinmemberIgor Vigdorchik22-Feb-05 3:01 
GeneralMessina NOT Mescina PinmemberPiccinano20-Feb-05 21:38 
GeneralRe: Messina NOT Mescina PinmemberAlexTheBoss20-Feb-05 22:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140718.1 | Last Updated 20 Oct 2005
Article Copyright 2005 by Alexander D. Alexeev
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid