通过FindWindowEx获取所有控件 [英] get all controls by FindWindowEx
问题描述
我正在构建一个应用程序,它会得到所有的控制已经进入应用程序winform正在运行。首先,我可以注入dll到应用程序winform正在运行,并获得应用程序winform正在运行的句柄。后我得到所有的孩子窗口进入应用。接下来,我想通过FindWindowEx将所有控件都放到子窗口中。但我不能
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
这里是代码:
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;
}
我得到一个子窗口的句柄,但我不能通过FindWindowEx的所有控制到子窗口。
对不起我的英语
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();
您可以'输掉' class
如果你愿意 - 但通常你正在检查一个特定的目标。
You can 'lose' the class
check if you wish - but usually you're checking for a specific target.
您可能也想检查这篇文章我做了一段时间 - 这是使用
此方法设置一个焦点远程窗口(这些情况是
很常见,你会迟早击中那个钩子)。
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 child in children)
{
if (GetWinClass(child) == childClassName)
yield return child;
foreach (var childchild in EnumAllWindows(child, childClassName))
yield return childchild;
}
}
这篇关于通过FindWindowEx获取所有控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!