如何在Windows中获得z顺序?

use*_*526 22 .net c# windows z-order

我正在创建一个应用程序,我在其中与每个正在运行的应用程 现在,我需要一种获取窗口z顺序的方法.例如,如果Firefox和记事本正在运行,我需要知道哪一个在前面.

有任何想法吗?除了为每个应用程序的主窗口执行此操作外,我还需要为其子窗口和姐妹窗口(属于同一进程的窗口)执行此操作.

Nin*_*rry 9

您可以使用GetTopWindow函数搜索父窗口的所有子窗口,并将句柄返回到z顺序最高的子窗口.GetNextWindow函数以z顺序检索下一个或上一个窗口的句柄.

GetTopWindow:http://msdn.microsoft.com/en-us/library/ms633514(
VS.85 ).aspx GetNextWindow:http://msdn.microsoft.com/en-us/library/ms633509( VS85 )的.aspx

  • 并且"桌面"应该可以用作父窗口,为父窗口指定null.因此,您可以轻松地在桌面上获得顶级窗口. (4认同)
  • 这是不可靠的。`GetNextWindow` 只是调用 `GetWindow`。来自 [`GetWindow` 参考](https://msdn.microsoft.com/en-us/library/ms633515(v=vs.85).aspx):“_调用 GetWindow 来执行此任务的应用程序有被捕获的风险在无限循环中或引用已被销毁的窗口的句柄。_” (4认同)

jnm*_*nm2 8

好又简洁:

int GetZOrder(IntPtr hWnd)
{
    var z = 0;
    for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;
    return z;
}
Run Code Online (Sandbox Code Playgroud)

如果您需要更高的可靠性:

/// <summary>
/// Gets the z-order for one or more windows atomically with respect to each other. In Windows, smaller z-order is higher. If the window is not top level, the z order is returned as -1. 
/// </summary>
int[] GetZOrder(params IntPtr[] hWnds)
{
    var z = new int[hWnds.Length];
    for (var i = 0; i < hWnds.Length; i++) z[i] = -1;

    var index = 0;
    var numRemaining = hWnds.Length;
    EnumWindows((wnd, param) =>
    {
        var searchIndex = Array.IndexOf(hWnds, wnd);
        if (searchIndex != -1)
        {
            z[searchIndex] = index;
            numRemaining--;
            if (numRemaining == 0) return false;
        }
        index++;
        return true;
    }, IntPtr.Zero);

    return z;
}
Run Code Online (Sandbox Code Playgroud)

(根据备注部分GetWindow,EnumChildWindowsGetWindow在循环中调用更安全,因为你的GetWindow循环对于外部更改不是原子的.根据参数部分EnumChildWindows,使用null父进行调用相当于EnumWindows.)

然后,而不是EnumWindows对每个窗口进行单独调用,这对于并发更改也不是原子的和安全的,您可以在params数组中发送要比较的每个窗口,这样它们的z顺序可以同时被检索.