在Win32编程中,一个窗口的父窗口和一个窗口的所有者之间有什么区别?我以为我已经理解了,然后我看到了这段代码:
SetWindowLong(handle, GWL_HWNDPARENT, foo);
实际上,这设置的是窗口的所有者而不是父窗口 - 尽管使用了GWL_HWNDPARENT。 父/所有者这些术语是否可以互换,或者它们之间实际上存在区别?
在Win32编程中,一个窗口的父窗口和一个窗口的所有者之间有什么区别?我以为我已经理解了,然后我看到了这段代码:
SetWindowLong(handle, GWL_HWNDPARENT, foo);
实际上,这设置的是窗口的所有者而不是父窗口 - 尽管使用了GWL_HWNDPARENT。 父/所有者这些术语是否可以互换,或者它们之间实际上存在区别?
所有权是两个顶级窗口之间的关系,而父子关系则是指顶级窗口和WS_CHILD之间的关系,或者是WS_CHILD和另一个WS_CHILD之间的关系。
按钮的父级是其所在的表单,而消息框由显示它的表单拥有。
阅读微软的这篇文章《Win32窗口层次和样式》,可以更加清晰地了解所有权、父子关系、ZOrder、SetWindowLong、GetWindow以及创建窗口关系的Win32 API的所有其他棘手细节。
编辑:看起来微软已经删除了该内容,这里有另一份所有权/父子关系总结。
Owner(所有者)是一个控件或对话框的 Window*,负责创建/销毁窗口等操作。
Parent(父级)是与一个控件或对话框在窗口链中相邻且比其高级的窗口,但并不实际负责该控件或对话框(不一定关心其生命周期等)。 一个窗口的父级也可以是它的所有者。
*Window vs window:Window 是屏幕上显示的实际窗口;window 是任何具有 HWND 的对象(包括按钮、面板等)。
Chen的博客文章是值得一读的。对我来说关键点是子窗口必须使用WS_CHILD样式。您可以尝试创建一个子窗口并将父句柄传递给CreateWindow(),但如果没有设置WS_CHILD样式,则两个窗口将具有所有者关系,而不是父/子关系。
这很简单:代码有问题,故事就到此为止了。
是的,某些窗口可能会对这样的调用做出积极反应 - 某些不知道更好的人可能已经实现了对它的支持。根据文档(而且这是旧的文档)- 您不能使用GWL_HWNDPARENT
索引调用SetWindowLong
来更改子窗口的父级。而是使用SetParent
函数。
所以,一切都很简单:你遇到了有缺陷的代码,将其更改为SetParent
或重构为其他操作,然后继续前进?