I am building an applicaton, It will get all control have into application winform is running. First, I can inject dll into application winform is running and get handle of application winform is running. After I get all child window into applcation. Next, I want get all controls into child window by FindWindowEx. But I can't
Here is 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 a handle of child window and use it is parent. But I can't get all control into child window by FindWindowEx . Sorry for my english
解决方案
You can use the code below. Put it into a helper class somewhere, and e.g. use it like this...
var hwndChild = EnumAllWindows(hwndTarget, childClassName).FirstOrDefault();
You can 'lose' the class check if you wish - but usually you're checking for a specific target.
You may also wanna check this post I made a while go - which is using this method to set a focus on a remote window (and those scenarios are quite common, and you'll hit that snag sooner or later).
Pinvoke SetFocus to a particular 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; } }
我正在构建一个应用程序,它会得到所有的控制已经进入应用程序winform正在运行。首先,我可以注入dll到应用程序winform正在运行,并获得应用程序winform正在运行的句柄。后我得到所有的孩子窗口进入应用。接下来,我想通过FindWindowEx将所有控件都放到子窗口中。但我不能
这里是代码:
GetAllChildrenWindowHandles(IntPtr hParent,int maxCount) { ArrayList result = new ArrayList(); intct = 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; }
我得到一个子窗口的句柄,但我不能通过FindWindowEx的所有控制到子窗口。
对不起我的英语
解决方案
您可以使用下面的代码。把它放在一个帮助类的某个地方,使用它像这样...
var hwndChild = EnumAllWindows(hwndTarget,childClassName).FirstOrDefault
您可以'输掉' class 如果你愿意 - 但通常你正在检查一个特定的目标。
您可能也想检查这篇文章我做了一段时间 - 这是使用
此方法设置一个焦点远程窗口(这些情况是
很常见,你会迟早击中那个钩子)。
Pinvoke SetFocus到特定控件
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子进程) { if(GetWinClass(child)== childClassName) yield return child; foreach(var childchild in EnumAllWindows(child,childClassName)) yield return childchild; } }