WS_CLIPCHILDREN和WS_CLIPSIBLINGS的区别

来源:互联网 发布:小米关闭自动更新软件 编辑:程序博客网 时间:2024/05/27 20:52

1. 概念

1.1. WS_CLIPCHILDREN

WS_CLIPCHILDREN:

Excludes the area occupied by child windows when you draw within the parent window. Used when you create the parent window.(来源MSDN)

中文翻译:

WS_CLIPCHILDREN样式主要是用于父窗口,也就是说当在父窗口绘制的时候,父窗口上还有一个子窗口,那么设置了这个样式的话,子窗口区域父窗口就不负责绘制。

那么按照MSDN的理解,可以用下面这幅图来表示:


1.2. WS_CLIPSIBLINGS

WS_CLIPSIBLINGS样式从字面上可以理解成ClipSiblings,裁减兄弟窗口。
 
WS_CLIPSIBLINGS:

Clips child windows relative to each other;

that is, when a particular child window receives a WM_PAINT message,

the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated.

 If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window,

 to draw within the client area of a neighboring child window.(来源MSDN)

中文翻译:

子窗口间相互裁减。也就是说当两个窗口相互重叠时,设置了WS_CLIPSIBLINGS样式的子窗口重绘时不能绘制被重叠的部分。

反之没有设置WS_CLIPSIBLINGS样式的子窗口重绘时是不考虑重叠不重叠,统统重绘。

那么按照MSDN的理解,可以用下面这幅图来表示:


2. 相关资料

(1)所有的overlapped和popup风格的窗口,都有WS_CLIPSIBLINGS 属性。

也就是说这类风格的窗口,你是无法去掉WS_CLIPSIBLINGS 属性的,不会在它重叠的兄弟窗口绘图。
 
(2)更进一步说明,WS_CLIPSIBLINGS只是用于子窗口(For use with the WS_CHILD style only.)

当然在Google上搜索,通常会有意外发现,一般和这个主题相关的往往是控件如何透明的问题。

 

这里也给大家几个关于控件透明的讨论。
 
(1)http://www.pocketpcjunkies.com/Uwe/Forum.aspx/wince-vc/4744/Transparent-bitmap-button。

这个是关于控件上绘制位图,然后透明的讨论。

在桌面系统和WinCE的CreateWindoowsEx还有一些细微的差别,在WinCE上隐含地指定了窗口具备WS_CLIPCHILDREN和WS_CLIPSIBLINGS风格。
 
(2)http://www.pocketpcdn.com/articles/transparent_static.html 

这个是关于控件上面文本透明的例子。

3. 实验

3.1. 验证 WS_CLIPCHILDREN

(1)只需要在对话框的属性打个勾而已。

(2)需要继承一下CStatic类,然后重载一下OnPaint函数。

void MYStatic::OnPaint() { CPaintDC dc(this); // device context for painting   // TODO: Add your message handler code here   // 获得控件客户区矩形大小 CRect rect; GetClientRect(rect); // 绘制控件边框 dc.MoveTo(0,0); dc.LineTo(rect.Width(),0); dc.LineTo(rect.Width(),rect.Height()); dc.LineTo(0,rect.Height()); dc.LineTo(0,0);   // 绘制文本     dc.TextOut(rect.Width()/2 - 5,rect.Height()/2 - 5,"Hello");   // Do not call CStatic::OnPaint() for painting messages }

(3)

A. 当不设置对话框的Clip children属性的时候,效果如下图所示:

B. 当设置对话框的Clip children属性的时候,效果如下图所示:

很明显父窗口没有管子窗口的背景色如何绘制。子窗口的背景只是当时桌面上现有的窗口内容。

3.2. 验证WS_CLIPSIBLINGS

A. 首先遇到的第一个问题,当然是动态地改样式,这个并不是太复杂的问题。如何动态改样式,见下面的代码:

LONG style = GetWindowLong(m_pic.GetSafeHwnd(),GWL_STYLE); style = style | WS_CLIPSIBLINGS ; SetWindowLong(m_pic.GetSafeHwnd(),GWL_STYLE,style);

然后,在对话框上添加了一个图片控件和一个自绘制的控件(和上例类似,为了效果明显,我对自绘的控件进行了填充)

按照原文作者(helloj2ee)预先设想的效果,理想的情况应该如下:

但实际上最常见的是这样一种情况,就是无论原文作者设置不设置WS_CLIPSIBLINGS属性,当点击重绘图片控件的时候(m_pic.Invalidate()),

效果都一如既往:先开始图片控件(pic)被自定义控件(custom)压盖,然后重绘之后,图片控件(pic)压盖自定义控件(custom)。

如下错误图:

原因:

WS_CLIPSIBLINGS还和控件的叠加顺序有关。叠加顺序如果不对,你无法查看WS_CLIPSIBLINGS的效果。

就上面的问题,可以在VC编辑器里查看到控件的叠加顺序。

Pic控件是在custom控件的下方。(Tab Order和Z Order顺序是一致的)。这样设置不设置WS_CLIPSIBLINGS都无法看出效果。

 

B. 修改控件的压盖顺序,令pic控件压盖在custom控件之上(实际上是改变Tab order顺序)
 

 
这样就会出现预期的效果。

当不设置WS_CLIPSIBLINGS,pic控件会压盖custom控件,

而当设置了该属性,则pic控件不会压盖custom控件,重叠的区域由custom控件自己绘制。

效果如下:


4.结论

(1)WS_CLIPCHILDREN样式主要是用于父窗口,也就是说当在父窗口绘制的时候,父窗口上还有一个子窗口,

那么设置了这个样式的话,子窗口区域父窗口就不负责绘制。
 
(2)所有的overlapped和popup风格的窗口,都有WS_CLIPSIBLINGS 属性。

也就是说这类风格的窗口,你是去不掉WS_CLIPSIBLINGS 属性的,不会在它重叠的兄弟窗口绘图。
 
(3)更进一步说明,WS_CLIPSIBLINGS只是用于子窗口(For use with the WS_CHILD style only.)
 
(4)WS_CLIPSIBLINGS实际上还需要和控件的叠放顺序(z order)配合使用,才能看出明显的效果。

参考文献:

【1】http://www.cnblogs.com/helloj2ee/archive/2009/05/29/1491822.html      博主:helloj2ee

【2】http://blog.163.com/sandylin_wind/blog/static/935500552008105104617806/ 博主:Wind


 

0 0