BringWindowToTop
,SetForegroundWindow
,SwitchToThisWindow
,SetWindowPos
,ShowWindow
都被描述为显示和激活窗口。
它们之间有什么真正的区别?何时以及为什么BringWindowToTop
首选SetForegroundWindow
,SwitchToThisWindow
甚至SetWindowPos
,并将标记设置为激活并显示?
答案 0 :(得分:30)
涉及许多密切相关的概念,相关术语经常被误用,即使在官方文档中也是如此。
重要的窗口类型:
顶级窗口:没有父窗口的Windows。应用程序的主窗口几乎总是顶级窗口。它与z-order没有任何关系。
子窗口:父窗口包含的Windows。他们的位置总是相对于父寡妇的区域。子窗口通常是“控件”:UI等按钮和编辑框。
父窗口:具有子窗口的Windows。顶级窗户经常有孩子。但请注意,子窗口也可能有子窗口,因此同时是父窗口和子窗口。
拥有的窗口:由另一个窗口控制但不一定是其他窗口的子窗口的Windows。一个例子是浮动工具调色板:它由应用程序中的另一个窗口拥有,但它没有锁定到其他窗口的区域。
所有者窗口:拥有自有窗口的Windows。
通常,所有者/拥有关系与父/子关系之间的区别并不重要,因此父和子术语通常用于两种情境,即使在文档中也是如此。在某些情况下,父字段和参数会重载为父母和/或所有者。
重要概念:
z顺序的顶部:这实际上是指显示在其他窗口上方的窗口。
活动窗口:模糊概念,但它通常表示用户将认为是“当前”窗口的顶级窗口。活动窗口通常使用独特边框绘制,并且任务栏上的图块会突出显示。活动窗口通常位于所有其他顶级窗口中z顺序顶部或附近,并且它是具有键盘焦点的窗口的父级或所有者(可能是间接的)。
键盘焦点:表示将接收键盘消息的窗口。从概念上讲,有一个带键盘焦点的窗口。通常,具有焦点的窗口是活动窗口的子(或孙子等)。
前景:活动窗口通常位于前台。这个名称似乎表明它位于z顺序的顶部,但它确实意味着创建窗口的线程获得了轻微的优先级提升。该活动窗口通常也是前景窗口。
因此,假设您已打开此浏览器窗口,并且还有一个记事本运行实例。如果在记事本中单击该文档,则会发生一连串的消息和状态更改。您实际上是在点击一个大编辑框,这是一个记事本顶层窗口的子窗口。该单击导致编辑框被激活,但子窗口实际上不能成为“活动”窗口,因此它只需要键盘焦点并通过其祖先传递激活消息,直到它到达顶级窗口。顶级窗口通过移动到z顺序的顶部来“激活”,突出显示其边框等。它也成为前景窗口,因此其线程得到一点提升,使UI比其他任何一个响应更快窗户。
考虑到这些条款,您可以解析列出的功能的MSDN描述,以梳理出细微差别。
如果你试图布置窗口的孩子,只需使用SetWindowPos(或MoveWindow,SizeWindow和ShowWinow)。在剩余的函数中,SwitchToThisWindow看起来已被弃用,与SetForegroundWindow基本相同。 (请注意,在许多情况下,除非您是活动应用程序或活动应用程序已授予您使用权限,否则SetForegroundWindow将无法执行您想要的操作。)BringWindowToTop主要是将窗口置于z的顶部。 order(你可以使用SetWindowPos),如果你在顶级窗口调用它,会产生类似SetForegroundWindow的额外副作用。
更新: Raymond Chen发布了clearer distinction between the active window and the foreground window。引用:
前导窗口的概念是在输入被去同步时引入的,以便表达“真正的全局活动窗口”,而不是SetActiveWindow,后者继续引用本地活动窗口。
答案 1 :(得分:3)
如果您需要更改窗口的大小(而不仅仅是其状态),请使用setwindowpos
使用showwindow
仅更改窗口状态
使用bringwindowtotop
通过孩子激活父窗口。如果你发送一个子窗口(也许是一个浮动的工具栏),父母将被带到前面,而不是孩子。
他们都有自己的位置,显然有重复的功能,但每个都会根据你想做的事情做一些不同的事情。