Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is EnumChildWindows skipping children?

Tags:

c#

winapi

I'm getting strange behavior when it comes to using the Windows API method EnumChildWindows. It seems to not be picking up a section of children windows. When I drill down using Spy++ I can see the children, but when I execute my code, it doesn't return the ones I see in Spy++.

What I see in Spy++ What I see in Spy++ http://img24.imageshack.us/img24/9264/spyhandles.png

Here is my code:

public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

    [DllImport("user32")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);

    public static List<IntPtr> GetChildWindows(IntPtr parent)
    {
        List<IntPtr> result = new List<IntPtr>();
        GCHandle listHandle = GCHandle.Alloc(result);
        try
        {
            EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
            EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
        }
        finally
        {
            if (listHandle.IsAllocated)
                listHandle.Free();
        }
        return result;
    }

    private static bool EnumWindow(IntPtr handle, IntPtr pointer)
    {
        GCHandle gch = GCHandle.FromIntPtr(pointer);
        List<IntPtr> list = gch.Target as List<IntPtr>;
        if (list == null)
            throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");

        list.Add(handle);            
        return true;
    }

Is there a reason as to why the highlighted red section in the screenshot above would not get populated into my collection (List<IntPtr>) when calling EnumChildWindows?

like image 677
Dekryptid Avatar asked Aug 10 '11 16:08

Dekryptid


1 Answers

Doh! I discovered the errors of my ways. The reason why I was only getting half of the children was due to the fact I was not waiting long enough for the window to initially load and create ALL of the children within it, therefore I was only getting the first half that it created at the time I was calling my function to obtain all child windows. So I added a line of code to sleep before calling EnumChildWindows().

"Windows does not call the callback function for any child windows created after EnumChildWindows is called but before it returns." - Source

The above quoted piece of information is what turned the light-bulb on in my head.

like image 105
Dekryptid Avatar answered Sep 24 '22 13:09

Dekryptid