Get child windows in correct Z-Order

I need to get a list of child windows in Z-order.  I'm currently using EnumChildWindows, but that doesn't seem to give me the results in sorted order.

My specific application is finding all top-level Internet Explorer or Netscape windows, in correct Z-order.

I'll give points for a good answer to any of the following questions:

1) A way to compare two sibling windows and determine which is higher up.  Otherwise if I use FindWindow and there are both MSIE and NS windows open, I won't know which is the highest one.

2) Reassure me that GetWindow can be used in such a way that it won't go into an infinite loop (preferably without remembering lots of hwnd's that I've already seen, but if that's the ONLY way...)  I don't care about hwnds that are killed halfway through.

3) A way for EnumChildWindows to give its results in sorted z-order.

4) Some other way...
newcumdbAsked:
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.

chensuCommented:
You can probably use GetTopWindow/GetNextWindow.
0
NickRepinCommented:
chensu is right. GetNextWindow is ok.
0
DarrinECommented:
You'll have to tweak this for it to work according to what you require - but this should answer your question.

int WINAPI GetSortedChildWindows (HWND hwnd)
{
 HWND FirstChildHwnd = GetTopWindow(hwnd);
 HWND NextChildHwnd = (HWND) NULL;

 int  NumWindows = 0;

 if (FirstChildHwnd)
    {
    do
      {
       NextChildHwnd = GetNextWindow(NextChildHwnd, GW_HWNDNEXT);
       NumWindows++;

       //
       // Place Function or Code to do what ever with the handle of the window here
       //

      } while (NextChildHwnd !=NULL);

    }

 return NumWindows;
}

Pass the window handle of the parent window you are wanting to interogate. The function returns the number of child windows interogated.

DarrinE

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
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

newcumdbAuthor Commented:
According to msdn, "Using this function [GetNextWindow] is the same as calling the GetWindow function with the GW_HWNDNEXT or GW_HWNDPREV flag set."

In the GetWindow documentation, "The EnumChildWindows function is more reliable than calling GetWindow in a loop. An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed."

I'm trying to develop a reliable library, and I'd like to be sure it won't get in an infinite loop (assuming a dead hwnd could be detected quickly...  even if it's been recreated, it'd have a different parent).

So your suggestions would work great as long you can assure me it won't get in infinite loop.  The author of the Hardcore VB manual says that it's never happened to him, but I'm still wary.  Does anyone know specifically why the disclaimer was put there?
0
DarrinECommented:
From my own experience I know that EnumChildWindows can reference a "lost window" - the loop I gave you can have a couple more lines added for additional security - see below.

As with all code the authors really cant guarantee it for another party because the author cant guarantee how it will be used or referenced etc - we have no control over how the code is used so out goes the guarantee.

I'm happy with the code and actually use something very similar in one of my products.

WINAPI GetSortedChildWindows (HWND hwnd)
{
 HWND FirstChildHwnd = GetTopWindow(hwnd);
 HWND NextChildHwnd = (HWND) NULL;

 int  NumWindows = 0;

 if (FirstChildHwnd)
    {
    do
      {
       NextChildHwnd = GetNextWindow(NextChildHwnd, GW_HWNDNEXT);
      if (IsWindow(NextChildHwnd))
       {
       NumWindows++;
       continue;
       }
       else
        break;

       //
       // Place Function or Code to do what ever with the handle of the window here
       //

      } while (NextChildHwnd !=NULL);

    }

 return NumWindows;
}

Remember - you'll need to tweak the code for your own purposes.

DarrinE
0
newcumdbAuthor Commented:
Legal disclaimers are different than a warning about infinite loops, especially when it's a basic OS call.  I guess I'll take that answer though since it's hard to know what the author meant when they wrote the documentation.

I'll cut off processing after some large number of windows processed (10,000?) to catch infinite loops.
0
DarrinECommented:
does that mean you accept my answer ??
0
newcumdbAuthor Commented:
Yeah.

:)  With the additional comment (in case anyone else happens along) that I'm an idiot and that Enum(Child)Windows does sort in Z-order, as does GetWindow.

Note to self: if the contents of a listbox LOOK like they're sorted in dictionary order, maybe it's not the underlying data's fault.

Thanks for your comments though.  :)
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
Microsoft Development

From novice to tech pro — start learning today.