度日FindWindowEx所有控件 [英] get all controls by FindWindowEx

查看:141
本文介绍了度日FindWindowEx所有控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我构建的一个应用,它会得到所有的控制都成应用程序的winform正在运行。首先,我可以注入DLL到应用程序的winform正在运行,并得到应用的winform的手柄运行。之后,我得到的所有子窗口进入的applcation。接下来,我想通过FindWindowEx得到所有的控件到子窗口。但我不能

下面是code:

 静态的ArrayList GetAllChildrenWindowHandles(IntPtr的设定hParent,诠释MAXCOUNT)
    {
        ArrayList的结果=新的ArrayList();
        INT克拉= 0;
        IntPtr的prevChild = IntPtr.Zero;
        IntPtr的currChild = IntPtr.Zero;
        而(真放;&安培; CT< MAXCOUNT)
        {
            currChild = FindWindowEx(设定hParent,prevChild,NULL,NULL);
            如果(currChild == IntPtr.Zero)
            {
                INT错误code = Marshal.GetLastWin32Error();
                打破;
            }
            result.Add(currChild);
            prevChild = currChild;
            ++ CT;
        }
        返回结果;
    }

我得到的子窗口的句柄,并用它的母公司。但我不能让所有的控制到由FindWindowEx子窗口。
对不起,我的英语


解决方案

您可以用code以下。把它放进一个辅助类的地方,例如和使用它像这样...

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

您可以丢失检查,如果你想 - 但通常你在检查一个具体的目标。


  

您也可能想检查这个职位,我做了,而走了 - 这是使用
  此方法来设置焦点远程窗口上(以及这些方案是
  相当普遍,你会打的障碍迟早)。结果
  <一href=\"http://stackoverflow.com/questions/9503027/pinvoke-setfocus-to-a-particular-control/9547099#9547099\">Pinvoke SetFocus的一个特定的控制


 公共委托布尔Win32Callback(IntPtr的HWND,IntPtr的lParam的);函数[DllImport(USER32.DLL)]
[返回:的MarshalAs(UnmanagedType.Bool)
公共静态的extern BOOL EnumChildWindows(IntPtr的parentHandle,Win32Callback回调,IntPtr的lParam的);函数[DllImport(user32.dll中,字符集= CharSet.Auto)
静态公共EXTERN的IntPtr GetClassName(IntPtr的的HWND,System.Text.StringBuilder lpClassName,诠释nMaxCount);私人静态布尔EnumWindow(IntPtr的手柄,IntPtr的指针)
{
    的GCHandle GCH = GCHandle.FromIntPtr(指针);
    清单&LT; IntPtr的&GT;清单= gch.Target的名单,LT; IntPtr的取代;
    如果(名单== NULL)
        抛出新InvalidCastException的(目标的GCHandle无法转换为表&LT; IntPtr的&GT;);
    list.Add(手柄);
    返回true;
}公共静态列表&LT; IntPtr的&GT; GetChildWindows(IntPtr的父母)
{
    清单&LT; IntPtr的&GT;结果=新的List&LT; IntPtr的&GT;();
    的GCHandle listHandle = GCHandle.Alloc(结果);
    尝试
    {
        Win32Callback childProc =新Win32Callback(EnumWindow);
        EnumChildWindows(父母,childProc,GCHandle.ToIntPtr(listHandle));
    }
    最后
    {
        如果(listHandle.IsAllocated)
            listHandle.Free();
    }
    返回结果;
}公共静态字符串GetWinClass(IntPtr的HWND)
{
    如果(HWND == IntPtr.Zero)
        返回null;
    StringBuilder的类名=新的StringBuilder(100);
    IntPtr的结果= GetClassName(HWND,类名,classname.Capacity);
    如果(结果!= IntPtr.Zero)
        返回classname.ToString();
    返回null;
}公共静态的IEnumerable&LT; IntPtr的&GT; EnumAllWindows(IntPtr的HWND,字符串childClassName)
{
    清单&LT; IntPtr的&GT;孩子= GetChildWindows(HWND);
    如果(孩子== NULL)
        产生中断;
    的foreach(IntPtr的孩子的孩子)
    {
        如果(GetWinClass(子)== childClassName)
            产生收益的孩子;
        的foreach(在EnumAllWindows VAR childchild(儿童,childClassName))
            产生回报childchild;
    }
}

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

这篇关于度日FindWindowEx所有控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆