Creating a Property Sheet Inside a Form View

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

This topic was contributed by Asaf Levy.

Form views (CFormView) can do almost anything you want: you can easily shape and modify it, process its control's messages, and communicate with the document. It's like creating a very important dialog box.

Property sheet (CPropertySheet) is also a very convinient and simple way to gather and display information. You create property pages using the dialog template editor, and simply add them to the propery sheet's object. Most importantly, the property sheet takes care of all the page's notification messages for you. All you have to be worried about is what your code will do, not where it is routed to, and who is actually getting it (each page intercepts its own IDC_blahblah's messages).

But, have you ever tried putting a propery sheet inside a form view, together with other controls like buttons, check boxes, list boxes, ect...? Sure, you can use the tab control (CTabControl), given in the dialog template editor. But who will take care of all the notification messages? YOU?? no way!! And how will you create the page's interfaces? BY HAND?? no way!!

To my opinion, these two reasons if far from enough to convince a sane programmer to look for a way out: property sheets inside a form view! It handels your notification messages and lets you add editable dialog templates to the sheet - what more can you possibly ask??

Now, lets look at how you do this. This task has a few simple steps:

Step 1: Create a "place holder" control in your form view's template

You have to create a control that will function as a place holder for the property sheet control. The most suitable control is the picture control: it will be the sheet's parent window. Make sure the control is Visible, and that it's on type Frame. Make it big enough to include the pages in it. Lets suppose that its ID of the picture control is IDC_PLACEHOLDER.

Step 2: Create a derived CPropertySheet class

Create a class derived from CPropertySheet using ClassWizard (lets call it CMyPropertySheet), and leave only one constructor with the parent window as its parameter:
	CMyPropSheet(CWnd* pParentWnd = NULL);

Step 3: Add a pointer to the derived property sheet class in your form view class

In your derived form view class, add a pointer to the newly created derived property sheet class, so you can refer to it and use it later:
	CMyPropSheet* m_pMyPropSheet;

Step 4: Add code in CMyFormView::OnInitialUpdate() to create your property sheet

Create a handler to WM_INITIALUPDATE in CMyFromView, and after the call to CFormView::OnInitialUpdate(), add code to create a Modeless Property Sheet and associate it with the place holder control.
	// create and asociated the property sheet with the "place holder" window
	CWnd* pwndPropSheetHolder = GetDlgItem(IDC_PLACEHOLDER);
	m_pMyPropSheet = new CMyPropSheet(pwndPropSheetHolder);
	if (!m_pMyPropSheet->Create(pwndPropSheetHolder, 
		WS_CHILD | WS_VISIBLE, 0))
	{
		delete m_pMyPropSheet;
		m_pMyPropSheet = NULL;
		return;
	}

	// fit the property sheet into the place holder window, and show it
	CRect rectPropSheet;
	pwndPropSheetHolder->GetWindowRect(rectPropSheet);
	m_pMyPropSheet->SetWindowPos(NULL, 0, 0,
		rectPropSheet.Width(), rectPropSheet.Height(),
		SWP_NOZORDER | SWP_NOACTIVATE);

Step 5: Create the pages by deriving from CPropertyPage

Create as many classes as you wish which are derived from CPropertyPage using ClassWizard, and leave them as they are (you will later handle the page control's specific messages there). Associate a different IDD_blahblah to every class.

Step 6: Add the page's objects as member variables to the propery sheet class

Declare objects of your page's derived types (as was created in step 5), and put them in the class declaration of your derived property sheet:
	CMyPage1 m_pageMy1;
	CMyPage2 m_pageMy2;
	......

Step 7: Add page insertion code in the derived property sheet's constructor

Now you will associate the page's objects to your property sheet, by adding them to the sheet, using the CPropertySheet::AddPage(...) function.

Note: Here i put the code in the sheet's constructor, so it will be done automatically, but you can put this code anywhere you want in the derived property sheet class.

CMyPropSheet::CMyPropSheet(CWnd* pParentWnd)
	:CPropertySheet(AFX_IDS_APP_TITLE, pParentWnd)
{
	AddPage(&m_pageMy1);
	AddPage(&m_pageMy2);
	......
}
That's it. If you compile and run your application, you will now get a fully functional property sheets with pages you can edit easily!

All you have to do now is add message handlers in each page to the page's own control. Have Fun!!



Comments

  • WONDERFUL tutorial

    Posted by vpappas on 11/03/2004 11:13am

    This was a great article. I have had a bit of trouble finding a clear explanation of how to use property sheets/pages and this article made it easy. Plus, it taught me why I don't want to use the tab control that comes with the VC++ resource editor. THANKS!!!!

    Reply
  • Thanks

    Posted by Legacy on 01/15/2004 12:00am

    Originally posted by: Alex K

    ^^

    Reply
  • how to call different views to different tab

    Posted by Legacy on 12/25/2003 12:00am

    Originally posted by: kalyani

    i want to create interface like workspace in vc++ application. i taken one sdi application and splitted into two portions. in left panel i want to create tabsheetand on each tab click it has to be display one view. like workspace having three tab sheets (classwizard and fileview nad resource view) how i will get that one. please help me.
    
    

    Reply
  • Thanks!

    Posted by Legacy on 10/28/2003 12:00am

    Originally posted by: Johnny Serup

    I implemented this not for FormView, but inside a Dialog box, so initial update is done in OnInitDialog before CDialog::OnInitDialog(), and it works perfect.

    Do you by any chance know how to set the tab's in the buttom instead of the top ???

    Reply
  • Can I move the tabs to the bottom?

    Posted by Legacy on 10/22/2003 12:00am

    Originally posted by: Frank Perry

    I need to use a touch screen and would like the tabs on the bottom so the user's hand doesn't block the view of the screen. Propertysheets do this if they are created from from the tools list but I can't find a way to change them when they are created this way. Ideas?

    Frank Perry

    Reply
  • Error C2440

    Posted by Legacy on 07/29/2003 12:00am

    Originally posted by: DimiGR

    I am getting an error:

    error C2440: 'static_cast' : cannot convert from 'void (__thiscall CFormView::* )(void)'
    to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'

    None of the functions with this name in scope match the target type

    It has somthing to do with the WM_INITIALUPDATE handler.
    Can some1 post the hole handler def. and decl. here?

    THX in advance

    Reply
  • Please help!!!System hangs even after adding ModifyStyleEx (0, WS_EX_CONTROLPARENT)

    Posted by Legacy on 07/28/2003 12:00am

    Originally posted by: Fordiscuss

    Hello all,

    I created a MFC Dialog with a property sheet, with two property pages.
    I followed your example code and created this by creating a place
    holder (Picture Object) and them creating the property sheet in the
    OnInitDialog() function of the dialog.

    The application launches fine.Clicking on the tabs seems to work.
    When I switch to another program, I am able to focus back to the
    Property pages.

    However, If i click on any of the controls placed on the Propertypage,
    like a editbox or a combo box, and then switch focus to another
    program, the Application loses focus, and the system hangs and the
    runs at 100% utilization.

    I researched this problem on the internet and found the following

    "Q149501: "PRB: Child CPropertySheet Hangs If Focus Is Switched"

    I did as was suggested, and tried the following:

    1)added ModifyStyleEx (0, WS_EX_CONTROLPARENT)to the Property sheet
    InitDialog()
    Result: Application hung while starting up!
    2)added ModifyStyleEx (0, WS_EX_CONTROLPARENT) to the property sheet
    member in CDialog: InitDialog()
    Result: Same Problem Remained.
    3) Read in one of the posts that we need to add this to the place
    holder too, in my case, a Picture Object.
    Result: Application hung while starting up!

    I have no clue what I should be doing next and I am very confused.
    Please advise on what can be done.
    Thanks you so much.

    Reply
  • good idea!

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

    Originally posted by: Agent Smith

    so useful and great code!
    thank you so much

    Reply
  • Adding tool tips to the tabs of the property sheet?

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

    Originally posted by: jfeid

    Hi all,
    this implementation is nice, i followed and i have my property sheet inside a form view (SDI app) which is handled by a splitter (resizing handled ok). But i'm getting much trouble in showing tooltips on the tabs of the property sheet. Does anyone have a clue on this?

    John

    Reply
  • Dialogbox inside a property page?

    Posted by Legacy on 05/05/2003 12:00am

    Originally posted by: Flo

    I would like to know if it's possible to call a dialog box by clicking on a button in one of my property page(I used the same code as this tutorial), but when I clicked on this button everthing is blocked, and the dialog box doesn't appear
    Thank you for your help

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

Top White Papers and Webcasts

  • With the cloud transforming application development and deployment — enabling organizations to improve flexibility, automate processes, and decrease time to market — some big questions remain. One of the most important issues an organization must address is how it can best employ the smarter tools and limitless scale that the cloud offers. One way that enterprises take advantage of the benefits of the cloud is by deploying their own private cloud. Read this white paper to learn how private clouds …

  • IT is in a continual battle to simplify and "do more with the same, or less," but the continued growth of data has drastically increased the complexity and cost of deploying, managing, and processing data using traditional IT infrastructure components. One key component — enterprise storage and the underlying software that controls the storage — is fortunately evolving nearly as fast as the data is growing. This ESG Lab Review documents the results of hands-on testing of the WekaIO Matrix …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date