初看上去,HWND_TOP 和 HWND_TOPMOST 有点类似,但是实际上在调用 DeferWindowPos 或者 SetWindowPos时,它们之间的差别还挺大。
在同级窗口的维护机制中,有一个概念叫做 Z 序 (Z-order) 。出于此讨论的目的,顶级窗口也被视为同级窗口。事实上,大多数人在说”Z 序”时想到的正是顶级窗口的 Z 序。
Z 序应可视化为窗口的垂直堆栈,具体来说,就是哪个窗口在上方,哪个在下方。
在 Windows 3.0 版本之前,窗口的排序规则还是挺简单的:HWND_TOP 标志将会将它指定的窗口设定到窗口 Z 序的最上面。
Windows 3.0 版本开始,系统增加了”最顶层”窗口(Topmost)的概念。这些是始终保持”高于”非最顶层窗口的顶级窗口。要使窗口最顶层,请调用 DeferWindowPos(或其等价函数),HWND_TOPMOST 作为 hWndInsertAfter 参数的值。若要使窗口不在最顶层,请使用 HWND_NOTOPMOST。
由于引入了”最顶层”窗口,HWND_TOP 现在使窗口” 在 Z 顺序中尽可能高,同时不会违反最顶层窗口始终出现在非最顶层窗口上方的规则”。这在实践中意味着什么?
> 如果窗口位于最顶部(topmost),则 HWND_TOP 将其置于 Z 顺序的最顶部。
> 如果窗口不是最顶层(topmost)的,则 HWND_TOP 将其放在所有非最顶层窗口的顶部(即,如果存在,则位于最低的 topmost 窗口的正下方)。
注意:上面的讨论完全忽略了所有者和拥有窗口的问题。我省略了它们,因为它们会增加一层复杂性,分散主要话题的注意力。
总结
在实际体验中,我发现 topmost 窗口会给一些用户带来困扰,所以,在实际开发中,没有特殊的理由,我一般不使用 topmost。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《What’s the difference between HWND_TOP and HWND_TOPMOST?》