Getting All Child Window Handles using C# P/Invoke FindWindowEx

Recently I was working with the C# P/Invoke mechanism to perform some low-level UI automation on a desktop application. I needed a helper function that, for a given control window, would fetch the handles of all child control windows. For example, in the image below, I have a dummy WinForm application, which is itself a window. The form has four child windows (panel controls colored so you can see them). The Spy++ tool shows that the handle of the WinForm is 611150 and that the handles of the four children are 111142, 121112, 1210CA, and 1C104C. The console app shows the result of programmatically getting the children.

The function, which I named GetAllChildrenWindowHandles is:

static List GetAllChildrenWindowHandles(IntPtr hParent,
  int maxCount)
  List result = new List();
  int ct = 0;
  IntPtr prevChild = IntPtr.Zero;
  IntPtr currChild = IntPtr.Zero;
  while (true && ct < maxCount)
    currChild = FindWindowEx(hParent, prevChild, null, null);
    if (currChild == IntPtr.Zero) break;
    prevChild = currChild;
  return result;

The key is the FindWindowEx P/Invoke function defined as:

[DllImport("user32.dll", EntryPoint = "FindWindowEx",
  CharSet = CharSet.Auto)]
static extern IntPtr FindWindowEx(IntPtr hwndParent,
  IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

In particular, the second parameter which tells FindWindoEx where to start looking for a child handle. The calling code looks like:

// launch app first
IntPtr appHandle = FindWindow(null, "Form1"); // P/Invoke
Console.WriteLine("App handle = " + appHandle.ToString("X"));
List children = GetAllChildrenWindowHandles(appHandle, 100);

Console.WriteLine("Children handles are:");
for (int i = 0; i < children.Count; ++i)

Anyway, this was a surprisingly interesting little problem, especially because I hadn’t worked with P/Invoke for a while.


This entry was posted in Software Test Automation. Bookmark the permalink.