5

私はアプリケーションを構築しています.winformが実行されているアプリケーションにすべてのコントロールを取得します. まず、winform が実行されているアプリケーションに dll を挿入し、winform が実行されているアプリケーションのハンドルを取得します。すべての子ウィンドウをアプリケーションに入れた後。次に、FindWindowEx で子ウィンドウにすべてのコントロールを取得します。しかし、私はできません

コードは次のとおりです。

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 ですべてのコントロールを子ウィンドウに入れることはできません。私の英語でごめんなさい

4

2 に答える 2

7

以下のコードを使用できます。どこかのヘルパークラスに入れて、たとえば次のように使用します...

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

class必要に応じてチェック を「失う」こともできますが、通常は特定のターゲットをチェックしています。

また、しばらく前に作成したこの投稿を確認することもできます-この方法を使用して、リモートウィンドウにフォーカスを設定しています(これらのシナリオは非常に一般的であり、遅かれ早かれその障害にぶつかることになります)。
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;
    }
}
于 2013-04-24T17:12:41.463 に答える
1

Spy++ を試して、列挙しようとしているコントロールがウィンドウかどうかを確認してください。それらがウィンドウでない場合、この API を使用してそれらを列挙することはできません。

于 2013-04-25T10:06:09.633 に答える