0

I need to list all child controls of a Windows, but in exacly the same order that appear in the window.

I have this code;

    public static List<IntPtr> GetWindowControls(IntPtr hWnd)
    {
        List<IntPtr> result = new List<IntPtr>();
        GCHandle listHandle = GCHandle.Alloc(result);

        try
        {
            EnumWindowProc childProc = new EnumWindowProc(EnumWindowControls);
            EnumChildWindows(hWnd, childProc, GCHandle.ToIntPtr(listHandle));
        }
        finally
        {
            if (listHandle.IsAllocated)
                listHandle.Free();
        }
        return result;
    }

    private static bool EnumWindowControls(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>");

        string className = Helpers.WinApi.GetWinClass(handle).ToUpper();
        if (className.Contains("EDIT") || className.Contains("COMBOBOX") || className.Contains("STATIC") || className.Contains("BUTTON"))
            list.Add(handle);
        return true;
    }

After the execution of that method, I get a Windows list, but with any order.

jstuardo
  • 3,901
  • 14
  • 61
  • 136
  • 1
    It'd be in the z-order (tab order), which is not necessarily the top-to-bottom order. – Jonathan Potter Mar 30 '16 at 22:18
  • Tab order is correctly defined. This is a Winforms C# application where I placed some labels and textboxes. At the end of the form, I have placed 3 dropdowns. TabOrder is correctly set in form, and in fact, I have checked it again by using TAB key. The first item is the first TextBox that appear in form, then I can navigate the controls using TAB until I reach the dropdows. When using EnumChildWindows, first controls added are the dropdowns. – jstuardo Mar 30 '16 at 22:26
  • There is not any way you are going to get the TabIndex property of Winforms controls with this code. You need to stop trying. – Hans Passant Mar 30 '16 at 22:29
  • Get theTabindex property? I just need to list controls with the same order as visible in the window. – jstuardo Mar 30 '16 at 22:32
  • What order do you mean? Tab Order? Z-Index? Order of appearance Left To Right / Top Down? And are you trying to get controls of a form of your application or another application? – Reza Aghaei Mar 30 '16 at 23:37
  • Generally speaking, when enumerating objects of any sort they will not be enumerated in any particular order unless there is a specific reason why such an ordering would be generally useful. Also, where there *is* such a reason, the ordering will usually be clearly documented. If the documentation doesn't say the output will be ordered, assume that it won't. – Harry Johnston Mar 31 '16 at 05:08
  • @RezaAghaei Order that appear in the form from the currently active window that is not my own application. – jstuardo Mar 31 '16 at 10:14

2 Answers2

1

EnumChildWindows does not give you the windows in the order you want. You will have to ask each window for its position and then order the windows yourself based on those positions.

You will need to decide what order to use. Top to bottom, then left to right. Or left to right, then to to bottom. Or perhaps some other order.

You can use GetWindowRect to obtain the bounding rect for each window.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

EnumChildWindows enumerates the child windows that belong to the specified parent window by passing the handle to each child window, They are enumerated based on the windows Z Order.

Setting proper Z order for all the windows will solve your problem

  • I need to enumerate controls from other application, so I cannot control how it was developed. Is it possible to get Client coordinates of the found controls? I think that way I can solve the problem. – jstuardo Mar 31 '16 at 10:16