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

CResizableSheet and CResizablePage

, 27 Oct 2001 CPOL
Rate this:
Please Sign up or sign in to vote.
Two CPropertySheet/CPropertyPage derived classes to implement resizable property sheets or wizard dialogs with MFC

CResizableSheet(Ex) and CResizablePage(Ex)

These four classes handle resizable property sheets, wizards and the wizard 97 style dialogs, and are now fully based on my ResizableLib class library (see article).

The user will have the ability to resize the dialog, with consequent rearrangement of child windows. You can control the minimum and maximum size allowed, as well as the maximized size and position of the dialog. The size grip is displayed by default, but you may turn it off. Automatic Save/Restore the dialog's size and position, along with the active page, is also supported.

Conversion of a previously existant property sheet or wizard should be very simple.

I will talk about non-Ex classes for the rest of the article, but the same concepts applies for Wizard 97 dialogs.

The Sample Applications

This is a view of the sample dialog at minimum size as a property sheet and in wizard mode:

Property sheet with smaller size and proportional resizing Wizard mode with help button and minimal size

Note that the minimum width is not the default. You may see how to do this in the next section.

This is a screenshot of the resizable version of Wizard97 sample project coming with Visual C++.

A resizable Wizard 97 dialog

Usage - Step by Step

Add the ResizableLib to your project's workspace, as explained in the relative article.

Create a property sheet or wizard dialog and do the relative associations with MFC classes, for example using the Property Sheet component, or take one you have already made which you want to be resizable. You don't need to change any window style to have the dialog resizing.

Include 'ResizableSheet.h' in the property sheet associated header file.

Search and replace all CPropertySheet occurences with CResizableSheet in both your .cpp and .h files, just as if your property sheet class was derived from CResizableSheet instead of CPropertySheet.

Include 'ResizablePage.h' in the property pages associated header file.

Search and replace all CPropertyPage occurences with CResizablePage in both your .cpp and .h files, just as if your property page classes were derived from CResizablePage instead of CPropertyPage.

The same applies for wizard dialogs, of course.

Your property sheet header file should appear like this:

// MyPropertySheet.h : header file
//

#include <span class="code-string">"MyPropertyPages.h"</span>

/////////////////////////////////////////////////////////////////////////////
// CMyPropertySheet

#include <span class="code-string">"ResizableSheet.h"</span>

class CMyPropertySheet : public CResizableSheet
{
    DECLARE_DYNAMIC(CMyPropertySheet)

// Construction
public:
    CMyPropertySheet(CWnd* pWndParent = NULL);

// ( other stuff )
// ...
}

In your OnInitDialog override you may change the initial settings of your property sheet, such as the minimum size and automatic save/restore, that can optionally set also the active page.

BOOL CMyPropertySheet::OnInitDialog() 
{
    CResizableSheet::OnInitDialog();
    
    // set minimal size
    CRect rc;
    GetWindowRect(&rc);

    SetMinTrackSize(CSize(GetMinWidth(), rc.Height()));

    // enable save/restore, with active page
    EnableSaveRestore(_T("Properties"), TRUE, TRUE);

    return TRUE;
}

Your property pages header file should appear like this:

// MyPropertyPages.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CMyPropertyPage1 dialog

#include <span class="code-string">"ResizablePage.h"</span>

class CMyPropertyPage1 : public CResizablePage
{
    DECLARE_DYNCREATE(CMyPropertyPage1)
// ...
}

// and so on for the other pages ...

In each page's OnInitDialog override you only have to set a layout for your controls. You specify where to attach the top-left and bottom-right corners by horizontal/vertical percentage or using predefined constants.

BOOL CMyPropertyPage2::OnInitDialog() 
{
    CResizablePage::OnInitDialog();
    
    // preset layout
    AddAnchor(IDC_LIST1, TOP_LEFT, CSize(50,70));
    AddAnchor(IDC_PICTURE1, CSize(50,0), CSize(100,70));
    AddAnchor(IDC_GROUP1, CSize(0,70), BOTTOM_RIGHT);
    AddAnchor(IDC_CHECK1, CSize(0,85));
    AddAnchor(IDC_RADIO1, CSize(100,85));
    AddAnchor(IDC_COMBO1, CSize(100,70));
    AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);

    m_ctlEdit1.AddString(_T("Just a single item to test the "
        "listbox behavior with very long lines..."));
    m_ctlEdit1.SetHorizontalExtent(300);

    return TRUE;
}

You are ready to rebuild your project and you will have a resizable property sheet or a wizard dialog just as you wanted.

For further details, see the next section.

Class Reference

The property sheet class inherits from CResizableLayout, CResizableGrip, CResizableMinMax, CResizableState and obviously from CPropertySheet.

The property page class inherits from CResizableLayout and obviously from CPropertyPage. The other classes are not needed.

CResizableSheet::CResizableSheet

CResizableSheet()
CResizableSheet(UINT nIDTemplate, CWnd* pParentWnd = NULL)
CResizableSheet(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL)

CResizablePage::CResizablePage

CResizablePage()
CResizablePage(UINT nIDTemplate, CWnd* pParentWnd = NULL)
CResizablePAge(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL)

The first form is the default constructor.

The second and the third forms are needed to reproduce the construction scheme of a CPropertySheet/Page derived class. Since the dialog resource template is needed by the CPropertySheet/Page constructor, you have to call one of these forms of the CResizableSheet/Page constructor. This is the reason why replacing one class with the other will work.

CResizableSheet::EnableSaveRestore

void EnableSaveRestore(LPCTSTR pszSection, BOOL bRectOnly, BOOL bWithPage = FALSE)

Enables automatic save/restore on dialog's open/close operations. The first argument is the same as in CWinApp::WriteProfileString. If bRectOnly is TRUE, the minimized/maximized state is not saved/restored. The last argument is a flag for restoring the active page (active page is always saved). Should be called after all the layout settings.

If you want details on how these settings are stored, look at CWinApp::SetRegistryKey, CWinApp::m_pszProfileName, CWinApp::m_pszRegistryKey on MFC documentation.

CResizable???::???

Implemented in the various base classes, see ResizableLib article.

Member functions to set/reset maximized size and position may seem rather useless, since you don't have a maximize box in the window's caption. I left them because I think it should be possible to enable caption buttons, playing a little with window's styles.

Conclusion

I hope these classes can make some programmers' life a little easier. I also want to thank Jerzy Kaczorowski for his unique support during the port of CResizableDialog code to property sheets.

Integration with ResizableLib is now complete. This required a partial rewriting, but I hope it will benefit of all the improvements made to the library (and the bugs too).

The CVS tree is now on Source Forge.

Updates

28 Jul 2000

Initial public release.

27 Oct 2000

Fixed bug with stacked tabs.
Controls that need refresh now display correctly.
Replaced internal structure with a CArray.

13 Mar 2001

Fixed a bug with radio buttons and group boxes (thanks to Matt Philmon)
Changed copyright note

11 Jun 2001

New implementation and integration with ResizableLib

15 Jul 2001

Updated to new ResizableLib release
Complete integration with the library, now using new callback anchors
Added support for 'Wizard 97' style dialogs

28 Oct 2001

Version 1.1 (CVS Tag: SF_1_1)
Fixed a bug with CTRL+Tab while navigating Wizard dialogs
Added static build configurations to all projects

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Paolo Messina
Software Developer RoboTech srl
Italy Italy
Paolo began programming at the age of 9 with a glorious 8086 and GW-BASIC, then he played a bit with C, ASM and Pascal. He tought himself MFC and Windows programming, to exploit his studies of C++. Always attracted by low-level programming and Assembly, he's beginning to appreciate the joys of templates and STL. At work he changed his mind about Java, discovered Eclipse IDE, and now think it's cool.
 
He lives in Follonica, Italy.
 
He has been abroad in the U.S. to work on his final thesis before graduating. For seven months he was playing with airplanes and automatic control at the Unversity of Illinois at Urbana-Champaign.
 
He graduated in Computer Science Engineering at the University of Pisa, Italy, in December 2003.
 
Currently working for an edutainment robotics company (www.robotechsrl.com).
Follow on   Google+

Comments and Discussions

 
QuestionTabbing through controls PinmemberYanezDeGomeyra21-Jul-11 6:21 
AnswerRe: Tabbing through controls PinmemberPaolo Messina21-Jul-11 6:40 
GeneralRe: Tabbing through controls PinmemberYanezDeGomeyra21-Jul-11 7:03 
GeneralRe: Tabbing through controls PinmemberPaolo Messina21-Jul-11 7:46 
GeneralRe: Tabbing through controls PinmemberYanezDeGomeyra21-Jul-11 7:56 
GeneralModeless PropertySheet [modified] PinmemberFariborz_576-Mar-08 5:45 
GeneralTab control was drawn incorrectly if the property sheet was themed under XP PinmemberDandy Cheung15-Feb-08 6:01 
GeneralRe: Tab control was drawn incorrectly if the property sheet was themed under XP PinmemberDandy Cheung15-Feb-08 15:07 
GeneralRe: Tab control was drawn incorrectly if the property sheet was themed under XP Pinmemberanowsober25-May-09 22:14 
GeneralProblem in reusing CResizableSheet derived instance Pinmemberdobbs@riskeng.com23-Jan-08 5:38 
GeneralRe: Problem in reusing CResizableSheet derived instance PinmemberPaolo Messina23-Jan-08 6:28 
AnswerRe: Problem in reusing CResizableSheet derived instance PinmemberPaolo Messina25-Jan-08 3:46 
GeneralCannot Compile neither Version 1.3 of library nor dialog demo PinmemberzikTronics10-Aug-07 0:02 
AnswerRe: Cannot Compile neither Version 1.3 of library nor dialog demo PinmemberPaolo Messina10-Aug-07 0:33 
GeneralRe: Cannot Compile neither Version 1.3 of library nor dialog demo PinmemberzikTronics20-Aug-07 6:04 
Generallack buttons in CResizableSheet Pinmemberhphi30-Mar-07 0:07 
AnswerRe: lack buttons in CResizableSheet PinmemberPaolo Messina30-Mar-07 0:51 
GeneralRe: lack buttons in CResizableSheet Pinmemberhphi30-Mar-07 2:39 
AnswerRe: lack buttons in CResizableSheet PinmemberPaolo Messina25-Jan-08 3:50 
GeneralOnSetActive lost for the first page Pinmembersmall Smiley14-Aug-06 6:15 
AnswerRe: OnSetActive lost for the first page PinmemberPaolo Messina15-Aug-06 0:36 
GeneralMoving pages Pinmembersmall Smiley10-Jul-06 7:50 
GeneralRe: Moving pages PinmemberPaolo Messina11-Jul-06 6:21 
GeneralRe: Moving pages Pinmembersmall Smiley12-Jul-06 22:54 
AnswerRe: Moving pages PinmemberPaolo Messina30-Jul-06 8:07 
GeneralVC Designer Issues Pinmembersmall Smiley7-Jul-06 2:16 
GeneralLinking problems Pinmembersbuonocore18-Aug-05 3:14 
GeneralRe: Linking problems PinmemberPaolo Messina19-Aug-05 9:40 
General3 problems with 1.4alpha now... PinmemberPeter SJöström12-Jul-05 6:33 
GeneralRe: 3 problems with 1.4alpha now... PinmemberPeter SJöström13-Jul-05 3:57 
GeneralCan't compile with 1.4alpha PinmemberPeter SJöström6-Jul-05 6:26 
GeneralRe: Can't compile with 1.4alpha PinmemberPaolo Messina6-Jul-05 6:45 
GeneralRe: Can't compile with 1.4alpha PinmemberPeter SJöström6-Jul-05 7:46 
QuestionHow Can I Fit Sheet to max page? PinmemberFireEmissary26-May-05 17:48 
GeneralAccess Violation with Windows Me Pinmemberferro@winandweb.it9-Apr-05 10:57 
GeneralRe: Access Violation with Windows Me PinmemberPaolo Messina9-Apr-05 12:47 
GeneralRe: Access Violation with Windows Me Pinmemberemmi21-Apr-05 2:34 
GeneralRe: Access Violation with Windows Me Pinmemberferro@winandweb.it21-Apr-05 2:45 
I have find in MSDN Help this (searching: fix domodal property sheet):
 
FIX: CPropertySheet::DoModal() or Create() Causes an Exception
Last reviewed: February 17, 1998
Article ID: Q143071
The information in this article applies to:
a.. The Microsoft Foundation Classes (MFC), included with: -
Microsoft Visual C++, 32-bit Edition, version 4.0
 

SYMPTOMS
Under Windows 95, calling CPropertySheet::DoModal() or
CPropertySheet::Create() may cause an exception. The output window displays
a message saying "First-chance exception in (COMCTL32.DLL):
0xC0000005: Access Violation."
 
There is a second related problem. If the call to DoModal() or
Create() is inside a try/catch(...) block, you will get an error saying
"This program has performed an illegal operation..." If you click the
Details button, it will say " caused a stack fault in module
MSVCR40D.DLL at..."
 
CAUSE
Before a property page is created, it changes the style of the dialog
resource to the required style. Because resources are generally read-only,
this causes an exception.
 
The stack fault problem is caused by a bug in the C++ exception
handling routine. When the exception occurs and it is trapped by a
try/catch(...) block, it is not forwarded on to the operating system. This
leads to unpredictable results.
 

RESOLUTION
The first-chance exception can be ignored because it is safely handled
by the operating system.
 
A workaround for the stack fault problem is to use C++ exception
handling with specific exception types or use structured exception handling
where the access violation exception is passed through to the operating
system.
 

 
Sample Code to Demonstrate Workaround to Stack Fault Problem
 
/* Compile options needed: default
*/
 
/***** this code will cause unpredictable results *****/
try
{
sheet.DoModal();
}
catch(...)
{
}
 
/***** this code is OK *****/
try
{
if (0 == sheet.DoModal())
throw "DoModal() failed!";
}
catch(char * str)
{
TRACE ("Exception thrown: %s\n", str);
}
 
STATUS
This problem was corrected in Visual C++ version 5.0 and with
Comctl32.dll included with Internet Explorer 3.2 and later.
 

 
REFERENCES
This is also documented in the Vcread.wri readme file.
 

 
Searching: prb domodal property sheet, you may find this:
 
PRB: CPropertySheet::DoModal() or Create() Causes an Exception
Last reviewed: September 15, 1997
Article ID: Q158552
The information in this article applies to:
a.. The Microsoft Foundation Classes (MFC) included with: -
Microsoft Visual C++, 32-bit Edition, versions 4.0, 4.1, 4.2, 5.0
 

SYMPTOMS
Calling CPropertySheet::DoModal() or CPropertySheet::Create() in
Windows 95 may cause an exception. The Output window displays a message that
says the following:
 

First-chance exception in (Comctl32.dll): 0xC0000005:
Access Violation.
 
Newer versions (version 4.70) of the Comctl32.dll do not have this problem.
 

CAUSE
The CommCtl32.dll tries to modify the resources for the pages. Since
the resources are normally in read-only sections this throws an Exception
that can be caught in the application. However, if the application does not
catch this exception then the OS will handle this exception correctly.
 

 
RESOLUTION
The first-chance exception can be ignored because it is safely handled
by the operating system.
 
One way to prevent the exception from being thrown is to make the
resources read/write. You can do this by adding a linker setting of
"/SECTION:.rsrc,rw."
 
A second way to prevent the exception being thrown is to change the
font of the pages so they are not "MS Sans Serif". MFC checks the dialog
template font for the page. If it is not "MS Sans Serif" then it makes a
copy of the resource in read/write memory, modifies the font and passes this
to the C mCtl32.dll. So when the dll writes to the template for the page it
is writing to read/write memory and hence exception is not thrown.
 
Another way to prevent the exception from affecting your application
is not to have the call for creating the property sheet in a try/catch(...)
block. Instead catch particular exceptions in the catch block.
 
If the property sheet is part of an OLE Automation Server that can be
invoked through a method of the server then you have to make the resources
read/write, using either of the first two methods described above, since OLE
catches the exception.
 
NOTE: Making the resources Read/Write can cause the resources to be
written to a page file.
 

 
STATUS
This behavior is by design.
 

 
MORE INFORMATION
 

Sample Code
 
/* Compile options needed: default
*/
 
/***** this code will cause unpredictable results *****/
try
{
sheet.DoModal();
}
catch(...)
{
}
 
/***** this code is OK *****/
try
{
if (0 == sheet.DoModal())
throw "DoModal() failed!";
}
catch(char * str)
{
TRACE ("Exception thrown: %s\n", str);
}
 
REFERENCES
For more information, please see the following article in the
Microsoft Knowledge Base:
 

ARTICLE ID: Q126630
TITLE : Resource Sections are Read-only
Keywords : MfcUI kbprg
Technology : kbMfc
Version : WINDOWS NT:4.0 4.1 4.2 5.0;
Platform : NT WINDOWS
Issue type : kbprb
 

Well, now I don't know how fix the soruce code of Paolo Messina Sigh | :sigh:
Bye, Roberto Ferro

 
Robi
GeneralRe: Access Violation with Windows Me PinmemberPaolo Messina21-Apr-05 3:39 
GeneralRe: Access Violation with Windows Me Pinmemberemmi22-Apr-05 4:58 
GeneralRe: Access Violation with Windows Me PinmemberPaolo Messina22-Apr-05 5:46 
GeneralRe: Access Violation with Windows Me PinsussAnonymous22-Apr-05 8:37 
GeneralThis code is great!! Pinmembercycosi9-Sep-04 5:03 
GeneralRe: This code is great!! PinmemberPaolo Messina10-Sep-04 4:48 
GeneralModeless propertysheet in a dialog Pinmemberng_793-Sep-04 1:26 
GeneralRe: Modeless propertysheet in a dialog PinmemberPaolo Messina3-Sep-04 6:47 
GeneralRe: Modeless propertysheet in a dialog Pinmemberng_795-Sep-04 20:07 
GeneralRe: Modeless propertysheet in a dialog PinmemberPaolo Messina5-Sep-04 23:14 
GeneralRe: Modeless propertysheet in a dialog Pinmemberng_796-Sep-04 0:34 
GeneralRe: Modeless propertysheet in a dialog PinmemberPaolo Messina6-Sep-04 1:04 

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 | Terms of Use | Mobile
Web01 | 2.8.1411022.1 | Last Updated 27 Oct 2001
Article Copyright 2000 by Paolo Messina
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid