2010-08-13 5 views
6

Tamam, bu yüzden benim previous question benim yararlı bir yanıt üretmedi, bu yüzden farklı bir yönden gelmeye çalışacağım.HitTest?

Uygulamam, muhtemelen birkaç pencereye sahiptir. Ekran koordinatlarındaki bir nokta göz önüne alındığında, hangi pencerenin üzerine "düştüğünü" bulmalıyım - yani söz konusu noktayı içeren tüm pencerelerin en önemlisi olan Pencereyi bulmalıyım. Bir pencerenin içinde Visual s ise, VisualTreeHelper.HitTest kullanıyorum. Fakat farklı pencereler oldukları için, bu yöntemin ilk argümanı olarak ne verileceği açık değildir.

cevap

7

WPF pencerelerinin Z Sırasını göstermediği için, bu işlem WPF kullanılarak mümkün değildir. Aslında, WPF, pencerelerin asla birbirini kesinlikle gizlemediği yanılsamasını korumak için çok çalışmaktadır.

public Window FindWindowAt(Point screenPoint) // WPF units (96dpi), not device units 
{ 
    return (
    from win in SortWindowsTopToBottom(Application.Current.Windows.OfType<Window>()) 
    where new Rect(win.Left, win.Top, win.Width, win.Height).Contains(screenPoint) 
    select win 
).FirstOrDefault(); 
} 

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

windows() ayrıca FindWindowAt ait "nerede" hükmündeki VisualTreeHelper.HitTest kullanmalıdır şeffaf olabilir edin:

Eğer hazırsanız

çözüm basit, Win32 çağrıları yapmak.

+0

Cevabınız için çok teşekkür ederim. Şimdiye kadarki tek cevap olduğu gibi kabul edeceğim ve sadece Tam Güveni gerektirme pahasına olursa kesinlikle işe yarayacaktır :-(Bir soru var, ancak: WPF'nin buna izin vermediğinden neden tam olarak emin olmalısınız? –

+3

Herhangi bir Win32 uygulaması, SetWindowPos kullanarak Z Sırasını değiştirebilir.WPF, bu Z Sipariş bilgileri, Win32: GetTopWindow/GetNextWindow, yukarıda gösterildiği gibi veya WM_WINDOWPOSCHANGED ve depolama durumunu kullanarak, iki yolu vardır.WPF derlemelerinde GetTopWindow için herhangi bir başvuru yoktur. Hata ayıklayıcısındaki nesnelerin incelenmesi, WPF'nin Z Sipariş bilgisini de saklamadığını gösterir. WPF, ne bilmediğini size söyleyemez. –