I have the handle for a given window. How can I enumerate its child windows?
-
1In general. I can get the HWND of the window I'd like to enumerate from. – Yuriy Faktorovich Sep 01 '09 at 16:12
-
Excellent - i've updated your question to make this clear. – Shog9 Sep 01 '09 at 16:25
-
1assume you know about spy++. Useful tool for working with this stuff. – David Sep 01 '09 at 17:21
-
1I do, if you liked spy++, you might want to try Winspector spy. I found it to be easier to use with more options. – Yuriy Faktorovich Sep 01 '09 at 19:09
5 Answers
Here you have a working solution:
public class WindowHandleInfo
{
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);
private IntPtr _MainHandle;
public WindowHandleInfo(IntPtr handle)
{
this._MainHandle = handle;
}
public List<IntPtr> GetAllChildHandles()
{
List<IntPtr> childHandles = new List<IntPtr>();
GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);
}
finally
{
gcChildhandlesList.Free();
}
return childHandles;
}
private bool EnumWindow(IntPtr hWnd, IntPtr lParam)
{
GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);
if (gcChildhandlesList == null || gcChildhandlesList.Target == null)
{
return false;
}
List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;
childHandles.Add(hWnd);
return true;
}
}
How to consume it:
class Program
{
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
static void Main(string[] args)
{
Process[] anotherApps = Process.GetProcessesByName("AnotherApp");
if (anotherApps.Length == 0) return;
if (anotherApps[0] != null)
{
var allChildWindows = new WindowHandleInfo(anotherApps[0].MainWindowHandle).GetAllChildHandles();
}
}
}

- 2,801
- 4
- 32
- 40

- 1,161
- 1
- 9
- 19
-
-
1@jai It's a Windows library, it's already present and registered in your machine. That code should work without the need for additional references. – Caffé May 28 '15 at 15:27
-
thanks @caffe.... But actually if i use user32.dll , the application asking some kind of permission...where i can couldn't run the application...how can i resolve that... – jai May 29 '15 at 06:10
-
-
[pinvoke.net](http://pinvoke.net/default.aspx/user32.EnumChildWindows) is a great place for references to using the win API. – Josh Gust Aug 29 '18 at 16:35
Using:
internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
[DllImport("user32.dll")]
internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
you will get callbacks on the function you pass in.

- 35,875
- 47
- 158
- 240
I've found the best solution to be Managed WindowsAPI. It had a CrossHair control that could be used to select a window(not part of the question), and a method AllChildWindows to get all child windows which likely wrapped the EnumChildWindows function. Better not to reinvent the wheel.

- 67,283
- 14
- 105
- 142
Use EnumChildWindows, with p/invoke. Here's an interesting link about some of it's behavior: https://blogs.msdn.microsoft.com/oldnewthing/20070116-04/?p=28393
If you don't know the handle of the window, but only it's title, you'll need to use EnumWindows. http://pinvoke.net/default.aspx/user32/EnumWindows.html

- 86,735
- 21
- 136
- 138

- 22,355
- 2
- 39
- 64
Here is a managed alternative to EnumWindows, but you will still need to use EnumChildWindows to find the handle of the child window.
foreach (Process process in Process.GetProcesses())
{
if (process.MainWindowTitle == "Title to find")
{
IntPtr handle = process.MainWindowHandle;
// Use EnumChildWindows on handle ...
}
}

- 476
- 3
- 15
-
-
1Epu, if there is not a main window then the process will not have a window handle to obtain (ie. Process.MainWindowHandle == IntPtr.Zero). – Special Touch Oct 07 '11 at 21:31