我有给定窗口的句柄.我如何枚举其子窗口?
这里有一个有效的解决方案:
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 ListGetAllChildHandles() { List childHandles = new List (); 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 childHandles = gcChildhandlesList.Target as List ; 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函数的所有子窗口.最好不要重新发明轮子.
使用带有p/invoke的EnumChildWindows.这是一个关于它的一些行为的有趣链接:https: //blogs.msdn.microsoft.com/oldnewthing/20070116-04/?p = 2893
如果你不知道窗口的句柄,只知道它的标题,你需要使用EnumWindows.http://pinvoke.net/default.aspx/user32/EnumWindows.html