If I'm enumerating windows in Application.Current.Windows
, how can I tell, for any two windows, which one is "closer" (i.e. has greater z-index)?
Or, to say the same in other words, how can I sort those windows by z-index?
If I'm enumerating windows in Application.Current.Windows
, how can I tell, for any two windows, which one is "closer" (i.e. has greater z-index)?
Or, to say the same in other words, how can I sort those windows by z-index?
Ah this was a really fun one:
[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();
public static Window ActiveWindow
{
get
{
return HwndSource.FromHwnd(GetActiveWindow()).RootVisual as Window;
}
}
It will give you the active window in your app (which is usually the foremost).
You cannot get a Window's Z Order information from WPF so you must resort to Win32.
Something like this ought to do the trick:
var topToBottom = SortWindowsTopToBottom(Application.Current.Windows.OfType<Window>());
...
public IEnumerable<Window> SortWindowsTopToBottom(IEnumerable<Window> unsorted)
{
var byHandle = unsorted.ToDictionary(win =>
((HwndSource)PresentationSource.FromVisual(win)).Handle);
for(IntPtr hWnd = GetTopWindow(IntPtr.Zero); hWnd!=IntPtr.Zero; hWnd = GetNextWindow(hWnd, GW_HWNDNEXT)
if(byHandle.ContainsKey(hWnd))
yield return byHandle[hWnd];
}
const uint GW_HWNDNEXT = 2;
[DllImport("User32")] extern IntPtr GetTopWindow(IntPtr hWnd);
[DllImport("User32")] extern IntPtr GetNextWindow(IntPtr hWnd, uint wCmd);
The way this works is: