Solved

MDI Grandchild Windows?

Posted on 1998-08-08
8
803 Views
Last Modified: 2013-11-20
I am porting a C Windows application to MFC.  This application uses an interface where each MDI child window has several child windows of it's own.  I'm looking for way to port this arrangement over to MFC, leveraging the most amount of MFC's functionality that I can.  I'm aware that Windows does not support nested MDI Windows. I've experimented with creating CWnds inside an CMDIChildWnd's CView. This almost works Ok, except that the "grandchild" windows don't act like normal windows.  They don't paint their title bars as the active window when they receive the focus and they don't pop to the front when activated by a mouse click down, only when the click is lifted.  

My question:  Should I continue with this approach and try to work around these problems or are there other options I should pursue to get this functionality. Any ideas on how to work around the problems with grandchild CWnd?  I would like to avoid managing the focus and painting in my own code if possible, that is where the C program is getting into trouble.

Splitter windows have already been rejected, there would be too many panes and would be too cumbersome for the user to drag the borders around when they wanted to enlarge a particular pane of information.  Movable, resizable windows are necessary.

Thanks in advance
0
Comment
Question by:dcooper080498
8 Comments
 
LVL 7

Expert Comment

by:psdavis
ID: 1320442
Hmmm... Nested MDI windows isn't absolutely impossible. (depends on the definition).  I'm doing a MDI window and when you click on the toolbar inside of the MDI window, then another MDI window pops up.  I'm doing it down three levels and everything seems well.

Here's a little snipplet from my mainfrm class.  The key to it is the last line "pApp->m_pSignatureTemplate->OpenDocumentFile( NULL );" that will open up the new MDI child if it doesn't already exist.  When creating your templates, keep a pointer to them in your main application's header file.  Then when you want to open it, check it against the current open classes to eliminate duplicates.

I hope this helps you.

Phillip


void CMainFrame::OnViewSignature()
{
   CVisaApp* pApp = CVisaApp::GetApp( );

// If the view is already opened, then just go to it!

   CCountryView* pCountryView = NULL;

   POSITION posTemplate = pApp->GetFirstDocTemplatePosition( );
   
   while( posTemplate )
   {
      CDocTemplate* pTemplate = (CDocTemplate*) pApp->GetNextDocTemplate( posTemplate );

      POSITION posDocument = pTemplate->GetFirstDocPosition( );
     
      while( posDocument )
      {
      // If we found a document of this type, then we're already done.  Just activate it!

         CDocument* pDocument = pTemplate->GetNextDoc( posDocument );

         if( pDocument->IsKindOf( RUNTIME_CLASS( CSignatureDoc )))
         {
         // Now iterate all of the windows and activate the first one!

            POSITION posView = pDocument->GetFirstViewPosition( );

            if( posView )
            {
               CView* pView = pDocument->GetNextView( posView );

               ((CMDIChildWnd*) pView->GetParentFrame( ))->MDIActivate( );
            }

            return;
         }
         else if( pDocument->IsKindOf( RUNTIME_CLASS( CCountryDoc )))
         {
         // Now iterate all of the windows and activate the first one!

            POSITION posView = pDocument->GetFirstViewPosition( );

            if( posView )
            {
               pCountryView = (CCountryView*) pDocument->GetNextView( posView );
            }
         }

      }
   }
   
// If the signature list is empty, but the country view is already opened, then limit the signatures to only that one country!

   BOOL GetCurrCountry( CString& strCurrCountry );

   if( pCountryView )
      pApp->m_pSignatureSet->m_strFilter.Format( "[Country Code] = \"%s\"", pCountryView->GetCurrCountry( ));
   else
      pApp->m_pSignatureSet->m_strFilter.Empty( );

   pApp->m_pSignatureSet->Requery( );

   pApp->m_pSignatureTemplate->OpenDocumentFile( NULL );      
}


0
 

Author Comment

by:dcooper080498
ID: 1320443
Thanks for you answer Phillip, but I don't think it is what I am looking for.  It appears that your app is opening MDI siblings when it responds to the toolbar command.  What I am looking for is an MDI child window that itself is the parent of and contains child windows:

CMDIFrameWnd <- MDI parent frame
     CMDIChildWnd <- MDI child frame
        CView
          CWnd <- Window contained in MDI child view or frame
          CWnd <- more of these
          ...  

Let me know if I am mistaken about how your app works.

Dan

0
 
LVL 7

Expert Comment

by:psdavis
ID: 1320444
No you're not mistaken, but it's the only way that I know to do 'simulated' children.  I do put the toolbars within the MDI windows so at least it seems more sibling like.

Phillip
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 2

Expert Comment

by:jstolan
ID: 1320445
How about adding your own information to the window classes?  Each window could have it's own member variables for remembering it's parent and children.  You could then add functions like

GetRealParent
GetFirstRealChild
GetNextRealChild
EnumerateRealChildren
etc. etc.

Where the "Real" parents and children used your internal member variables to keep track of who was who.  You could even override the "GetParent" etc CWnd functions, although I wouldn't recommend it.

This might give you the functionality you need without having to get too far away from the built in functionality provided by the MDI API.
0
 

Author Comment

by:dcooper080498
ID: 1320446
Thanks for you comment jstolan.  The problem seems to lie in the message passing up and down the chain of Windows.  While I can create and display windows that are children of an MDI child they don't respond like they should. I'm trying to work as much within the MFC framework as possible.  I guess the kind of answer I am looking for is an "oh yeah, just handle such and such message and everything will work" type of thing that a MFC guru might know about.  Such an answer may not exist, but I would like to put the question out there.

I'm currently trying out a solution using docking toolbar panes like DevStudio debug mode uses.  This doesn't duplicate the look of the program I'm duplicating, but it does work functionally so it really is an aesthetic decision.
0
 
LVL 1

Expert Comment

by:rlarner
ID: 1320447
Another thing to look at -- A splitter frame does something simmilar to what you are talking about (it contains two sub-windows in one).  You might look at it's implementation for hints on how to imbed CFrameWnd classes in a second CFrameWnd class.  CSplitterWnd does message passing, window selection, etc -- it should be easy to see what you have to override in a e.g. CContainerWnd.
0
 
LVL 7

Accepted Solution

by:
psdavis earned 190 total points
ID: 1320448
I think I found something for you.  Take a look at Stingray software's Objective Toolkit Pro.  It has a Dockable view class that can be docked to your mainframe.  I don't have it yet (I just ordered the Tookit std) but just from the screenshots, it will allow you to create views and keep them docked to a parent frame.  There's a download example from them at www.stingray.com that's about 3 meg if you want to see what they're doing.  It just might be helpful.

Phillip
0
 

Author Comment

by:dcooper080498
ID: 1320449
Ding ding ding, we have a winner!  Actually, I'm working on using similar docking CDialogBars extended using the fine examples available from www.codeguru.com.  Without having code in hand, Stingray's description of being able to dock to frames is pretty much what the doctor ordered.  I'm interested in how their focus management works etc.  A bit pricey, but it looks like something to look into.

Thanks, Phillip, for pointing this out.

Best regards,

Dan Cooper
dcooper@fvt.com
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Smart Camera scanning and reading information 3 113
modThree challenge 4 96
sumHeights  challenge 17 74
How to convert MFC::CString to UTF8 wchar_t* 10 278
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question