12

使用 Microsoft Spy++,我可以看到属于一个进程的以下窗口:

处理 XYZ 窗口句柄,以树形式显示,就像 Spy++ 给我的一样:

A
  B
  C
     D
E
F
  G
  H
  I
  J
     K

我可以得到进程,MainWindowHandle 属性指向窗口 F 的句柄。如果我使用枚举子窗口,我可以获得 G 到 K 的窗口句柄列表,但我不知道如何找到窗口A 到 D 的句柄。如何枚举不是由 Process 对象的 MainWindowHandle 指定的句柄的子窗口?

枚举我正在使用 win32 调用:

[System.Runtime.InteropServices.DllImport(strUSER32DLL)]
            public static extern int EnumChildWindows(IntPtr hWnd, WindowCallBack pEnumWindowCallback, int iLParam);
4

3 回答 3

12

通过IntPtr.ZeroashWnd获取系统中的每个根窗口句柄。

然后,您可以通过调用来检查 Windows 的所有者进程GetWindowThreadProcessId

于 2010-06-10T22:45:53.640 回答
11

对于仍然想知道的每个人,这就是答案:

List<IntPtr> GetRootWindowsOfProcess(int pid)
{
    List<IntPtr> rootWindows = GetChildWindows(IntPtr.Zero);
    List<IntPtr> dsProcRootWindows = new List<IntPtr>();
    foreach (IntPtr hWnd in rootWindows)
    {
        uint lpdwProcessId;
        WindowsInterop.User32.GetWindowThreadProcessId(hWnd, out lpdwProcessId);
        if (lpdwProcessId == pid)
            dsProcRootWindows.Add(hWnd);
    }
    return dsProcRootWindows;
}

public static List<IntPtr> GetChildWindows(IntPtr parent)
{
    List<IntPtr> result = new List<IntPtr>();
    GCHandle listHandle = GCHandle.Alloc(result);
    try
    {
        WindowsInterop.Win32Callback childProc = new WindowsInterop.Win32Callback(EnumWindow);
        WindowsInterop.User32.EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
        if (listHandle.IsAllocated)
            listHandle.Free();
    }
    return result;
}

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);
    //  You can modify this to check to see if you want to cancel the operation, then return a null here
    return true;
}

对于 Windows 互操作:

public delegate bool Win32Callback(IntPtr hwnd, IntPtr lParam);

对于 WindowsInterop.User32:

[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

[DllImport("user32.Dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam);

现在可以通过 GetRootWindowsOfProcess 简单地获取每个根窗口,并通过 GetChildWindows 获取它们的子窗口。

于 2014-03-16T17:42:42.393 回答
8

您可以使用EnumWindows获取每个顶级窗口,然后根据GetWindowThreadProcessId.

于 2010-06-10T22:49:27.627 回答