简体   繁体   English

通过FindWindowEx获取所有控件

[英]get all controls by FindWindowEx

I am building an applicaton, It will get all control have into application winform is running. 我正在构建一个应用程序,它将使所有控件都进入应用程序winform运行中。 First, I can inject dll into application winform is running and get handle of application winform is running. 首先,我可以将dll注入正在运行的应用程序winform中,并获取正在运行的应用程序winform的句柄。 After I get all child window into applcation. 我将所有子窗口放入应用程序之后。 Next, I want get all controls into child window by FindWindowEx. 接下来,我想通过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 . 但是我无法通过FindWindowEx将所有控件放到子窗口中。 Sorry for my english 对不起我的英语不好

You can use the code below. 您可以使用下面的代码。 Put it into a helper class somewhere, and eg 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. 您可以根据需要“丢失” class检查-但通常是在检查特定目标。

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

Try Spy++ and see the controls you are trying to enumerate are windows or not. 尝试使用Spy ++,然后查看要枚举的控件是否为Windows。 If they are not windows, you can not enumerate them using this API. 如果它们不是Windows,则无法使用此API枚举它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM