7

わかりました、前の質問では有用な回答が得られなかったので、別の方向から来ようとします。

私のアプリケーションには、潜在的に複数のウィンドウがあります。画面座標の点が与えられた場合、それが「落ちる」ウィンドウを見つける必要があります。つまり、その点を含むすべてのウィンドウの中で最も重要なウィンドウを見つける必要があります。

それらがVisual1 つのウィンドウ内にある場合は、 を使用しますVisualTreeHelper.HitTest。しかし、これらは異なるウィンドウであるため、そのメソッドの最初の引数として何を指定すればよいか明確ではありません。

4

1 に答える 1

8

WPF はウィンドウの Z オーダーを公開しないため、これは純粋な WPF では不可能です。実際、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); 

ウィンドウが透明な場合は、FindWindowAt() の "where" 句で VisualTreeHelper.HitTest も使用する必要があります。

于 2010-08-13T04:43:47.840 に答える