我正在编写一个自定义工具提示窗口(我们称之为 A)。它必须显示在另一个窗口上(我们称之为 B)并且:
不要窃取 B 的焦点
当用户继续向 B 中输入时,不要丢失其在 z 顺序中到 B 的位置
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 以获得预期的结果 - 或者,如何监 window 口 B 在 zorder 中的位置以强制窗口 A 进入它旁边的位置(从前景窗口开始)?
最佳答案
显然 HWND_TOPMOST
是您的问题,您当然不能这样做。您可以使用 HWND_TOP
,但接下来的挑战是如何将窗口 A 保持在窗口 B 的顶部。实现此目的的方法是使 A 成为 owned。由 B.
Owned Windows
An overlapped or pop-up window can be owned by another overlapped or pop-up window. Being owned places several constraints on a window.
- An owned window is always above its owner in the z-order.
- The system automatically destroys an owned window when its owner is destroyed.
- An owned window is hidden when its owner is minimized.
Only an overlapped or pop-up window can be an owner window; a child window cannot be an owner window. An application creates an owned window by specifying the owner's window handle as the hwndParent parameter of
CreateWindowEx
when it creates a window with theWS_OVERLAPPED
orWS_POPUP
style. The hwndParent parameter must identify an overlapped or pop-up window. If hwndParent identifies a child window, the system assigns ownership to the top-level parent window of the child window. After creating an owned window, an application cannot transfer ownership of the window to another window.
事实上,正如您从上面的第一个要点中看到的那样,一旦正确设置了所有权,就不需要 HWND_TOP
。
关于c# - 如何在另一个窗口上设置窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8923535/