好贷网好贷款

Windows窗口相关的一些概念解释

发布时间:2016-12-4 18:39:35 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"Windows窗口相关的一些概念解释",主要涉及到Windows窗口相关的一些概念解释方面的内容,对于Windows窗口相关的一些概念解释感兴趣的同学可以参考一下。

文章转自http://blog.sina.com.cn/s/blog_48f93b530100eamd.html 最近工作中关于UI开发方面的东西多了些,碰到问题的时候查阅了很多资料,对Windows窗口的一些概念的理解也慢慢深入了很多。在这篇中把一些比较容易混淆和相关资料比较少的概念做一个总结,可能你用到这些概念的几率不大,但是一旦你遇到相关问题,解决起来还真是要费一番功夫。       一、窗口的分类     Windows定义了3种窗口类型:     #define WS_OVERLAPPED       0x00000000L     #define WS_POPUP            0x80000000L     #define WS_CHILD            0x40000000L     顾名思义,CHILD是从属于其他窗口的子窗口;POPUP是弹出窗口;OVERLAPPED为重叠式窗口,MSDN中并没有给出该窗口的确切定义,只提到该类型的窗口一般都有标题栏和边框。其实从WS_OVERLAPPEDWINDOW宏的定义我们可以知道,OVERLAPPED窗口通常拥有标题栏、边框、客户区、图标、可调整尺寸边框、最小化和最大化按钮。     看上去这3种类型的窗口我们已经解释清楚了,但是其实还有很多概念需要阐述,下一节我们再仔细研究。     现在考虑一个问题:一个窗口能不能具有多个类型?这个问题在这篇文章里作者做了探讨(http://blog.csdn.net/guogangj/archive/2008/12/06/3460267.aspx),不过好像最后并没有明确的答案,这里总结一些比较确切的结论:     1、OVERLAPPED类型窗口适合作为应用程序的主窗口,或者POPUP类型也可以,如基于对话框的应用程序;     2、OVERLAPPED类型和POPUP类型比较类似,但是OVERLAPPED类型默认具有标题栏等元素,而且即使你显示去掉WS_CAPTION和WS_BORDER这些风格,Windows还是会加上标题栏和边框,POPUP类型没有这个特点;另外在CreateWindow函数中对于CW_USEDEFAULT默认值的取值是不同的;     3、OVERLAPPED类型不能和CHILD类型同时设置,原因后面说明;     4、事实上这3种类型的窗口不应该混合应用,虽然Windows会对他们的混合做处理,但是并没有官方的说明,我们无从确切的知道这样的行为的结果。       二、窗口的parent和owner     上一节只是大概介绍了窗口的3种类型,还有很多概念需要我们仔细弄个明白。     1、Desktop窗口     简单的说就是桌面窗口。desktop窗口是Windows产生的第一个窗口,上面的图画就是壁纸。desktop窗口是一个特殊的窗口,不属于上面3种窗口类型中的任何一种。你可以把Windows的所有窗口想象成一个树结构,而这棵树的根就是desktop窗口。     2、Top-Level窗口     top-level窗口是指没有WS_CHILD属性的窗口,它们的parent通常为desktop窗口或者为NULL。top-level窗口是desktop窗口的下一级。     3、子窗口(child window)     具有WS_CHILD属性的窗口为子窗口,它们必须有父窗口(parent),同时子窗口可以拥有自己的子窗口。子窗口只能出现在父窗口的客户区之内,子窗口不能成为活动窗口,也不能显示在任务栏上。建立子窗口时的区域坐标是以父窗口客户区左上角为原点的,而非子窗口是屏幕坐标。子窗口显示在父窗口显示之后,隐藏在父窗口隐藏之前,销毁在父窗口销毁之前。     4、重叠式窗口(overlapped)     具有WS_OVERLAPPED属性的窗口为重叠式窗口。重叠式窗口一定是top-level窗口,因此它们不能再具有WS_CHILD属性。     5、弹出窗口(popup)     具有WS_POPUP属性的窗口为弹出窗口,弹出窗口也是top-level窗口,它和重叠式窗口都可以显示在桌面的任何地方。     6、parent和owner     这两个概念是本节需要重点阐述的。Windows中上下级窗口的关系有两种:parent-child和owner-owned,一个窗口在有parent窗口的情况下还可能有owner窗口。这两种关系有什么联系和区别呢?     这篇文章中写得比较清楚(http://blog.vckbase.com/iwaswzq/archive/2006/09/12/22380.html),截取其中一段:       如果一个窗口数据的owner域非NULL,则它和该窗口建立了owner-owned 关系,拥有关系决定了:     (1)被拥有的窗口永远显示在拥有它的那个窗口的前面;     (2)当所有者窗口最小化的时候,它所拥有的窗口都会被隐藏;     (3)当所有者窗口被销毁的时候,它所拥有的窗口都会被销毁。     需要注意的是,隐藏所有者窗口并不会影响它所拥有的窗口的可见状态。比如:如果窗口 A 拥有窗口B,窗口B拥有窗口C,则当窗口A最小化的时候,窗口B被隐藏,但是窗口 C还是可见。     如果一个窗口的parent域非NULL,则它和该窗口之间就建立了parent-child关系。父子决定了:     (1)窗口在屏幕上面的显示位置。父窗口提供了用来定位子窗口的坐标系统,一个子窗口只能显示在它的父窗口的客户区中,之外的部分将被裁减。这个裁减法则决定了如果父窗口不可见,则子窗口肯定不可见。如果父窗口移动到了屏幕之外,子窗口也一样。     (2)当父窗口被隐藏时,它的所有子窗口也被隐藏。     (3)父窗口被销毁的时候,它所拥有的子窗口都会被销毁。      注意!最小化父窗口不会影响子窗口的可见状态,子窗口会随着父窗口被最小化,但是它的WS_VISIBLE属性不会变。       另外,parent-child关系是双向的,一个窗口知道自己的parent和child;owner-owned关系是单向的,窗口只知道自己的owner。     下面我们总结一下窗口类型与parent、owner窗口之间的关系特点。     1、子窗口一定有parent,且parent即相当于owner,子窗口的父窗口可以为top-level窗口或者其他子窗口;     2、只有overlapped窗口和popup窗口可以是owner窗口,子窗口不能是owner窗口;     3、overlapped窗口和popup窗口的parent一般都是desktop窗口,由于overlapped窗口多用于作为应用程序的主窗口,其owner一般为desktop窗口;而popup窗口的owner是在CreateWindow函数中通过设置hWndParent参数给定的,如果hWndParent为非子窗口,则这个窗口即为popup窗口的owner;如果hWndParent为子窗口,系统从hWndParent的父窗口向上找,直到找到第一个非子窗口,把它作为该popup窗口的owner;          Windows的API函数GetParent可以获取窗口的parent或owner,如果是子窗口则返回parent;如果overlapped窗口返回NULL;如果是popup窗口返回其owner。用API函数GetWindow(GW_OWNER)可以获取窗口的owner,或者用MFC CWnd类的成员函数GetOwner也可以。       三、窗口WS_CLIPSIBLING和WS_CLIPCHILDREN风格     首先简单的解释一下这两个风格的意义。     WS_CLIPSIBLING 风格用于同一级的子窗口之间,表示当某设置了该风格的子窗口需要重绘时,被其他窗口遮挡的部分(按照Z-order)将被裁减,也就是被遮挡区域不进行重绘。     WS_CLIPCHILDREN 风格则用于父窗口和子窗口之间,表示当某设置了该风格的父窗口需要重绘时,被子窗口遮挡的部分将被裁剪,即被遮挡的区域不进行重绘。         在Windows系统的窗口中,凡是overlapped窗口和popup窗口都肯定具有WS_CLIPSIBLING风格,即使你写代码将这个风格去掉,Windows还是会自动加上。     为什么呢?仔细想想就清楚了,我们可以认为overlapped窗口和popup窗口都是desktop窗口的同一级“子窗口”,他们之间要想在互相重叠的时候正确显示,就必须具有这个风格。为什么同一级子窗口重叠时都要有WS_CLIPSIBLING风格呢?比如现在有一个父窗口P,它有两个重叠的子窗口A和B,A的Z-order在B之前,那么正常显示的话A应该把B中重合的区域遮挡住。Windows在判断一个窗口区域是否需要重绘的时候,一般是看这个区域是否被其他窗口遮挡。因为此时系统认为A始终在B的上面,并未被遮挡,所以当你移动A窗口的时候,A的窗口内部区域是不会被通知重绘的。此时B被遮挡的部分肯定会被通知重绘,于是你会发现B重绘的时候却把与A重合的区域画乱了。但是如果我们把A和B都指定了WS_CLIPSIBLING风格以后,B被遮挡的部分的重绘就被裁剪掉了,这样它就不会捣乱了。     当然,对于我们平时在对话框上用的最多的控件子窗口,虽然它们都没有WS_CLIPSIBLING风格,但是由于它们基本不重叠,因此不会彼此影响。     如果你只为一部分子窗口设置了WS_CLIPSIBLING风格,就要保证其他窗口的所有重绘都发生在设置风格的子窗口之前,否则也会出现问题。对于对话框的控件来说,可以通过控制Tab-order来控制绘制顺序;对于其他子窗口,可以通过控制Z-order控制。     对于WS_CLIPCHILDREN风格也是相同的问题,如果你不想父窗口的重绘影响到子窗口的绘制,那么最好给父窗口加上WS_CLIPCHILDREN风格。       关于窗口的一些概念就先写这些吧,如果你对这些概念比较模糊的话,相信读完这篇文章会有很多收获。对于其中某些描述,我尽量做到严谨,但是可能会有错误的地方,请大家指正。另外有很多概念微软根本没有明确的定义和解释,所以还需要大家多摸索,在实践中探索规律性的东西。

上一篇:《职责链模式》
下一篇:是什么遮蔽了时寒冰的眼睛(转载)

相关文章

相关评论