代码之家  ›  专栏  ›  技术社区  ›  Fyodor Soikin

如何按z索引对窗口排序?

  •  6
  • Fyodor Soikin  · 技术社区  · 14 年前

    如果我在枚举窗口 Application.Current.Windows

    或者,换言之,如何按z索引对这些窗口进行排序?

    2 回复  |  直到 14 年前
        1
  •  7
  •   Julien Christin    5 年前

    无法从WPF获取窗口的Z顺序信息,因此必须使用Win32。

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

    其工作方式是:

    1. 它使用字典按窗口句柄索引给定的窗口,这是因为在WPF的windows实现中,窗口的PresentationSource总是HwndSource。
    2. 它使用Win32从上到下扫描所有未着色的窗口以找到正确的顺序。
        2
  •  -1
  •   Carlo    14 年前

    啊,这真的很有趣:

    [DllImport("user32.dll")]
    static extern IntPtr GetActiveWindow();
    
    public static Window ActiveWindow
    {
        get
        {
            return HwndSource.FromHwnd(GetActiveWindow()).RootVisual as Window;
        }
    }
    

    它将为您的应用程序提供活动窗口(通常是最重要的窗口)。