QT踩坑:窗口层级(Z-order)

4,457 阅读2分钟

今天遇见了一个问题:软件有一个提示弹窗,希望让他永远在最上面,保证该窗口在任何情况下不会被遮挡。

由上面的问题就查找对应的api找到了SetWindowPos()。

在说这个函数之前,先了解以下概念:


Z-order(Z顺序)

其实这玩意翻译成 Z轴 更好。

首先对于显示器而言,以左上角为坐标原点,向右为x轴,向下为y轴。除此之外,由里向外就是z轴,也就是所谓的Z-order。

top of the Z order:Z轴的最顶层,虽然是Z序里最上面的,但它并不一定是最最上面的。

按照Z轴的顺序,由外向里,分别是:顶端窗口--顶层窗口--子窗口。顶端窗口有TOPMOST风格。

我们在点击使用不同窗口的同时,就在不断的改变Z序列。因为系统会将你点击的窗口(活动窗口)放在Z序列中同类窗口的顶部(顶层窗口)。当一个窗口成为了顶层窗口,它的子窗口也就成了顶层窗口。

最后,总结一下排序依次是:TOPMOST窗口---顶层窗口---非顶层窗口


再说回SetWindowPos()函数:

BOOL SetWindowPos(
  HWND hWnd, 
  HWND hWndInsertAfter, 
  int  X,
  int  Y,
  int  cx,
  int  cy,
  UINT uFlags
);

MSDN地址:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos
  • HWND hWnd:窗口句柄
  • HWND hWndInsertAfter:原本可以是定位的窗口之前的窗口的句柄,但是主要使用的是一些参数。
  • int X,int Y:窗口左上角的x,
  • int cx,int cy:窗口的宽度和高度
  • UINT uFlags:窗口大小和位置标志,也是一些参数,具体参数比较多,详见MSDN。

“详见”这个词不错,显得很有文化。

主要解释第二个参数:hWndInsertAfter

上面截自MSDN,简单那解释一下:

  • HWND_BOTTOM:将窗口置于Z顺序的底部。
  • HWND_NOTOPMOST:将窗口放置在所有非最上面的窗口上方(即,所有最上面的窗口的后面)。
  • HWND_TOP:将窗口置于Z顺序的顶部。
  • HWND_TOPMOST:将窗口置于所有最上面的窗口上方。即使禁用窗口,窗口也将保持其最高位置。

由上到下,越来越靠前,TOPMOST就是最上面的窗口。

对了,发现了MSDN官网的解释都存在错误,HWND_TOPMOST后面的Meaning第一句应该是:Places the window above all topmost windows. 太坑了,理解了半天,对英语差的人太不友好了。