2017-08-20 70 views
0

如何检查窗口是否有重叠?检查窗口是否有重叠?

我发现这个的WinForms代码应该做的伎俩:

public static bool IsOverlapped(IWin32Window window) 
{ 
    if (window == null) 
     throw new ArgumentNullException("window"); 
    if (window.Handle == IntPtr.Zero) 
     throw new InvalidOperationException("Window does not yet exist"); 
    if (!IsWindowVisible(window.Handle)) 
     return false; 

    IntPtr hWnd = window.Handle; 
    HashSet<IntPtr> visited = new HashSet<IntPtr> { hWnd }; 

    // The set is used to make calling GetWindow in a loop stable by checking if we have already 
    // visited the window returned by GetWindow. This avoids the possibility of an infinate loop. 

    RECT thisRect; 
    GetWindowRect(hWnd, out thisRect); 

    while ((hWnd = GetWindow(hWnd, GW_HWNDPREV)) != IntPtr.Zero && !visited.Contains(hWnd)) 
    { 
     visited.Add(hWnd); 
     RECT testRect, intersection; 
     if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, out testRect) && IntersectRect(out intersection, ref thisRect, ref testRect)) 
      return true; 
    } 

    return false; 
} 

[DllImport("user32.dll")] 
private static extern IntPtr GetWindow(IntPtr hWnd, int uCmd); 
[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool GetWindowRect(IntPtr hWnd, [Out] out RECT lpRect); 
[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool IntersectRect([Out] out RECT lprcDst, [In] ref RECT lprcSrc1, [In] ref RECT lprcSrc2); 
[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool IsWindowVisible(IntPtr hWnd); 

private const int GW_HWNDPREV = 3; 

[StructLayout(LayoutKind.Sequential)] 
private struct RECT 
{ 
    public int left; 
    public int top; 
    public int right; 
    public int bottom; 
} 

但我不知道如何使它在WPF工作,有人可以帮我吗? 我已经尝试了很多东西..

回答

1

如果你想获得给定WPF窗口的句柄,你可以使用System.Windows.Interop.WindowInteropHelper类。到IsOverlapped更新将允许你用的WinForms代码交互:

public static bool IsOverlapped(Window window) 
{ 
    if (window == null) 
     throw new ArgumentNullException("window"); 

    var hWnd = new WindowInteropHelper(window).Handle; 
    if (hWnd == IntPtr.Zero) 
     throw new InvalidOperationException("Window does not yet exist"); 
    if (!IsWindowVisible(hWnd)) 
     return false; 

    HashSet<IntPtr> visited = new HashSet<IntPtr> { hWnd }; 

    // The set is used to make calling GetWindow in a loop stable by checking if we have already 
    // visited the window returned by GetWindow. This avoids the possibility of an infinate loop. 

    RECT thisRect; 
    GetWindowRect(hWnd, out thisRect); 

    while ((hWnd = GetWindow(hWnd, GW_HWNDPREV)) != IntPtr.Zero && !visited.Contains(hWnd)) 
    { 
     visited.Add(hWnd); 
     RECT testRect, intersection; 
     if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, out testRect) && IntersectRect(out intersection, ref thisRect, ref testRect)) 
      return true; 
    } 

    return false; 
} 
+0

非常感谢您! :D不幸的是,我试过了,它认为它是重叠的,即使它不是。 :( – SikuliXUser

1

我解决这样说:

[System.Runtime.InteropServices.DllImport("user32.dll")] 
    public static extern IntPtr GetForegroundWindow(); 

    private void TmrCheckTopmost_Tick(object sender, EventArgs e) 
    { 
     if (!GetForegroundWindow().Equals(new WindowInteropHelper(this).Handle)) 
     { 
      Topmost = false; 
      Topmost = true; 
      Focus(); 
     } 
    }