我是個喜歡瞎琢磨的人。尤爲是這幾天心情很是鬱悶。因而開始琢磨了…….琢磨的問題就是WS_CLIPCHILDREN和WS_CLIPSIBLINGS兩種窗口樣式的理解。html
1.求助MSDNwindows
個人第一步固然是求助MSDN。在MSDN裏面有詳細的解釋。app
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.this
讀E文是一件困難的事,爲了避免讓你們再重複個人痛苦,我就越俎代庖翻譯一下:WS_CLIPCHILDREN樣式主要是用於父窗口,也就是說當在父窗口繪製的時候,父窗口上還有一個子窗口,那麼設置了這個樣式的話,子窗口區域父窗口就不負責繪製。spa
那麼按照MSDN的理解,能夠用下面這幅圖來表示:翻譯
圖 1‑1 WS_CLIPCHILDREN樣式的初理解code
1.1 WS_CLIPSIBLINGScdn
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順序)
圖 3‑7 控件的Tab順序
這樣就會出現預期的效果。當不設置WS_CLIPSIBLINGS,pic控件會壓蓋custom控件,而當設置了該屬性,則pic控件不會壓蓋custom控件,重疊的區域由custom控件本身繪製。
圖 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)配合使用,才能看出明顯的效果。