Property Sheet Inside Property Page

SheetInSheet

Environment: VC6

You can use embedded property sheet in your application. I use "Creating a Property Sheet Inside a Dialog" by Zafir Anjum, as start solution.

1st step.

You must derive class from CPropertyPage and add CPropertySheet member to this class:
class CPropertyPageWithPropertySheet : public CPropertyPage
{

...
public:
	virtual BOOL UpdateData(BOOL bSaveAndValidate);
	virtual void AddPage(CPropertyPage *pPage);
...

...
// Implementation
protected:
	CPropertySheet m_internal_sheet;
	// Generated message map functions
	//{{AFX_MSG(CPropertyPageWithPropertySheet)
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
...

};

2nd step.

Override OnInitDialog() for configure property page and start it Create() method:
BOOL CPropertyPageWithPropertySheet::OnInitDialog() 
{
	CPropertyPage::OnInitDialog();
	
	// TODO: Add extra initialization here
	m_internal_sheet.EnableStackedTabs( FALSE );
	m_internal_sheet.Create(this, WS_CHILD | WS_VISIBLE , 0);
	m_internal_sheet.ModifyStyleEx (0, WS_EX_CONTROLPARENT);
	m_internal_sheet.ModifyStyle( 0, WS_TABSTOP );
	
	// move to left upper corner
	m_internal_sheet.SetWindowPos( NULL, 0, 0, 0, 0, 
                        SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE );

	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

3rd step.

After this you can add property pages to CPropertySheet member. For this I use AddPage() function:
void CPropertyPageWithPropertySheet::AddPage(CPropertyPage *pPage)
{
	m_internal_sheet.AddPage(pPage);
}

4th step.

For data exchange and validation you must override UpdateData() function in your dialog class and derived CPropertyPage class:
BOOL CPropertyPageWithPropertySheet::UpdateData(BOOL bSaveAndValidate)
{
	if(!CPropertyPage::UpdateData(bSaveAndValidate))
		return FALSE;
	// check property sheet. Need when OK button pressed in main dialog
	return m_internal_sheet.GetActivePage()->UpdateData(bSaveAndValidate);	
}
... and add change to DoDataExchange():
void CPropertyPageWithPropertySheet::DoDataExchange(CDataExchange* pDX)
{
	CPropertyPage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPropertyPageWithPropertySheet)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP

	// this need for check data when user change tab in parent property sheet
	if(m_internal_sheet)
		if(!m_internal_sheet.GetActivePage()->UpdateData(pDX->m_bSaveAndValidate))
			pDX->Fail();	
}
This code responds for validation, when user changes tabs in parent property sheet.

5th step.

Also you must add calls m_page_with_sheetXX.UpdateData( ) in parent dialog overrided UpdateData() function:
BOOL CPs_in_psDlg::UpdateData(BOOL bSaveAndValidate)
{
	if(!CDialog::UpdateData(bSaveAndValidate))
		return FALSE;

	// check addition property sheet in property pages
	if(m_page_with_sheet0)
		if(!m_page_with_sheet0.UpdateData(bSaveAndValidate))
			return FALSE;
	if(m_page_with_sheet1)
		if(!m_page_with_sheet1.UpdateData(bSaveAndValidate))
			return FALSE;

	// check main property sheet. Need when OK button pressed in main dialog
	return m_sheet.GetActivePage()->UpdateData(bSaveAndValidate);	
}

Downloads

Download demo project - 19 Kb


Comments

  • Good job...! Thanks!!

    Posted by Legacy on 09/02/2003 12:00am

    Originally posted by: Pentomic

    It's Very what I searching.......!
    Thanks for.....your job.

    Reply
  • Thanks! It works great!

    Posted by Legacy on 08/27/2003 12:00am

    Originally posted by: Kostya

    I'm using this class in my program and it works very good.

    Reply
  • Great !!!!!!!!

    Posted by Legacy on 01/23/2003 12:00am

    Originally posted by: Meena

    Thank you for you demo code...It got me out of the stupid mistake i had made

    Reply
  • Problem: Does not work with a RichEdit control !!!!

    Posted by Legacy on 10/26/2002 12:00am

    Originally posted by: Bundy

    i made a dialog based application with the property sheet model you have presented,
    and if i add a RichEdit control to ANY of the pages, then the page simply disappears
    when i click on its tab! (instead of being displayed, it disappears, the page AND the tab).
    i have also tried this with your own sample project, and i got the same results.
    personally, i couldn't figure out how to fix this. i *think* the problem
    is with the UpdateData function, but i'm not sure.

    Reply
  • What to do when using CMyPropertySheet instead of CPropertySheet?

    Posted by Legacy on 05/22/2002 12:00am

    Originally posted by: Simon De meulemeester

    Hello,

    I've tried your code and it works fine. However, when I try to use my own defined property sheet the compiler says that no default constructor is available for m_internal_sheet. Do you or anybody else knows how to solve this problem?

    Reply
  • How can I use a CPropertyPage as a CDialog ??? thanks

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

    Originally posted by: juhasaproblem

    I've made a CPropertyPage that I use in a CPropertySheet but I'd like to use too this CPropertyPage as a CDialog : the problem is that I can't close this CPropertyPage...
    Thanks for help me !!!!

    Reply
  • Problem with CFormView

    Posted by Legacy on 03/05/2002 12:00am

    Originally posted by: Ofer Erlich

    I try to add propertysheet inside propertysheet to a dilog which is in a CFormView Class.
    
    The first time the dialog is on every thing is fine , but the second time the system fail and it because of this function

    HWND CDataExchange::PrepareCtrl(int nIDC)
    {
    ASSERT(nIDC != 0);
    ASSERT(nIDC != -1); // not allowed
    HWND hWndCtrl;
    m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
    if (hWndCtrl == NULL)
    {
    TRACE1("Error: no data exchange control with ID 0x%04X.\n", nIDC);
    ASSERT(FALSE); // here is the problem
    AfxThrowNotSupportedException();
    }
    m_hWndLastControl = hWndCtrl;
    m_bEditLastControl = FALSE; // not an edit item by default
    ASSERT(hWndCtrl != NULL); // never return NULL handle
    return hWndCtrl;
    }
    what can be done to avoid this?

    Reply
  • Very Cool

    Posted by Legacy on 07/06/2001 12:00am

    Originally posted by: Keivan Eshghi

    I implemented your code in my project. It works fine.

    Thanks

    Reply
  • Can't Get it work under SDI environment

    Posted by Legacy on 01/06/2001 12:00am

    Originally posted by: Victor

    as above...any suggestions??

    Reply
  • Setting the focus in inside property page

    Posted by Legacy on 12/30/1999 12:00am

    Originally posted by: Joe Ersinghaus

    Hi,
    
    

    Your code has been a great help! Thanks!

    Was having trouble setting the focus to a control inside
    the inside property sheet. My outside property sheet is in wizard mode. I've tried setting the focus to the control and then returning false in my OnInit() function in the property page code. Using VC6.

    Appreciate the help!

    Joe

    Reply
  • Loading, Please Wait ...

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

Top White Papers and Webcasts

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • In support of their business continuity and disaster recovery plans, many midsized companies endeavor to avoid putting all their eggs in one basket. Understanding the critical role of last-mile connectivity and always available Internet access for their enterprises, savvy firms utilize redundant connections from multiple service providers. Despite the good intentions, their Internet connectivity risk may still be in a single basket. That is because internet service providers (ISPs) and competitive local …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds