zoukankan      html  css  js  c++  java
  • 关于WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解

    我是个喜欢瞎琢磨的人。尤其是这几天心情非常郁闷。于是开始琢磨了…….琢磨的问题就是WS_CLIPCHILDREN和WS_CLIPSIBLINGS两种窗口样式的理解。

      1.求助MSDN

      我的第一步当然是求助MSDN。在MSDN里面有详细的解释。

      1.1 WS_CLIPCHILDREN

      WS_CLIPCHILDREN样式从字面上可以理解成ClipChildren,裁减子窗口。

      MSDN里的E文解释:Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.

      读E文是一件困难的事,为了不让大家再重复我的痛苦,我就越俎代庖翻译一下:WS_CLIPCHILDREN样式主要是用于父窗口,也就是说当在父窗口绘制的时候,父窗口上还有一个子窗口,那么设置了这个样式的话,子窗口区域父窗口就不负责绘制。

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

      图 1‑1 WS_CLIPCHILDREN样式的初理解

      1.1 WS_CLIPSIBLINGS

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

      MSDN里的E文解释: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.
    中文意思是:子窗口间相互裁减。也就是说当两个窗口相互重叠时,设置了WS_CLIPSIBLINGS样式的子窗口重绘时不能绘制被重叠的部分。反之没有设置WS_CLIPSIBLINGS样式的子窗口重绘时是不考虑重叠不重叠,统统重绘。


      图 1‑2 WS_CLIPSIBLINGS样式的初理解

      2.求助Google

      最初看完MSDN,说实话,没有像现在这么清晰画出上面两幅图。而是一片茫然。Google上我所搜索到的中文的还算是比较好的一篇,应该是这篇:http://blog.163.com/sandylin_wind/blog/static/935500552008105104617806/

      大家可以看看,但是确实我觉得还不够详细,因此才会写篇博文,讨论一下这个问题。

      当然E文的专注于WS_CLIPCHILDREN和WS_CLIPSIBLINGS讨论的也比较少。可能老外由于懂E文,所以不像我们这样费事。

      经过一番搜索,仍然有一些比较重要的结论,列举如下:

      (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

      简单到什么程度呢?只需要在对话框的属性打个勾而已。

    简单到什么程度呢?只需要在对话框的属性打个勾而已。

      图 3‑1 如何设置对话框Clip Children属性

      我们先做做第一个程序,这个程序唯一有点难的地方就在于需要继承一下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
    }
    当我们不设置对话框的Clip children属性的时候,效果如下图所示:


      图 3‑2 效果图

       当设置了Clip children属性的时候,接下来是见证奇迹的时刻 。^_^

     

      图 3‑3 效果图

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

      3.2 验证WS_CLIPSIBLINGS

      当第一个实验成功之后,我原以为WS_CLIPSIBLINGS也会相当地简单。结果我花费了大量的时间纠缠在这个问题上。首先遇到的第一个问题,当然是动态地改样式,这个并不是太复杂的问题。如何动态改样式,见下面的代码:

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

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

      按照我预先设想的效果,理想的情况应该如下:


    图 3‑4 预想的效果图

      发现结果很混乱,每回都得不到我想要的,具有随机性。甚至有的时候按照我的预想,有的时候则完全不管我的心情。哪怕我气的吹胡子瞪眼睛,也是枉然。

      最常见的是这样一种情况,就是无论我设置不设置WS_CLIPSIBLINGS属性,当点击重绘图片控件的时候(m_pic.Invalidate()),效果都一如既往,先开始图片控件(pic)被自定义控件(custom)压盖,然后重绘之后,图片控件(pic)压盖自定义控件(custom)。

     

      图 3‑5 一种错误图

      经过一段时间的郁闷,我最终找到了问题之所在,是这样的一个结论:WS_CLIPSIBLINGS还和控件的叠加顺序有关。叠加顺序如果不对,你无法查看WS_CLIPSIBLINGS的效果。就上面的问题,我们可以在VC编辑器里查看到控件的叠加顺序。


      图 3‑6控件的Tab顺序

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

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

    关于WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解

      图 3‑7 控件的Tab顺序

      这样就会出现预期的效果。当不设置WS_CLIPSIBLINGS,pic控件会压盖custom控件,而当设置了该属性,则pic控件不会压盖custom控件,重叠的区域由custom控件自己绘制。

    关于WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解

      图 3‑8 预期的效果

      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)配合使用,才能看出明显的效果。

  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/mokliu/p/2138818.html
Copyright © 2011-2022 走看看