c# - index - ¿Cómo obtener el orden z en windows?
wpf grid z index (4)
Agradable y terso:
int GetZOrder(IntPtr hWnd)
{
var z = 0;
for (var h = hWnd; h != IntPtr.Zero; h = GetWindow(h, GW.HWNDPREV)) z++;
return z;
}
Si necesitas 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 Comentarios en GetWindow
, EnumChildWindows
es más seguro que llamar a GetWindow
en un bucle porque su bucle GetWindow
no es atómico a los cambios externos. De acuerdo con la sección de Parámetros para EnumChildWindows
, llamar con un padre nulo es equivalente a EnumWindows
).
Luego, en lugar de una llamada separada a EnumWindows
para cada ventana, que tampoco sería atómica y estaría a salvo de los cambios simultáneos, usted envía cada ventana que desea comparar en una matriz de parámetros para que sus órdenes z puedan recuperarse al mismo tiempo. .
Estoy creando una aplicación en la que interactúo con cada aplicación en ejecución. En este momento, necesito una forma de obtener el orden z de la ventana. Por ejemplo, si Firefox y el bloc de notas se están ejecutando, necesito saber cuál está al frente.
¿Algunas ideas? Además de hacer esto para cada ventana principal de la aplicación, también necesito hacerlo para sus ventanas hijas y hermanas (ventanas que pertenecen al mismo proceso).
Aquí está mi solución de C #: La función devuelve el índice zIndex entre los hermanos del HWND dado, comenzando en 0 para el zOrder más bajo.
using System;
using System.Runtime.InteropServices;
namespace Win32
{
public static class HwndHelper
{
[DllImport("user32.dll")]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
public static bool GetWindowZOrder(IntPtr hwnd, out int zOrder)
{
const uint GW_HWNDPREV = 3;
const uint GW_HWNDLAST = 1;
var lowestHwnd = GetWindow(hwnd, GW_HWNDLAST);
var z = 0;
var hwndTmp = lowestHwnd;
while (hwndTmp != IntPtr.Zero)
{
if (hwnd == hwndTmp)
{
zOrder = z;
return true;
}
hwndTmp = GetWindow(hwndTmp, GW_HWNDPREV);
z++;
}
zOrder = int.MinValue;
return false;
}
}
}
Puede utilizar la función GetTopWindow para buscar todas las ventanas secundarias de una ventana primaria y devolver un identificador a la ventana secundaria que está más arriba en orden z. La función GetNextWindow recupera un identificador de la ventana siguiente o anterior en orden z.
GetTopWindow: http://msdn.microsoft.com/en-us/library/ms633514(VS.85).aspx
GetNextWindow: http://msdn.microsoft.com/en-us/library/ms633509(VS.85).aspx
// Find z-order for window.
Process[] procs = Process.GetProcessesByName("notepad");
Process top = null;
int topz = int.MaxValue;
foreach (Process p in procs)
{
IntPtr handle = p.MainWindowHandle;
int z = 0;
do
{
z++;
handle = GetWindow(handle, 3);
} while(handle != IntPtr.Zero);
if (z < topz)
{
top = p;
topz = z;
}
}
if(top != null)
Debug.WriteLine(top.MainWindowTitle);