如何设置另一个窗口?

时间:2012-01-19 09:17:03

标签: c# winforms winapi

我正在编写一个自定义工具提示窗口(让我们称之为A)。它必须显示在另一个窗口上(让我们称之为B)和:

  • 不要从B

  • 中窃取焦点
  • 当用户继续输入B时,不要将其在z顺序中的位置丢失到B

  • 必须收到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:不会在活动窗口B上显示窗口A;更确切地说:在通话之后,它确实将窗口A带到前景,但是B然后转到前景;在实践中,当B被标题栏移动并且按下鼠标按钮时,窗口A被绘制在它上面 - 但是当时鼠标按钮被按下了

  • 使用UnderHandle作为第一个参数调用SetWindowPos,将Handle作为第二个参数调用,以尝试将窗口B置于窗口A"产生相同的结果

如何正确地使用SetWindowPos来获得所需的结果 - 或者,如何监视窗口B在zorder中的位置以将窗口A强制到它旁边的位置(从前景窗口开始)?

1 个答案:

答案 0 :(得分:2)

显然HWND_TOPMOST是你的问题,你当然不能这样做。您可以使用HWND_TOP,但接下来的挑战是如何将窗口A保持在窗口B的顶部。这样做的方法是使A成为owned

  

拥有Windows

     

重叠或弹出窗口可以由另一个窗口拥有   重叠或弹出窗口。被拥有会带来一些限制   一个窗口。

     
      
  • 拥有的窗口始终位于z订单的所有者之上。
  •   
  • 当系统所有者拥有时,系统会自动销毁拥有的窗口   破坏。
  •   
  • 拥有的窗口在其所有者最小化时隐藏。
  •   
     

只有   重叠或弹出窗口可以是所有者窗口;一个儿童窗口   不能是所有者窗口。应用程序创建一个拥有的窗口   将所有者的窗口句柄指定为 hwndParent 参数   CreateWindowEx当它创建一个包含WS_OVERLAPPED或{。}的窗口时   WS_POPUP风格。 hwndParent 参数必须标识重叠   或弹出窗口。如果 hwndParent 标识子窗口,则为系统   将所有权分配给子窗口的顶级父窗口。   创建拥有的窗口后,应用程序无法传输   窗口的所有权到另一个窗口。

事实上,从上面的第一个要点可以看出,一旦正确设置了所有权,就不需要HWND_TOP