Get all controls with FindWindowEx

I create an application, it will get all the controls in the winform application. First, I can add a dll to the winform application and run the winform application descriptor. After I get the whole child window in applcation. Then I want to get all the controls in the FindWindowEx child window. But I can not

Here is the code:

static ArrayList GetAllChildrenWindowHandles(IntPtr hParent, int maxCount) { ArrayList result = new ArrayList(); 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) { int errorCode = Marshal.GetLastWin32Error(); break; } result.Add(currChild); prevChild = currChild; ++ct; } return result; } 

I get the handle of the child window and use its parent. But I can’t get all the control over the FindWindowEx child window. sorry for my English

+2
source share
2 answers

You can use the code below. Put it in a helper class somewhere and, for example, use it like this ...

 var hwndChild = EnumAllWindows(hwndTarget, childClassName).FirstOrDefault(); 

You can β€œlose” a class check if you want, but usually you check a specific target.

You may also want to check out this post, which I made for a while - that using this method allows you to focus on a remote window (and these scripts are pretty common, and you will fall into this trap sooner or later).
Pinvoke SetFocus for a specific control

 public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam); [DllImport("user32.Dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] static public extern IntPtr GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount); private static bool EnumWindow(IntPtr handle, IntPtr pointer) { GCHandle gch = GCHandle.FromIntPtr(pointer); List<IntPtr> list = gch.Target as List<IntPtr>; if (list == null) throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>"); list.Add(handle); return true; } public static List<IntPtr> GetChildWindows(IntPtr parent) { List<IntPtr> result = new List<IntPtr>(); GCHandle listHandle = GCHandle.Alloc(result); try { Win32Callback childProc = new Win32Callback(EnumWindow); EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle)); } finally { if (listHandle.IsAllocated) listHandle.Free(); } return result; } public static string GetWinClass(IntPtr hwnd) { if (hwnd == IntPtr.Zero) return null; StringBuilder classname = new StringBuilder(100); IntPtr result = GetClassName(hwnd, classname, classname.Capacity); if (result != IntPtr.Zero) return classname.ToString(); return null; } public static IEnumerable<IntPtr> EnumAllWindows(IntPtr hwnd, string childClassName) { List<IntPtr> children = GetChildWindows(hwnd); if (children == null) yield break; foreach (IntPtr child in children) { if (GetWinClass(child) == childClassName) yield return child; foreach (var childchild in EnumAllWindows(child, childClassName)) yield return childchild; } } 
+4
source

Try Spy ++ and see which controls you are trying to list, whether they are windows or not. If they are not windows, you cannot list them using this API.

0
source

Source: https://habr.com/ru/post/1012277/


All Articles