視窗風格是各種視窗開發的重要基礎之一。它可以分為普通風格(WS_系列)和擴充風格(WS_EX_系列)。從其特點上,主要分成兩大類:
1. 一類表明視窗和其它視窗的關係,包括:WS_CHILD、WS_POPUP、WS_OVERLAPPED、WS_CLIPCHILDREN、WS_CLIPSIBLINGS、WS_GROUP、
WS_EX_TOPMOST、WS_EX_MDICHILD等。(這裡的關係並不是指Foreground/Background window和Z-Order的概念)
2. 一類表明視窗自身的外觀特徵,包括:WS_BORDER、WS_CAPTION、WS_MINIMIZE、WS_MINIMIZEBOX、WS_DLGFRAME、
WS_EX_DLGMODALFRAME 、WS_EX_WINDOWEDGE等。
例如:
一個標準的Dialog視窗,除了Dialog自身的風格(DS_系列)外,其視窗風格如下:
普通風格:WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU
擴充風格:WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT | WS_EX_APPWINDOW
一個標準的Frame視窗,其風格如下:
普通風格:WS_CAPTION | WS_OVERLAPPED | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU | WS_MAXIMIZE | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
擴充風格: WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_WINDOWEDGE
大部分的視窗風格都比較容易理解。下面重點講解一下第一類風格中主要幾個風格的差異:
- WS_POPUP和WS_OVERLAPPED的視窗均為top-level視窗,即:如果採用SetWindowPos改變其位置需要使用Screen座標,而不是Client座標。不同的是,WS_POPUP視窗有父視窗,使用GetParent方法可以獲得;而WS_OVERLAPPED視窗卻沒有,GetParent方法為NULL。也就是說,對於一個介面應用程式而言,一定存在至少一個WS_OVERLAPPED視窗(作為應用程式的主視窗)。
此外,WS_OVERLAPPED視窗總是有title bar和border,即使你顯示刪除WS_CAPTION和WS_BORDER風格,而WS_POPUP卻沒有該特點。
- WS_CLIPCHILDREN:繪圖時,將該視窗中的子視窗所佔的地區排除在外。當你建立父視窗時,可以使用該風格。如果使用Invalidate方法,這部分地區不會計算在更新地區內。因此,有可能產生這些子視窗沒有重新整理的問題。
- WS_CLIPSIBLINGS:繪圖時,將該子視窗和其同級其它子視窗(具有相同的父視窗)重疊的地區排除在外。如果使用Invalidate方法,這部分地區不會計算在更新地區內。這樣此時繪畫,就不會畫到其它視窗上。
- WS_EX_APPWINDOW:強迫一個top-level視窗在可見時,出現在TaskBar上。但這並不意味著一個視窗出現在TaskBar上就一定需要該風格,其實,如果是主線程的第一個視窗(m_pMainWnd),即使沒有該風格,也會出現在TaskBar上。
- WS_EX_LAYERED:建立Layered視窗,即:具有複雜視覺特徵的視窗,比如:透明視窗。該風格不能用於子視窗。主要有SetLayeredWindowAttributes和UpdateLayeredWindow兩個方法,其中,後者更加靈活。前者通常用來實現透明視窗等簡單任務。
上面提到了top-level視窗,因此有必要解釋下面幾個方法的差異:
GetParent方法:如果是子視窗(具有WS_CHILD風格),那麼總能得到一個有效臨時視窗對象(Immediate Window);如果是top-level視窗,又分為兩種情況:如果該視窗為非擁有(unowned),那麼返回NULL,否則,返回擁有者視窗對象。因此,GetParent並非總是返回父視窗。
GetOwner方法:獲得擁有者視窗,預設為父視窗。父子視窗中的子視窗只能出現在父視窗的用戶端區域,而具有擁有者視窗的視窗可以出現在案頭的任何位置。這裡的Owner視窗,不同於API方法GetWindow獲得的Owner視窗,它是MFC特定的概念。
GetAncestor方法:獲得祖先視窗。有三個選擇,GA_PARENT, GA_ROOT, GA_ROOTOWNER
MFC中的Immediate視窗:在MSDN中關於MFC的描述中,經常能看到Immediate和Permanent Window字樣。其中,Immediate視窗是MFC中臨時產生的視窗對象,MFC會定期清理這些對象,因此通常不可以儲存作為類成員變數。
原文地址: http://citycowboy.blog.sohu.com/82857453.html