Nicea i lakoniczny:
int GetZOrder(IntPtr hWnd)
{
var z = 0;
for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;
return z;
}
Jeśli potrzebujesz więcej niezawodność:
/// <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;
}
(Według sekcji Uwagi o GetWindow
, EnumChildWindows
jest bezpieczniejsze niż wywoływanie GetWindow
w pętli, ponieważ twoja pętla GetWindow
nie jest atomowa dla zewnętrznych zmian. Według sekcji Parametry dla EnumChildWindows
, dzwonisz z pustym rodzica jest równoważna EnumWindows
.)
Wtedy zamiast osobnego wezwania do EnumWindows
dla każdego okna, które również nie można być atomowy i bezpieczny z jednoczesnych zmian wyślesz każde okno, które chcesz porównać w tablicy params, aby wszystkie zamówienia z-Z można było pobrać w tym samym czasie.
A "pulpit" powinien być używany jako okno nadrzędne przez podanie wartości NULL dla elementu nadrzędnego. Dzięki temu możesz łatwo uzyskać okno najwyższego poziomu na pulpicie. –
To nie jest niezawodne. 'GetNextWindow' po prostu wywołuje' GetWindow'. Z [odniesienia GetWindow] (https://msdn.microsoft.com/en-us/library/ms633515 (v = vs.85) .aspx): "_Anulacja, która wywołuje GetWindow w celu wykonania tego zadania, może zostać przyłapana w nieskończonej pętli lub odwołując się do uchwytu do okna, które zostało zniszczone._ " – zett42