設備環境類:CDC類、CPaintDC類、CClientDC類、CWindowDC類總結

  • DC    :   設備環境(Device Context)

                     1.  設備環境, 是 Window 內部的一種數據結構,用來保存與某個設備相關的繪製屬性信息。

                     2.  所有的繪製調用都必須通過設備環境 dc 進行。這些對象封裝了用於繪製線條、圖形以及文本的 Window API 。

                     3. 設備環境允許 Window 在設備中進行與設備無關的繪製。

                     4. 設備環境可用於繪製到屏幕、打印機可圖元文件。

  • HDC :   設備環境句柄

                     一個指針類型對像,指向 dc 對象 在 Window 內部的位置。

  • CDC、CClientDC、CPaintDC、CWindowDC的派生關係

         

------------------------------------------------------------------------------------------------------------------

1、CDC 類

        Window 使用與設備無關的設備環境dc來進行顯示。MFC 基礎類庫定義了設備環境對象類 --  CDC

其構造函數如下:
CDC::CDC()
{
    m_hDC        = NULL;
    m_hAttribDC  = NULL;
    m_bPrinting  = FALSE;
}

其析構函數如下:
CDC::~CDC()
{
    if (m_hDC != NULL)
        ::DeleteDC(Detach());
}


    

需要注意的是:在生成CDC對象的時候,並不像它的派生類那樣,在構造函數裏獲取相應的Windows設備上下文句柄。

所以,最好不要使用::GetDC等函數來獲取一個設備描述表,而是使用BOOL CreateCompatibleDC(CDC*pDC )創建一個設備描述表。

在 CDC析構函數中,如果設備描述表句柄不空,則調用DeleteDC刪除它。這是直接使用CDC時最好創建Windows設備描述表的理由。

如果設備描述表不是創建的,則應該在析構函數被調用前分離出設備描述表句柄並用::RealeaseDC釋放它,釋放後m_hDC爲空,則在析構函數調用時不會執行::DeleteDC

當然,不用擔心CDC的派生類的析構函數調用CDC的析構函數,因爲CDC::~CDC()不是虛擬析構函數。

 

使用CDC有兩種做法:

 

//  1.用 CWnd::GetDC()來初始化CDC對象
CDC		*pDC = GetDC();
pDC->MoveTo(m_ptOrigin); 
pDC->LineTo(point); 
ReleaseDC(pDC);

//  2.CreateCompatibleDC(CDC* pDC ) 來創建 CDC 對象
//  用於爲當前 dc 在內存創建一個兼容DC。這樣要可消除閃爍
CDC		dcMem; 
dcMem.CreateCompatibleDC(&dc);			//創建設備描述表
pbmOld = dcMem.SelectObject(&m_bmBall);	//更改設備描述表屬性

…//作一些繪製操作

dcMem.SelectObject(pbmOld);				//恢復設備描述表的屬性
dcMem.DeleteDC();						//可以不調用,而讓析構函數去刪除設備描述表


 

 

 

2、CClientDC 類

       CClientDC 類,在構造函數中調用 Window API 函數 GetDC(),在析構函數中調用ReleaseDC()。

       CClientDC 類只能在客戶區繪圖。面所謂的客戶區是指窗口區域去掉邊框、標題欄、菜單欄、工具欄、狀態欄等之外的部分。

       它是用戶可操作的區域。

       CClientDC類的窗口句柄保存在成員變量m_hWnd,爲構造CClientDC,需將CWnd作爲參數傳遞給構造函數。 

    在使用CClientDC進行繪圖時,一般要調用GetClientRect()函數來獲取客戶區域的大小;

//CClientDC : public CDC  特點:構造函數時候GetDC()  析構函數時候調用ReleaseDC 
// CClientDC dc(GetParent());	GetParent view的父窗口 也就是frame 但不能出客戶區域 
CClientDC dc(this);  		//指針構造DC 
dc.MoveTo(m_ptOrigin); 
dc.LineTo(point);

 

3、CPaintDC類

        CPaintDC 用於響應窗口重繪消息(WM_PAINT)是的繪圖輸出。

        CPaintDC在構造函數中調用BeginPaint()取得設備上下文,在析構函數中調用 EndPaint()釋放設備上下文。

        EndPaint()除了釋放設備上下文外,還負責從消息隊列中清除WM_PAINT消息。

        因此,在處理窗口重畫時,必須使用CPaintDC,否則WM_PAINT消息無法從消息隊列中清除,將引起不斷的窗口重畫

        CPaintDC也只能用在WM_PAINT消息處理之中。

// MFC中 CView 對 WM_PAINT 消息的實現方法如下:
void CView::OnPaint()
{
	// standard paint routine
	CPaintDC dc(this);
	OnPrepareDC(&dc);
	OnDraw(&dc);
}

// 在棧中定義了CPaintDC類型的變量dc,隨着構造函數的調用獲取了設備描述表;
// 設備描述表使用完畢,超出其有效範圍就被自動地清除,隨着析構函數的調用,其獲取的設備描述表被釋放。

// 如果希望在堆中創建,例如

CPaintDC *pDC;
pDC = new CPaintDC(this)

// 則在使用完畢時,用delete刪除pDC:
delete pDC;


 

 

4、CWindowDC 類

       CWindowDC對象在構造時調用Windows API函數GetWindowDC,在析構時調用相應的API函數ReleaseDC。

       這意味着CWindowDC對象可訪問CWnd所指向的爲整個全屏幕區域; 

       CWindowDC允許在顯示器的任意位置繪圖。座標原點在整個窗口的左上角。 

       在使用CWindowDC進行繪圖時,一般要調用GetWindowRect函數來獲取整個應用程序窗口區域的大小; 

       CWindowDC類的窗口句柄保存在成員變量m_hWnd,爲構造CClientDC,需將CWnd作爲參數傳遞給構造函數。 

// CWindowDC 也是派生於CDC 構造、析構也是類似ClientDC 。可以訪問整個程序區域 包括客戶區與非客戶區 
// CWindowDC dc(GetParent());			繪製父窗體 文檔結構中 可以繪製到框架類 乃至非客戶區上 
// CWindowDC dc(GetDesktopWindow());	可以繪製到整個非客戶區 桌面上 
CWindowDC dc(this);  //繪製當前窗口 
dc.MoveTo(m_ptOrigin); 
dc.LineTo(point);

 

=================================================

 

附: Windows 程序設計 對 圖形基礎的描述:
 

1. 取得設備上下文句柄

       Windows 提供了幾種取得設備上下文句柄的方法。如果在處理一個消息時取得了設備上下文句柄,應該在退出窗口函數之前釋放它(或者刪除它)。

       一旦釋放了句柄,它就不再有效了。對於打印機設備上下文句柄,規則就沒有這麼嚴格。

       最常用的用於取得並釋放設備上下文句柄的方法是:在處理WM_PAINT 消息時,使用 BeginPaint 和 EndPaint 調用:

       hdc = BeginPaint(hwnd, &ps);   

       // 其他操作

       EndPaint(hwnd, &ps); 

      其中,ps 爲PAINTSTRUCT 結構對象,該結構中的 hdc 字段是 BeginPaint 傳回的設備上下文句柄,PAINTSTRUCT 結構又包含一個名爲rcPaint 的RECT(矩形)結構,

     rcPaint 定義一個包圍窗口顯示區域無效的矩形。使用從BeginPaint獲得的設備上下文句柄,只能在這個區域內繪圖。BeginPaint 調用使該區域有效。

 

     Windows 程序還可以在處理非WM_PAINT消息時取得設備上下文句柄

     hdc = GetDC(hwnd);

     // 其他操作

     ReleaseDC(hwnd, hdc);

 

     這個設備上下文適用於窗口句柄爲hwnd 的顯示區域。

     這些調用與BeginPaint 和 EndPaint 的組合之間的區別是,利用從GetDC傳回的句柄可以在整個顯示區域上繪圖。

     當然,GetDC 和 ReleaseDC 不使顯示區域中任何可能的無效區域變成有效。

 

     Windows 程序還可以取得適用於整個窗口的設備上下文句柄:

     hdc = GetWindowDC(hwnd);

     // 其他操作

     ReleaseDC(hwnd, hdc);

   

     這個設備上下文除了顯示區域之外,還包括窗口的標題欄、菜單、滾動條、和框架。

     GetWindowDC 函數很少使用,如果想嘗試用一用它,則必須攔截處理WM_NCPAINT 消息,

     Windows 使用該消息在窗口的非顯示區域上繪圖。

     BeginPaint、GetDC和GetWindowDC獲得的設備上下文句柄都和顯示器上的某個特定窗口相關。

     取得設備上下文句柄的另一個更通用的函數是CreateDC:

     hdc = CreateDC(pszDreiver, pszDevice, pszOutput, pData);

     // 其他操作

     DeleteDC(hdc);

     .......

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章