MinimizeAll method for MDI children

Using MSVC 5 w/ MFC, how does one incorporate a MinimizeAll method for a MDI implmentation? The more detailed question is how to iterate on MDI children and guarantee you will hit them all?

This was suggested...

You can get the active MDI child by calling CMDIFrameWnd.MDIGetActive(). Then you can iterate using pMDIChild->GetWindow(HWND_NEXT) sending messages or calling member functions as you like.

Which is what I actually had done, but there is a problem...

void CMainFrame::OnWindowMinimizeAll()
{
  CMDIChildWnd* pMDIChild = MDIGetActive();
  CMDIChildWnd* pFirstActive = pMDIChild;
  while (pMDIChild)
  {
    pMDIChild->CloseWindow(); // Minimizes
    pMDIChild =  (CMDIChildWnd*)pMDIChild->GetNextWindow();
    if (pMDIChild == pFirstActive)
      break;
  }

However this will not actually do the job. If any window is activated other than the last, the loop will not hit each child. There is probably something wrong w/ the loop termination criteria, but something has to be there or the iteration will never terminate. The fundamental issue witht he suggested approach is that the 1st window in the window management list is not the same as the active MDI child, so iterating from active window forward doesn't guarantee all children are processed (at least w/ my loops above)
fontainejAsked:
Who is Participating?
 
gaohongConnect With a Mentor Commented:

text above
0
 
BelgaratCommented:
You can get the active MDI child by calling CMDIFrameWnd.MDIGetActive(). Then you can iterate using pMDIChild->GetWindow(HWND_NEXT) sending messages or calling member functions as you like.

0
 
fontainejAuthor Commented:
Edited text of question
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

 
fontainejAuthor Commented:
Edited text of question
0
 
fontainejAuthor Commented:
Edited text of question
0
 
fontainejAuthor Commented:
Edited text of question
0
 
gaohongCommented:
It hit me once. Using MDIGetActive() will not work.
You need to do is get its parent window first, then

hChild = GetWindow(GW_CHILD);
//mini for first
//loop here
hNext = GetWindow(hChild, GW_HWNDNEXT);
//mini
hChild = hNext;
0
 
fontainejAuthor Commented:
From gaohong...

It hit me once. Using MDIGetActive() will not work.
You need to do is get its parent window first, then

hChild = GetWindow(GW_CHILD);
//mini for first
//loop here
hNext = GetWindow(hChild, GW_HWNDNEXT);
//mini
hChild = hNext;

is not quite working. Here is the current implementation which is trying to minimize windows that are children of frame (parent of MDI child), but these windows include menus, toolbars, etc and not just MDI children. I'm sure I'm just interpreting the suggestion incorrectly, to avoid ambiguity it would be helpful if someone would just modify the following self-explanatory code so it will work. I'll up the points to 100 to the 1st working solution as this has been ridiculously tedious. THIS SHOULD BE VERY EASY (I did it in borland easy enough but OWL maintains its MDI child lists differently than MFC).


void CMainFrame::OnWindowMinimizeAll()
{
  HWND hFirstChild = ::GetWindow(*this,GW_CHILD);
  HWND hChild = hFirstChild;
  ::ShowWindow(hChild, SW_MINIMIZE);
  while (hChild)
  {
    HWND hNext = ::GetWindow(hChild, GW_HWNDNEXT);
    ::ShowWindow(hChild, SW_MINIMIZE);
    hChild = hNext;
  }
}
0
 
gaohongCommented:
You miss understood the MDI architecture. MDIFrame only has MDIClient as child, while MDIChild's parent is MDIClient.

      void CMainFrame::OnWindowMinimizeAll()
      {
        CMDIChildWnd *activeChild = MDIGetActive();

        if(activeChild)
          {
           CWnd *client = activeChild->GetParent();
           if(client)
             {
        HWND hFirstChild = client->GetWindow(*this,GW_CHILD);
        HWND hChild = hFirstChild;
        ::ShowWindow(hChild, SW_MINIMIZE);
        while (hChild)
        {
          HWND hNext = client->GetWindow(hChild, GW_HWNDNEXT);
          ::ShowWindow(hChild, SW_MINIMIZE);
          hChild = hNext;
        }
        }
        }
      }

0
 
fontainejAuthor Commented:
From gaohong...

It hit me once. Using MDIGetActive() will not work.
You need to do is get its parent window first, then

hChild = GetWindow(GW_CHILD);
//mini for first
//loop here
hNext = GetWindow(hChild, GW_HWNDNEXT);
//mini
hChild = hNext;

is not quite working. Here is the current implementation which is trying to minimize windows that are children of frame (parent of MDI child), but these windows include menus, toolbars, etc and not just MDI children. I'm sure I'm just interpreting the suggestion incorrectly, to avoid ambiguity it would be helpful if someone would just modify the following self-explanatory code so it will work. I'll up the points to 100 to the 1st working solution as this has been ridiculously tedious. THIS SHOULD BE VERY EASY (I did it in borland easy enough but OWL maintains its MDI child lists differently than MFC).


void CMainFrame::OnWindowMinimizeAll()
{
  HWND hFirstChild = ::GetWindow(*this,GW_CHILD);
  HWND hChild = hFirstChild;
  ::ShowWindow(hChild, SW_MINIMIZE);
  while (hChild)
  {
    HWND hNext = ::GetWindow(hChild, GW_HWNDNEXT);
    ::ShowWindow(hChild, SW_MINIMIZE);
    hChild = hNext;
  }
}
0
 
BelgaratCommented:
Sorry fontainej, but first try to learn how to use your WWW browser :-)
0
 
fontainejAuthor Commented:
Thanks a lot gaohong, this is one of those where a little sleep last night would have been advantageous. Here is a compiled solution that is working if anyone else has this question...

void CMainFrame::OnWindowMinimizeAll()
{
  CMDIChildWnd *activeChild = MDIGetActive();
  ASSERT(activeChild);

  CWnd *client = activeChild->GetParent();
  ASSERT(client);
 
  CWnd*  hChild = client->GetWindow(GW_CHILD);
  while (hChild)
  {
    CWnd* hNext = hChild->GetWindow(GW_HWNDNEXT);
    hChild->ShowWindow(SW_MINIMIZE);
    hChild = hNext;
  }
}
0
 
fontainejAuthor Commented:
Thanks a lot gaohong, this is one of those where a little sleep last night would have been advantageous. Here is a compiled solution that is working if anyone else has this question...

void CMainFrame::OnWindowMinimizeAll()
{
  CMDIChildWnd *activeChild = MDIGetActive();
  ASSERT(activeChild);

  CWnd *client = activeChild->GetParent();
  ASSERT(client);
 
  CWnd*  hChild = client->GetWindow(GW_CHILD);
  while (hChild)
  {
    CWnd* hNext = hChild->GetWindow(GW_HWNDNEXT);
    hChild->ShowWindow(SW_MINIMIZE);
    hChild = hNext;
  }
}
0
 
gaohongCommented:
Did I get points or you are still open the question. IMO, my
solution is A solution
0
 
fontainejAuthor Commented:
gaohong, sorry this is my first use of the site and i thought i did award the points. apparently, since i rejected answer before there is no option for me to accept answer at this time. please just resubmit or whatever is required and i'll happily award the points. thanks.
0
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.

All Courses

From novice to tech pro — start learning today.