Nice et laconique:
int GetZOrder(IntPtr hWnd)
{
var z = 0;
for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;
return z;
}
Si vous avez besoin plus de fiabilité:
/// <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;
}
(Selon la section Remarques sur GetWindow
, EnumChildWindows
est plus sûr que d'appeler GetWindow
dans une boucle parce que votre boucle GetWindow
n'est pas atomique à des changements extérieurs. Selon la section Paramètres pour EnumChildWindows
, appeler avec un parent nul équivaut à EnumWindows
.)
Alors, au lieu d'un appel séparé à EnumWindows
pour chaque fenêtre, ce qui serait également ne pas être atomique et à l'abri des changements simultanés, vous envoyez chaque fenêtre que vous voulez comparer dans un tableau params afin que leurs ordres z puissent tous être récupérés en même temps.
Et le "bureau" devrait pouvoir être utilisé comme la fenêtre parente en spécifiant null pour le parent. Par conséquent, vous pouvez facilement obtenir la fenêtre de niveau supérieur sur le bureau. –
Ce n'est pas fiable. 'GetNextWindow' appelle simplement' GetWindow'. De la référence ['GetWindow'] (https://msdn.microsoft.com/en-us/library/ms633515 (v = vs.85) .aspx):" _Une application qui appelle GetWindow pour effectuer cette tâche risque d'être interceptée dans une boucle infinie ou référençant un handle à une fenêtre qui a été détruite._ " – zett42