如何获得给定HWND窗口的子窗口?

我有给定窗口的句柄。 我怎样枚举它的子窗口?

在这里你有一个工作解决方案:

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; } } 

如何使用它:

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

使用:

 internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam); [DllImport("user32.dll")] internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam); 

你会得到你传递的函数的回调。

我找到了最好的解决方案来管理WindowsAPI 。 它有一个CrossHair控件,可以用来选择一个窗口(不是问题的一部分),以及一个方法AllChildWindows来获取所有可能包裹EnumChildWindows函数的子窗口。 最好不要重新发明轮子。

使用EnumChildWindows,与p / invoke。 以下是一些有关其行为的有趣链接: https : //blogs.msdn.microsoft.com/oldnewthing/20070116-04/?p = 28393

如果你不知道窗口的句柄,但只有它的标题,你需要使用EnumWindows。 http://pinvoke.net/default.aspx/user32/EnumWindows.html

这是EnumWindows的一个托管替代方法,但是您仍然需要使用EnumChildWindows来查找子窗口的句柄。

 foreach (Process process in Process.GetProcesses()) { if (process.MainWindowTitle == "Title to find") { IntPtr handle = process.MainWindowHandle; // Use EnumChildWindows on handle ... } }