c# - 如何在另一个窗口上设置窗口?

标签 c# winforms winapi

我正在编写一个自定义工具提示窗口(我们称之为 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 the WS_OVERLAPPED or WS_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/

相关文章:

c# - 如何获得平滑的颜色变化?

c# - 类设计 - 具有通用后代的基类

c# - 结构图和通用类型

c# - 为什么我没有收到 "Cross-thread operation not valid"错误

c# - 在“保存文件”提示中使用适当的扩展名保存文件

windows - Windows 上有哪些熵源可用?

c++ - 如何在 C++ 中获取使用我的服务的用户的 SID 和用户名

javascript - 使用 Ajax 形式 knockout 推送新数组项

c# - 获取用户控件以填充其容器

winapi - 监视虚拟内存区域 (Win32)