狀態(tài)條CStatusBar
其他各類控制窗口,如列表框CList,編輯框CEdit,組合框CComboBox,按鈕Cbutton等。
通常,直接使用這些類。
在MFC下窗口的銷毀
窗口對象使用完畢,應(yīng)該銷毀。在MFC下,一個窗口對象的銷毀包括HWND窗口對象的銷毀和MFC窗口對象的銷毀。一般情況下,MFC編程框架自動地處理了這些。
(1)對CFrameWnd和CView的派生類
這些窗口的關(guān)閉導(dǎo)致銷毀窗口的函數(shù)DestroyWindow被調(diào)用。銷毀Windows窗口時,MFC框架調(diào)用的最后一個成員函數(shù)是OnNcDestroy函數(shù),該函數(shù)負責Windows清理工作,并在最后調(diào)用虛擬成員函數(shù)PostNcDestroy。CFrameWnd和CView的PostNcDestroy調(diào)用delete this刪除自身這個MFC窗口對象。
所以,對這些窗口,如前所述,應(yīng)在堆(Heap)中分配,而且,不要對這些對象使用delete操作。
(2)對Windows Control窗口
在它們的析構(gòu)函數(shù)中,將調(diào)用DestroyWidnow來銷毀窗口。如果在棧中分配這樣的窗口對象,則在超出作用范圍的時候,隨著析構(gòu)函數(shù)的調(diào)用,MFC窗口對象和它的Windows window對象都被銷毀。如果在堆(Heap)中分配,則顯式調(diào)用delete操作符,導(dǎo)致析構(gòu)函數(shù)的調(diào)用和窗口的銷毀。
所以,這種類型的窗口應(yīng)盡可能在棧中分配,避免用額外的代碼來銷毀窗口。如前所述的CMainFrame的成員變量m_wndStatusBar和m_wndToolBar就是這樣的例子。
(3)對于程序員直接從CWnd派生的窗口
程序員可以在派生類中實現(xiàn)上述兩種機制之一,然后,在相應(yīng)的規(guī)范下使用。
后面章節(jié)將詳細的討論應(yīng)用程序退出時關(guān)閉、清理窗口的過程。
設(shè)備描述表
設(shè)備描述表概述
當一個應(yīng)用程序使用GDI函數(shù)時,必須先裝入特定的設(shè)備驅(qū)動程序,然后為繪制窗口準備設(shè)備描述表,比如指定線的寬度和顏色、刷子的樣式和顏色、字體、剪裁區(qū)域等等。不像其他Win32結(jié)構(gòu),設(shè)備描述表不能被直接訪問,只能通過系列Win32函數(shù)來間接地操作。
如同Windows“窗口類”一樣,設(shè)備描述表也是一種Windows數(shù)據(jù)結(jié)構(gòu),用來描述繪制窗口所需要的信息。它定義了一個坐標映射模式、一組GDI圖形對象及其屬性。這些GDI對象包括用于畫線的筆,繪圖、填圖的刷子,位圖,調(diào)色板,剪裁區(qū)域,及路徑(Path)。
表2-2列出了設(shè)備描述表的結(jié)構(gòu)和各項缺省值,表2-3列出了設(shè)備描述表的類型,表2-4顯示設(shè)備描述表的類型。
表2-2 設(shè)備描述表的結(jié)構(gòu)
屬性缺省值
Background colorBackground color setting from Windows Control Panel (typically, white)
Background modeOPAQUE
BitmapNone
BrushWHITE_BRUSH
Brush origin(0,0)
Clipping regionEntire window or client area with the update region clipped, as appropriate. Child and pop-up windows in the client area may also be clipped
PaletteDEFAULT_PALETTE
Current pen position(0,0)
Device originUpper left corner of the window or the client area
Drawing modeR2_COPYPEN
FontSYSTEM_FONT (SYSTEM_FIXED_FONT for applications written to run with Windows versions 3.0 and earlier)
Intercharacter spacing0
Mapping modeMM_TEXT
PenBLACK_PEN
Polygon-fill modeALTERNATE
Stretch modeBLACKONWHITE
Text colorText color setting from Control Panel (typically, black)
Viewport extent(1,1)
Viewport origin(0,0)
Window extent(1,1)
Window origin(0,0)
表2-3 設(shè)備描述表的分類
Display顯示設(shè)備描述表,提供對視頻顯示設(shè)備上的繪制操作的支持
Printer打印設(shè)備描述表,提供對打印機、繪圖儀設(shè)備上的繪制操作的支持
Memory內(nèi)存設(shè)備描述表,提供對位圖操作的支持
Information信息設(shè)備描述表,提供對操作設(shè)備信息獲取的支持
表2-3中的顯示設(shè)備描述表又分三種類型,如表2-4所示。
表2-4 顯示設(shè)備描述表的分類
名稱特點功能
Class Device
Contexts提供對Win16的向后兼容
Common
Device
Contexts在Windows系統(tǒng)的高速緩沖區(qū),數(shù)量有限Applicaion獲取設(shè)備描述表時,Windows用缺省值初始化該設(shè)備描述表,Application使用它完成繪制操作,然后釋放
Private
Device
Contexts沒有數(shù)量限制,用完不需釋放一次獲取,多次使用多次使用過程中,每次設(shè)備描述表屬性的任何修改或變化都會被保存,以支持快速繪制
(1)使用設(shè)備描述表的步驟
要使用設(shè)備描述表,一般有如下步驟:
獲取或者創(chuàng)建設(shè)備描述表;
必要的話,改變設(shè)備描述表的屬性;
使用設(shè)備描述表完成繪制操作;
釋放或刪除設(shè)備描述表。
Common設(shè)備描述表通過::GetDC,::GetDCEx,::BeginPaint來獲得一個設(shè)備描述表,用畢,用::ReleaseDC或::EndPaint釋放設(shè)備描述表;
Printer設(shè)備描述表通過::CreateDC創(chuàng)建設(shè)備描述表,用::DeleteDC刪除設(shè)備描述表。
Memory設(shè)備描述表通過::CreateCompatibleDC創(chuàng)建設(shè)備描述表,用::DeleteDC刪除。
Information設(shè)備描述表通過::CreateIC創(chuàng)建設(shè)備描述表,用::DeleteDC刪除。
(2)改變設(shè)備描述表屬性的途徑
要改變設(shè)備描述表的屬性,可通過以下途徑:
用::SelectObject選入新的除調(diào)色板以外的GDI Object到設(shè)備描述表中;
對于調(diào)色板,使用::SelectPalette函數(shù)選入邏輯調(diào)色板,并使用::RealizePalette把邏輯調(diào)色板的入口映射到物理調(diào)色板中。
用其他API函數(shù)改變其他屬性,如::SetMapMode改變映射模式。
設(shè)備描述表在MFC中的實現(xiàn)
MFC提供了CDC類作為設(shè)備描述表類的基類,它封裝了Windows的HDC設(shè)備描述表對象和相關(guān)函數(shù)。
CDC類
CDC類包含了各種類型的Windows設(shè)備描述表的全部功能,封裝了所有的Win32 GDI 函數(shù)和設(shè)備描述表相關(guān)的SDK函數(shù)。在MFC下,使用CDC的成員函數(shù)來完成所有的窗口繪制工作。
CDC 類的結(jié)構(gòu)示意圖2-2所示。
CDC類有兩個成員變量:m_hDC,m_hAttribDC,它們都是Windows設(shè)備描述表句柄。CDC的成員函數(shù)作輸出操作時,使用m_Hdc;要獲取設(shè)備描述表的屬性時,使用m_hAttribDC。
在創(chuàng)建一個CDC類實例時,缺省的m_hDC等于m_hAttribDC。如果需要的話,程序員可以分別指定它們。例如,MFC框架實現(xiàn)CMetaFileDC類時,就是如此:CMetaFileDC從物理設(shè)備上讀取設(shè)備信息,輸出則送到元文件(metafile)上,所以m_hDC和m_hAttribDC是不同的,各司其責。還有一個類似的例子:打印預(yù)覽的實現(xiàn),一個代表打印機模擬輸出,一個代表屏幕顯示。
CDC封裝::SelectObject(HDC hdc,HGDIOBJECT hgdiobject)函數(shù)時,采用了重載技術(shù),即它針對不同的GDI對象,提供了名同而參數(shù)不同的成員函數(shù):
SelectObject(CPen *pen)用于選入筆;
SelectObject(CBitmap* pBitmap)用于選入位圖;
SelectObject(CRgn *pRgn)用于選入剪裁區(qū)域;
SelectObject(CBrush *pBrush)用于選入刷子;
SelectObject(CFont *pFont)用于選入字體;
至于調(diào)色板,使用SelectPalette(CPalette *pPalette,BOOL bForceBackground )選入調(diào)色板到設(shè)備描述表,使用RealizePalletter()實現(xiàn)邏輯調(diào)色板到物理調(diào)色板的映射。
從CDC派生出功能更具體的設(shè)備描述表
從CDC 派生出四個功能更具體的設(shè)備描述表類。層次如圖2-3所示。
下面,分別討論派生出的四種設(shè)備描述表。
CCientDC
代表窗口客戶區(qū)的設(shè)備描述表。其構(gòu)造函數(shù)CClientDC(CWnd *pWin)通過::GetDC獲取指定窗口的客戶區(qū)的設(shè)備描述表HDC,并且使用成員函數(shù)Attach把它和CClientDC對象捆綁在一起;其析構(gòu)函數(shù)使用成員函數(shù)Detach把設(shè)備描述表句柄HDC分離出來,并調(diào)用::ReleaseDC釋放設(shè)備描述表HDC。
CPaintDC
僅僅用于響應(yīng)WM_PAINT消息時繪制窗口,因為它的構(gòu)造函數(shù)調(diào)用了::BeginPaint獲取設(shè)備描述表HDC,并且使用成員函數(shù)Attach把它和CPaintDC對象捆綁在一起;析構(gòu)函數(shù)使用成員函數(shù)Detach把設(shè)備描述表句柄HDC分離出來,并調(diào)用::EndPaint釋放設(shè)備描述表HDC,而::BeginPaint和::EndPaint僅僅在響應(yīng)WM_PAINT時使用。
CMetaFileDC
用于生成元文件。
CWindowDC
代表整個窗口區(qū)(包括非客戶區(qū))的設(shè)備描述表。其構(gòu)造函數(shù)CWindowDC(CWnd *pWin)通過::GetWindowDC獲取指定窗口的客戶區(qū)的設(shè)備描述表HDC,并使用Attach把它和CWindowDC對象捆綁在一起;其析構(gòu)函數(shù)使用Detach把設(shè)備描述表HDC分離出來,調(diào)用::ReleaseDC釋放設(shè)備描述表HDC。
MFC設(shè)備描述表類的使用
使用CPaintDC、CClientDC、CWindowDC的方法
首先,定義一個這些類的實例變量,通常在棧中定義。然后,使用它。
例如,MFC中CView對WM_PAINT消息的實現(xiàn)方法如下:
void CView::OnPaint()
{
// standard paint routine
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
在棧中定義了CPaintDC類型的變量dc,隨著構(gòu)造函數(shù)的調(diào)用獲取了設(shè)備描述表;設(shè)備描述表使用完畢,超出其有效范圍就被自動地清除,隨著析構(gòu)函數(shù)的調(diào)用,其獲取的設(shè)備描述表被釋放。
如果希望在堆中創(chuàng)建,例如
CPaintDC *pDC;
pDC = new CPaintDC(this)
則在使用完畢時,用delete刪除pDC:
delete pDC;
評論