2010-08-13 50 views
6

如果我列舉了Application.Current.Windows中的窗口,我怎麼能告訴,對於任何兩個窗口,哪一個「更接近」(即具有更大的z-索引)?或者,換句話說,我怎樣才能用z-index對這些窗口進行排序呢?如何使用z-index對Windows進行排序?

回答

6

您無法從WPF獲取Window的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 = 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); 

其工作原理是:

  1. 它使用字典來指數給出的Windows的窗口句柄,使用的事實, WPF的Windows實現,Window的PresentationSource始終是HwndSource。
  2. 它使用Win32從上到下掃描所有未經過授權的窗口,找到正確的順序。
+0

是的,很抱歉,這確實需要非託管代碼權限(「完全信任」)。 – 2010-08-13 04:55:30

+0

不過我會接受的,因爲這是目前唯一的答案。 – 2010-08-13 14:49:45

+0

你能看看我最近的問題嗎?我真的很想看到你在這個問題上的角度。 http://stackoverflow.com/questions/3642763/static-verification-of-bindings – 2010-09-04 22:56:01

0

啊,這是一個非常有趣的一個:

[DllImport("user32.dll")] 
static extern IntPtr GetActiveWindow(); 

public static Window ActiveWindow 
{ 
    get 
    { 
     return HwndSource.FromHwnd(GetActiveWindow()).RootVisual as Window; 
    } 
} 

它會給你在你的應用程序的活動窗口(這通常是最重要的)。

+0

我認爲這不是他的意思 – 2010-08-13 00:46:33

+2

這不僅僅是我的意思,它還需要完全信任(就像任何P/Invoke一樣)。它可能甚至是值得的,用Window.IsActive屬性是不容易實現的。 – 2010-08-13 00:55:13

相關問題