Niza y concisa:
int GetZOrder(IntPtr hWnd)
{
var z = 0;
for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;
return z;
}
Si necesita más fiabilidad:
/// <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;
}
(De acuerdo con la sección de observaciones en GetWindow
, EnumChildWindows
es más seguro que llamar GetWindow
en un bucle porque su bucle GetWindow
no es atómico a cambios externos. De acuerdo con la sección Parámetros para EnumChildWindows
, llamando con una matriz nula es equivalente a EnumWindows
.)
Entonces, en lugar de una llamada independiente a EnumWindows
para cada ventana, que tampoco sería ser atómica y seguro de los cambios simultáneos, se envía cada ventana que desee comparar en una matriz de params para que sus órdenes z puedan recuperarse todas al mismo tiempo.
Y el "escritorio" debe poder usarse como la ventana padre especificando nulo para el elemento primario. Por lo tanto, puede obtener fácilmente la ventana de nivel superior en el escritorio. –
Esto no es confiable. 'GetNextWindow' simplemente llama a' GetWindow'. De la [referencia 'GetWindow'] (https://msdn.microsoft.com/en-us/library/ms633515 (v = vs.85) .aspx):" _Una aplicación que llama a GetWindow para realizar esta tarea corre el riesgo de ser atrapada en un bucle infinito o haciendo referencia a un identificador de una ventana que se ha destruido. " – zett42