Click here to Skip to main content
15,887,083 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm using Interop Services, trying to find all child windows in a process that I run from within my app. The app being run is IE. It finds the first two (BrowserFrameGripperClass and Client Caption) and then simply quits.

Relevant code:

C#
public static class WinAPI
{
    public delegate bool WindowEnumProc(IntPtr hwnd, IntPtr lparam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc callback, IntPtr lParam);
}

class public MyClass
{
    public IntPtr HWnd { get; set; }
    public List<IntPtr> Children { get; set; }
 
    public MyClass(IntPtr hwnd)
    {
    }

    public void RefreshChildren()
    {
        if (this.Children == null)
        {
            this.Children = new List<WindowHandle>();
        }
        else
        {
            this.Children.Clear();
        }
        if (this.HWnd != IntPtr.Zero)
        {
            List<IntPtr> childHandles = new List<IntPtr>();
            GCHandle gch = GCHandle.Alloc(childHandles);
            try
            {
                WinAPI.WindowEnumProc childProc = new WinAPI.WindowEnumProc(EnumerateChildWindow);
                WinAPI.EnumChildWindows(this.HWnd, childProc, GCHandle.ToIntPtr(gch));
                List<IntPtr> list = gch.Target as List<IntPtr>;
                foreach (IntPtr child in list)
                {
                    Children.Add(new WindowHandle(child));
                }
            }
            finally
            {
                if (gch.IsAllocated)
                {
                    gch.Free();
                }
            }
        }
    }

    public bool EnumerateChildWindow(IntPtr hwnd, IntPtr lParam)
    {
        bool result = true;
        GCHandle gch = GCHandle.FromIntPtr(lParam);
        List<IntPtr> list = gch.Target as List<IntPtr>;
        result = (list.Count == 0);
        if (list != null)
        {
            list.Add(hwnd);
        }
        return result;
    }

}
Posted
Comments
#realJSOP 9-Sep-14 10:31am    
If you're not going to answer the question, STFU.
[no name] 9-Sep-14 10:41am    
It's a troll John. Don't bother.
[no name] 9-Sep-14 14:09pm    
hahaha
George Jonsson 9-Sep-14 10:32am    
Rather ask every child about their children.
And do it recursively with the end state "children == null"
#realJSOP 9-Sep-14 10:55am    
EnumChildWindows is *supposed* to enumerate all child windows and their children - if you recurse, you'll get all the windows more than once. My problem is that it's not even getting all of the main IE window's child windows. I don't know if this has anything to do with it, but it only found child windows that don't have their own child windows. These child windows are also the first two I see with Spy++.

If you open IE and then inspect the window with Spy++, you'll see what I mean.

Hi John,

Just a quick message - no solution I fear... Just want to tell you what I found out (or not)...

The documentation for EnumerateChildWindow states:

Enumerates the child windows that belong to the specified parent window by passing the handle to each child window, in turn, to an application-defined callback function. EnumChildWindows continues until the last child window is enumerated or the callback function returns FALSE

I suspect one (!) error is in the condition.
C#
result = (list.Count == 0)


If I try your code without this condition to enumerate VisualStudio's child windows I get ~10 but with your condition only 2... On iexplore it doesn't work at all on my system - the callback seems to be never called... ??? Sorry I didn't find the time to find out what may be the problem on my system. (I also tested with the original code found at )[^] - same results - not any childwindow for iexplore is found...

Anyway I can't spot any mistake in your code (except the above condition which is I think just an "additional" error).

Kind regards

Johannes
 
Share this answer
 
v2
Comments
Richard Deeming 9-Sep-14 11:43am    
I've just tried John's code modified to return true from the call-back, and the list of enumerated handles matches the Spy++ list.
#realJSOP 9-Sep-14 13:10pm    
I also tried it, and it almost matches. I have an intranet site up, and the innermost child window in the client area (it's a Internet Explorer_Server class) isn't being enumerated, but I think getting the parent TabWindowClass window will be sufficient.
I changed the logic in
C#
public bool EnumerateChildWindow(IntPtr hwnd, IntPtr lParam)
{
    bool result = false ;
    GCHandle gch = GCHandle.FromIntPtr(lParam);
    List<IntPtr> list = gch.Target as List<IntPtr>;
    if (list != null)
    {
        list.Add(hwnd);
        result = true; // return true as long as children are found
    }
    return result;
}


The result is list of children, some with names and some without.
1 -
2 - Navigation Bar
3 -
4 -
5 -
6 -
7 -
8 -
9 - Address Combo Control
10 - Page Control
11 -
12 -
13 - SeConnect
14 -
15 - Search Combo Control
16 - Search Control
17 -
18 -
19 -
20 - Command Bar
21 -
22 -
23 -
24 - Favorites Command Bar
25 - LinksBand
26 - Favorites Bar
27 - Add to Favorites Bar
28 -
29 - ITBarHost
30 - Menu Bar
31 -
32 -
33 - Bing - Windows Internet Explorer provided by ...
34 -
35 -
36 - Zoom Level
37 -
38 -
39 -


I run the code from a console application and get the handle to the IE8 window via GetWindow.
Not sure if that has any significance.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900