Хорошо, поэтому мой предыдущий вопрос не дал никаких полезных ответов, поэтому я попытаюсь прийти в другом направлении.
Мое приложение имеет Потенциально, несколько окон. Учитывая точку в экранных координатах, мне нужно найти, в какое окно она «падает», то есть найти окно, которое является главным из всех окон, содержащих указанную точку.
Если бы они были визуальными
внутри одного окна Я бы использовал VisualTreeHelper.HitTest
. Но поскольку они являются разными окнами, неясно, что следует указывать в качестве первого аргумента этого метода.
Это невозможно при использовании чистого WPF, поскольку WPF не раскрывает Z-порядок своих окна. Фактически, WPF прилагает все усилия, чтобы поддерживать иллюзию того, что окна никогда не заслоняют друг друга.
Если вы хотите выполнять вызовы Win32, решение простое:
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);
Если ваши окна могут быть прозрачными, вам также следует использовать VisualTreeHelper.HitTest в предложении where функции FindWindowAt ().