Easy Dialog, Property Sheet and Window Resizing

Environment: VC6, NT4, Win9x, WinXP

Dialog sizer

Code homepage - This is where updates will be found as and when they become available.

Motivation

All too often we restrict the size of dialogs just so they fit onto smaller screens - this penalises those of us with larger monitors for no apparent reason. Sizeable windows, dialogs and property sheets can end much of the frustration for your users and provide a more pleasing and flexible UI.

I've seen many dialog resizing projects on codeguru.com and codeproject.com. They all seem to suffer from the same fate: They are complex to integrate into your current project, they require MFC projects to add control objects for every control or they are plain clumsy to use - or a combination of all three.

If you use MFC then they often require you to change your class hierarchy, deriving from their classes instead of your own custom classes. This is painful and is easy to avoid.

It's my aim to correct this, to provide a simple API that hopefully can be built upon to create clean and simple window manager.

What's it do

With a single function call you can make your dialogs, windows and property sheets resizable. This is complete with sizing and moving controls as the user resizes the window. DialogSizer optionally saves and restores the window position and size too.

DialogSizer will optionally add a sizing gripper to your windows giving your users valuable feedback about what can be resized and what can't. You can even optionally specify the largest size of your window.

Example

The ZIP file contains two contrived examples, one for Win32 API and one for MFC. The MFC version demonstrates adding the library to a dialog, a property sheet and a view. The API example demonstrates just the dialog but the conventions remain the same for API and MFC (or any language I guess).

Let's look at an example, here's a simple dialog that is not resizable:


And here it is resizable:

And here is the simple code that makes it possible:

DIALOG_SIZER_START( sz )
  DIALOG_SIZER_ENTRY( IDOK, DS_MoveX )
  DIALOG_SIZER_ENTRY( IDCANCEL, DS_MoveX )
  DIALOG_SIZER_ENTRY( IDC_LIST1, DS_SizeX )
  DIALOG_SIZER_ENTRY( IDC_LIST2, DS_SizeY )
  DIALOG_SIZER_ENTRY( IDC_LIST3, DS_SizeY | DS_SizeX )
  DIALOG_SIZER_ENTRY( IDC_BUTTON1, DS_MoveY )
  DIALOG_SIZER_ENTRY( IDC_BUTTON2, DS_MoveY )
  DIALOG_SIZER_ENTRY( IDC_EXPAND_SHRINK, DS_MoveX )
DIALOG_SIZER_END()
(void)DialogSizer_Set( hDlg, 
         sz, 
         TRUE, 
         HKEY_CURRENT_USER, 
         _T("software\\GipsySoft.com\\DialogSizer\\ApiTest\\Main"), 
         NULL );

API

Docs are a pain but I'll do my best. The library is essentially very simple to use but to avoid confusion I've provided some basic docs.

DIALOG_SIZER_START( name )

Parameters
name
Name of the structure

This is used to declare the begining of the description of how sizing should take place, you'll give this to the library

DIALOG_SIZER_END

This is used to declare the end of the description of how sizing should take place.

extern "C" BOOL DialogSizer_Set( HWND hwnd, const DialogSizerSizingItem *psd, BOOL bShowSizingGrip, HKEY hkRootSave, LPCTSTR pcszName, SIZE *psizeMax );

Parameters
hwnd
The window handle to set as sizable
pds
pointer to the sizing structure as built up by the macros.
bShowSizingGrip
TRUE if the sizing grip should be displayed, FALSE if not.
hkRootSave
Registry root key to be used to store/retrieve the window size/position information in the registry. Can be NULL
pcszName
Name that will be used to store/retrieve the window size/position information in the registry. Can be NULL only if hkRootSave is also NULL.
psizeMax
Pointer to the maximum size of window, NULL if you don't wish to use a maximum size.
Return value

FALSE if something failed, non-zero if everything went well

This is used to pass the sizing desciption to the library. DialogSizer_Set basically takes a copy of your description (so it can go out of scope) and then subclasses your window. It then takes care of all WM_SIZE messages (and a couple of others) to ensure correct behaviour.

DIALOG_SIZER_ENTRY( controlID, flags )

Parameters
controlID
the ID of the control
flasg
The flags that describe how a control is sized.

This is the interesting bit. Using a combination of simple flags we can control how a control is moved and resized.

Flags
DS_MoveX
Add this flag to move a control in the X axis when the window is horizontally sized
DS_MoveY
Add this flag to move a control in the Y axis when the window is vertically sized
DS_SizeX
Add this flag to size a control in the X axis when the window is horizontally sized
DS_SizeY
Add this flag to move a control in the Y axis when the window is vertically sized

Say you only have an edit box on a dialog and nothing else. Then you would use flags of DS_SizeX | DS_SizeY.

Licence

This software is provided 'as-is', without any express or implied warranty.

In no event will the author be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is requested but not required.
  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. Altered source is encouraged to be submitted back to the original author so it can be shared with the community. Please share your changes.
  3. This notice may not be removed or altered from any source distribution.

Source code notes

The bulk of the functionality is in the single source file DialogSizer_Set.cpp. You should feel free to add this source file to your core utilities to better integrate it into your system builds.

The source is built using level 4 warnings and warnings as errors. It will compile as-is with unicode.

I use the directory structure outlined here. You don't need to follow this but it's served me well for many years and I've had zero problems with it. All my stuff goes into this structure

Share any modifications you make with me so I can share them with others...help make this a better tool and let's help everyone else so they don't need to write the same thing again!

About the author

I'm a C++ developer with more years than I can remember.
Main day job is working on the rather fabulous PC based TV guide called DigiGuide.

My 'spare time' is occupied by writing either contract code or working on stuff for my own website, which includes QHTM - a rather nifty HTML rendering windows control.

I wrote this library *ages* ago but, as is always the case, once the fun(coding) bit is out of the way that only leaves writing the web pages, creating the zip files and uploading it - none of which is fun.

Hope you get as much use out of it as I have, and don't forget to share your mods!

Downloads

  • Only source code Includes source for the library and the examples, plus any supporting files needed - 83 Kb
  • Compiled examples only So you can take a quick look and see if the library does what you expect - 39 Kb


Comments

  • Question

    Posted by Legacy on 11/13/2002 12:00am

    Originally posted by: ArielR

    I have created 3 dialogs,
    
    Dlg1-> Parent
    Dlg2 -> child
    Dlg3 -> child

    How I may to do if want to use Dlg2 members like CString value in Dlg3 dialog.

    I tried with:
    In Dlg3:
    # Include "Dlg2.h"

    BOOL CDlg3::OnInitDialog()
    {
    CDialog::OnInitDialog();

    CDlg2 m_pDlg2;

    m_sDlg3Strn = m_pDlg2.m_sTxtDlg2;

    UpdateData(TRUE);

    return TRUE; // return TRUE unless you set the
    }

    But my m_pDlg2.m_sTxtDlg2 String is empty.

    Reply
  • MFC Sample does not seem to work properly

    Posted by Legacy on 04/25/2002 12:00am

    Originally posted by: Ralf Pichocki

    Hi!
    I just downloaded your "compiled only" zip and tried it. With the MFC sample, however, there seems to be a problem: As soon as you make the window small enough to hide the lower two edit fields, and enlarge it again afterwards, those lower two edit fields are stretched too big vertically; and a similar thing happens with horizontal resizing...;-(
    Is there anything to do against (means: either to force proper resizing or have a minimal dialog size put into before)?
    Thanks, Pi.
    p.s.: If you cannot reproduce this behavior, let me know and I'll describe it in more detail...

    Reply
  • Problems with PropertySheet

    Posted by Legacy on 04/18/2002 12:00am

    Originally posted by: Stephan Pilz

    Very nice Example, but my Mainapplication is based on CPropertySheet (not MDI !!!) with an added Minimize-Button.
    Your Code works only without Systemmenu (what I need).

    In my Test, I could resize the Mainwindow (PropSheet and the active Page), but the Member in the PropPage (CListCtrl) was not resized. I set this Member in the DIALOG_SIZER-Struct.

    In my Opinion a simple Library (not DLL) is a better solution, because in the exist way I need many more files in the Revision Control System.

    Thanks
    Stephan

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Hurricane Sandy was one of the most destructive natural disasters that the United States has ever experienced. Read this success story to learn how Datto protected its partners and their customers with proactive business continuity planning, heroic employee efforts, and the right mix of technology and support. With storm surges over 12 feet, winds that exceeded 90 mph, and a diameter spanning more than 900 miles, Sandy resulted in power outages to approximately 7.5 million people, and caused an estimated $50 …

  • Ever-increasing workloads and the challenge of containing costs leave companies conflicted by the need for increased processing capacity while limiting physical expansion. Migration to HP's new generation of increased-density rack-and-blade servers can address growing demands for compute capacity while reducing costly sprawl. Sponsored by: HP and Intel® Xeon® processors Intel, the Intel logo, and Xeon Inside are trademarks of Intel Corporation in the U.S. and/or other countries. HP is the sponsor …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds