12

Microsoft Spy++ を使用して、プロセスに属する次のウィンドウを確認できます。

Spy++ と同じように、ツリー形式で表示される XYZ ウィンドウ ハンドルを処理します。

A
  B
  C
     D
E
F
  G
  H
  I
  J
     K

プロセスを取得でき、MainWindowHandle プロパティはウィンドウ F のハンドルを指しています。 Process オブジェクトの MainWindowHandle で指定されたハンドルの子ではないウィンドウを列挙するにはどうすればよいですか?

列挙するには、win32 呼び出しを使用しています。

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

3 に答える 3

12

IntPtr.Zeroasを渡してhWnd、システム内のすべてのルート ウィンドウ ハンドルを取得します。

その後、 を呼び出して、ウィンドウの所有者プロセスを確認できます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 に答える