如何将窗口设置在另一个窗口上方?

4

我正在编写一个自定义的工具提示窗口(我们称之为A)。它必须显示在另一个窗口(我们称之为B)上,并且需要满足以下条件:

  • 不要从B窗口中夺取焦点

  • 当用户继续在B窗口输入时,不要让A窗口在z-order中失去其位置

  • A窗口必须接收WM_NCHITTEST消息(我用它们来跟踪非活动窗口上的鼠标位置)

  • 当其他窗口覆盖B窗口时,A窗口也必须被覆盖;避免出现B窗口被覆盖而不可见,但A窗口仍然显示的情况

我已尝试通过使用SetWindowPos函数来实现此目标,从B中调用其包装器(在A中定义),如下所示:

    public void SetLocation(Point location, IntPtr UnderHandle)
    {
        SetWindowPos(Handle, HWND_TOPMOST, location.X, location.Y, Width, Height,
                             SetWindowPosFlags.DoNotActivate);

    }

(来自pinvoke.net的SetWindowPosFlags)

这个结果几乎满足了我所有的需求,除了最后一个。

我还尝试过:

  • HWND_TOP: 不能将窗口A置于活动窗口B之上;更准确地说:在调用后,它确实将窗口A置于前景,但随后B会取代它成为前景;在实践中,当B被标题栏和鼠标按钮移动时,窗口A被绘制在其上方 - 但是在释放鼠标按钮时就会变成下层

  • 尝试使用UnderHandle作为第一个参数,Handle作为第二个参数调用SetWindowPos,以尝试“将窗口B置于窗口A之下”会得到相同的结果

如何正确使用SetWindowPos以达到所需的结果 - 或者,另一种方法是如何监视窗口B在zorder中的位置,以强制将窗口A从前景窗口移动到其旁边?

1个回答

3

很明显,HWND_TOPMOST 是你的问题,你绝不能这样做。你可以使用 HWND_TOP,但是挑战在于如何使窗口 A 始终在窗口 B 之上。方法是使 A 被 B 拥有

拥有窗口

一个重叠或弹出窗口可以被另一个重叠或弹出窗口所拥有。被拥有会对窗口施加一些限制。

  • 拥有窗口总是在其所有者之上。
  • 当其所有者被销毁时,系统会自动销毁拥有窗口。
  • 当其所有者被最小化时,拥有窗口会被隐藏。

只有重叠或弹出窗口可以成为拥有窗口;子窗口不能成为拥有窗口。应用程序通过将所有者的窗口句柄指定为 CreateWindowExhwndParent 参数来创建拥有窗口,当它使用 WS_OVERLAPPEDWS_POPUP 样式创建一个窗口时。 hwndParent 参数必须标识一个重叠或弹出窗口。如果 hwndParent 标识了一个子窗口,则系统会将所有权分配给该子窗口的顶级父窗口。创建拥有窗口后,应用程序无法将窗口的所有权转移给另一个窗口。

事实上,正如您可以从上面的第一个要点中看到的那样,一旦正确设置所有权,就没有必要使用HWND_TOP

谢谢您!根据您的建议,我将A.Owner=B设置为了相同,成功得到了所需结果。 - Srv19

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接