I have the handle for a given window. How can I enumerate its child windows?

4

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(); } } } 
5

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.

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.

Use EnumChildWindows, with p/invoke. Here's an interesting link about some of it's behavior:

If you don't know the handle of the window, but only it's title, you'll need to use EnumWindows.

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 ... } } 
2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.