Nested PropertySheet

Is it possible to create nested property sheet? If yes, how do you create them? Any example appreciated.
mnyeuAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kburns102197Commented:
Yes you can - do the following:

1) Create a parent  property sheet normally (called CParentSht for this example) derived from CPropertySheet, with pages derived from CPropertyPage.
2) Create a child property sheet exactly as you created parent sheet (called CChildSht in this example) - All you have done at this to point is  create two separate property sheets.
3)Add a message handler for your parent sheet(I called it OnMainSht)
4)Add a message handler for your child sheet(I called it OnChildSht)
3)Assuming your view document is called CYourView, your  message handler should look like this:

void CMainView::OnMainSht()
{
       CParentSht  ParentSheet("Parent Sheet",this,0);
       int result=ParentSheet.DoModal();
       if(result==IDOK)
       {
         // this will invoke your child page on the OK button
          OnChildSht();
          Invalidate();
       }
}

void CMainView::OnChildSht()
{
       CChildSht  ChildSheet("Child Sheet",this,0);
       int result=ChildSheet.DoModal();
       if(result==IDOK)
       {
         // this will take you all the way back
          Invalidate();
       }
 
}


This example is not truely nested because the child window does not return the parent.  To make it truly nested then you should add another button on the parent to invoke the child (Don't use the OK button) as follows:
void CMainView::OnMainSht()
{
       CParentSht  ParentSheet("Parent Sheet",this,0);
       int result=ParentSheet.DoModal();
       if(result==IDCHILD)
       {
         // this will invoke your child page on the CHILD button
          OnChildSht();
          Invalidate();
       }
       else if(result==IDOK)
       {
         // exit
          Invalidate();
       }
}

void CMainView::OnChildSht()
{
       CChildSht  ChildSheet("Child Sheet",this,0);
       int result=ChildSheet.DoModal();
       if(result==IDOK)
       {
         // this will take you back to the parent
         OnMainSht();
          Invalidate();
       }
 
}


I coded this up just make sure it worked (I've never need to nest property pages before).  Let me know if you need the full source code..kburns
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
kburns102197Commented:
Sorry I mistyped the View name above, obviously it should be:

void CYourView::OnMainSht()
{
     ...
}

void CYourView::OnChildSht()
{
    .....
 }
0
mnyeuAuthor Commented:
First of all I appreciate your quick reply. But I am not sure your answer will work. How do you get IDCHILD as a return value from DoModal()? Moreover, you are creating one property sheet after another. That is not what I have asked in "Nested Property Sheet". I wanted to have one property sheet inside another.

Let me state my problem with an example. I create a property sheet with 3 property pages, namely A, B, and C. Now when I open Property page A, I shall see 3 property pages inside A, say x,y,and z. Property Page B, and C each have 3 property pages inside too. I called it "nested" because it looks like property sheet inside property sheet or like Tabs inside Tab. I hope it makes somewhat clear to you. Again I'll appreciate your reply.
0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

kburns102197Commented:
I think I see what you want to  do. I thought you wanted to launch a property sheet from within another & have it return to the parent.  As I understand it, you want new pages  x,y,z imbeded (smaller) in page A? A "sheet within a sheet" so to speak? If that is what you want to do then my answer may still work.

To answer your first question, you can in fact get DoModal to return IDCHILD.  By  default, DoModal will only return IDOK & IDCANCEL but you can use a Launch Child Sheet button and wire it up like this:

BEGIN_MESSAGE_MAP (CParentSht,CPropertySheet)
  ON_BN_CLICKED(IDCHILD,OnChildSht)
END_MESSAGE_MAP( )
   .
   .
   .

void CParentSht::OnChildSht( )
{
   EndDialog(IDCHILD);
}

then use  the the code above in CYourView::OnMainSht( ) that processes IDCHILD.

Also for simplicites sake, I don't think we should care if we have a "flat" model that emulates nesting.  You just care about the end result right? You want to  create the appearance of new pages within a sheet.  The trick is get the event IDCHILD to trigger off the tab key (an invisible  Launch Child Sheet button).

  I have never tried this , but I know you can get an object to work outside of the bounding rectangle of a dialog by holdiing down the CTRL key when constructing the page.  I'll experiment with it and see If I can get it to work in th tab area. I think I read that trick in Mike Blaszczak's book.  Mike are you reading  this? I'll let you know, mnyeu.
0
kburns102197Commented:
Ah, the problems grows.. I can see another problem, when we call the ::EndDialog( ) we will erase the parent so we will need a clever way to draw a fake set of tabs around the child sheets or not erase them is the first place. How many points is this question? Just kidding!
0
kburns102197Commented:
Ah, the problems grows.. I can see another problem, when we call the ::EndDialog( ) we will erase the parent so we will need a clever way to draw a fake set of tabs around the child sheets or not erase them is the first place. How many points is this question? Just kidding!
0
mnyeuAuthor Commented:
Considering the complexity of the problem, I have increased the points to 200. If you get it working, please let me know.

I wonder if you can embed a property sheet within a property page, that will solve the problem. So property page A will hold a property sheet which in turn have x, y, and z property pages. If you have any better solution, let me know.
0
kburns102197Commented:
mnyeu,
One last question - Have you considered carefully that a nested property sheet is a major deviation from the normal WIN95/NT GUI.  I have never seen one.  I will certainly work on a solution for you but before I do  want to to confirm that it is really the approach you want to take.

I am always up for a challenge but not if it is for nothing. .  I think I'll have to resort tho the Win API to solve this.  Please comment... kburns
0
kburns102197Commented:
mnyeu,
 I have completed the project for you and will post the general solution in my next comment. I wound up making a parent property sheet from scratch so I could have total control.  Give me your e-mail address and I will send you the complete solution. Thankyou for increasing the points. It took quite a while to get this working! ...kburns
0
kburns102197Commented:
I tried several approaches to this problem including a truly nested approach but I found it very difficult to actually nest one sheet inside another. To give the control I needed, I built the parent sheet from scratch.
Here is the general solution(when I get your e-mail address I'll send you the complete source so you have all the details):

1) Create a Parent Property Sheet by constructing a dialog with the tab control, and the OK, CANCEL, and APPLY buttons.  - Make sure the parent dialog  is large enough to hold the LARGEST Child Property Sheet because it doesn't have the intelligence to size itself dynamically (you could build this functionality in however). Leave off the Apply button if you don't need it. Also you the multiline tab control option if you want the tabs stacked instead of scrolled.

2) Create a Child set of Property sheets normally.

3) Call the Parent Dialogs OnInit() method  to add the page tabs, initialize the default tab member , and draw the Child sheet with the method with your custom method ShowChildPropSheet( );

4) Monitor the tab control and call the appropriate child via ShowChildPropSheet( ).

This approach works exactly the way you want to do it. Each tab press will invike a new child property sheet.

Thats it but there are some details to wire it up. I would post the entire souce locally but the folks at Experts Exchange probably would'nt appreciate it. I' rather send you the complete working demo with souce.
0
mnyeuAuthor Commented:
My email is mnyeu@smc.com. EMail me your working version for the points. I have got it working. I created a property sheet with 3 property pages. In the initialization of property page, I create another property sheet. I hide the default buttons of child property sheet as I do not need them anymore. Had to be careful with message loop.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.