Winforms 如何检查窗体是否位于另一个窗口后面?

Winforms 如何检查窗体是否位于另一个窗口后面?,winforms,Winforms,是否有一个窗体的属性,我可以检查它是否位于另一个窗口后面 我有一个基于OpenGL的虚拟环境在表单中运行 我希望在单击此窗体顶部的另一个窗口时能够忽略鼠标 我看了这篇文章,但题目与答案不符。汉斯一如既往地是对的。平沃克是你的朋友。。我找到了一个解决方案来满足我的需求,这个方法使用大量的WinAPI调用来确定窗口是否重叠。我做了一些小的修改以允许忽略某些句柄。只要另一个窗口稍微重叠,该方法就会返回true,您可能需要自己进行修改 private const int GW_HWNDPREV =

是否有一个窗体的属性,我可以检查它是否位于另一个窗口后面

我有一个基于OpenGL的虚拟环境在表单中运行


我希望在单击此窗体顶部的另一个窗口时能够忽略鼠标


我看了这篇文章,但题目与答案不符。

汉斯一如既往地是对的。平沃克是你的朋友。。我找到了一个解决方案来满足我的需求,这个方法使用大量的WinAPI调用来确定窗口是否重叠。我做了一些小的修改以允许忽略某些句柄。只要另一个窗口稍微重叠,该方法就会返回true,您可能需要自己进行修改

  private const int GW_HWNDPREV = 3;

    [DllImport("user32.dll")]
    private static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

    [DllImport("user32.dll")]
    private static extern bool IntersectRect(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);

    public static bool IsWindowOverlapped(IntPtr hWnd, HashSet<IntPtr> ignoreHandles)
    {
        if (hWnd == IntPtr.Zero)
            return false; //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 = new RECT();
        GetWindowRect(hWnd, ref thisRect);

        while ((hWnd = GetWindow(hWnd, GW_HWNDPREV)) != IntPtr.Zero && !visited.Contains(hWnd))
        {
            visited.Add(hWnd);
            if (ignoreHandles != null && ignoreHandles.Contains(hWnd))
                continue;

            RECT testRect, intersection;
            testRect = intersection = new RECT();
            if (IsWindowVisible(hWnd) && GetWindowRect(hWnd, ref testRect) && IntersectRect(out intersection, ref thisRect, ref testRect))
                return true;
        }

        return false;
    }
private const int GW_hwndprov=3;
[DllImport(“user32.dll”)]
私有静态外部IntPtr GetWindow(IntPtr hWnd,intucmd);
[DllImport(“user32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
私有静态外部bool GetWindowRect(IntPtr hWnd,ref RECT lpRect);
[DllImport(“user32.dll”)]
私有静态外部bool IntersectRect(out RECT lprcDst,[In]ref RECT lprcSrc1,[In]ref RECT lprcSrc2);
[DllImport(“user32.dll”)]
[返回:Marshallas(UnmanagedType.Bool)]
私有静态外部bool IsWindowVisible(IntPtr hWnd);
公共静态布尔值IsWindowOverlapped(IntPtr hWnd、HashSet ignoreHandles)
{
if(hWnd==IntPtr.Zero)
返回false;//抛出新的InvalidOperationException(“窗口尚不存在”);
如果(!IsWindowVisible(hWnd))
返回false;
访问的HashSet=newhashset{hWnd};
//该集合用于通过检查是否已经在循环中调用GetWindow,使其稳定
//访问了GetWindow返回的窗口。这避免了内循环的可能性。
RECT thisRect=新RECT();
GetWindowRect(hWnd,ref thisRect);
while((hWnd=GetWindow(hWnd,gwhwndprov))!=IntPtr.Zero&!visted.Contains(hWnd))
{
已访问。添加(hWnd);
if(ignoreHandles!=null&&ignoreHandles.Contains(hWnd))
继续;
RECT testRect,交叉点;
testRect=交叉点=新的RECT();
if(IsWindowVisible(hWnd)&&GetWindowRect(hWnd,ref testRect)&&IntersectRect(out intersection,ref thisRect,ref testRect))
返回true;
}
返回false;
}

它需要pinvoke。这并不能解决您的问题,真正的问题是操作系统不会忽略该窗口。“我希望在单击此窗体顶部的另一个窗口时能够忽略鼠标。”假设您控制此窗体的代码,请在CreateParams()中为其设置WS_EX_TRANSPARENT。这将使其忽略所有鼠标事件。