开发者

How to sort 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. h开发者_JS百科as greater z-index)?

Or, to say the same in other words, how can I sort those windows by z-index?


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 = GetWindow(hWnd, GW_HWNDNEXT)
    if(byHandle.ContainsKey(hWnd))
      yield return byHandle[hWnd];
}

const uint GW_HWNDNEXT = 2;
[DllImport("User32")] static extern IntPtr GetTopWindow(IntPtr hWnd);
[DllImport("User32")] static extern IntPtr GetWindow(IntPtr hWnd, uint wCmd);

The way this works is:

  1. It uses a dictionary to index the given windows by window handle, using the fact that in the Windows implementation of WPF, Window's PresentationSource is always HwndSource.
  2. It uses Win32 to scan all unparented windows top to bottom to find the proper order.


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜