日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

使用CDC的四個(gè)派生類(lèi)CClientDC,CPaintDC,CWindowDC,CMetaFileD

 just_person 2009-08-28

使用CDC的四個(gè)派生類(lèi)CClientDC,CPaintDC,CWindowDC,CMetaFileD

1.首先介紹一下什么是DC(設(shè)備描述表)

Windows應(yīng)用程序通過(guò)為指定設(shè)備(屏幕,打印機(jī)等)創(chuàng)建一個(gè)設(shè)備描述表(Device Context, DC)在DC表示的邏輯意義的“畫(huà)布”上進(jìn)行圖形的繪制。DC是一種包含設(shè)備信息的數(shù)據(jù)結(jié)構(gòu),它包含了物理設(shè)備所需的各種狀態(tài)信息。Win32程序在繪制圖形之前需要獲取DC的句柄HDC,并在不繼續(xù)使用時(shí)釋放掉。

2.CDC及其派生類(lèi)

CDC及其派生類(lèi)的繼承視圖: CObject public |------CDC public |------CClientDC public |------CPaintDC public |------CWindowDC public |------CMetaFileDC (注意: 除CMetaFileDC以外的三個(gè)派生類(lèi)用于圖形繪制.) [以下幾段是翻譯MSDN中資料] CDC類(lèi)定義了一個(gè)設(shè)備描述表相關(guān)的類(lèi),其對(duì)象提供成員函數(shù)操作設(shè)備描述表進(jìn)行工作,如顯示器,打印機(jī),以及顯示器描述表相關(guān)的窗口客戶(hù)區(qū)域。

通過(guò)CDC的成員函數(shù)可進(jìn)行一切繪圖操作。CDC提供成員函數(shù)進(jìn)行設(shè)備描述表的基本操作,使用繪圖工具,選擇類(lèi)型安全的圖形設(shè)備結(jié)構(gòu)(GDI),以及色彩,調(diào)色板。除此之外還提供成員函數(shù)獲取和設(shè)置繪圖屬性,映射,控制視口,窗體范圍,轉(zhuǎn)換坐標(biāo),區(qū)域操作,裁減,劃線(xiàn)以及繪制簡(jiǎn)單圖形(橢圓,多邊形等)。成員函數(shù)也提供繪制文本,設(shè)置字體,打印機(jī)換碼,滾動(dòng), 處理元文件。

通過(guò)CDC的成員函數(shù)可進(jìn)行一切繪圖操作。CDC提供成員函數(shù)進(jìn)行設(shè)備描述表的基本操作,使用繪圖工具,選擇類(lèi)型安全的圖形設(shè)備結(jié)構(gòu)(GDI),以及色彩,調(diào)色板。除此之外還提供成員函數(shù)獲取和設(shè)置繪圖屬性,映射,控制視口,窗體范圍,轉(zhuǎn)換坐標(biāo),區(qū)域操作,裁減,劃線(xiàn)以及繪制簡(jiǎn)單圖形(橢圓,多邊形等)。成員函數(shù)也提供繪制文本,設(shè)置字體,打印機(jī)換碼,滾動(dòng), 處理元文件。

其派生類(lèi): PaintDC: 封裝BeginPaint和EndPaint兩個(gè)API的調(diào)用。 CClientDC: 處理顯示器描述表的相關(guān)的窗體客戶(hù)區(qū)域。 CWindowDC: 處理顯示器描述表相關(guān)的整個(gè)窗體區(qū)域,包括了框架和控 件(子窗體)。 CMetaFileDC: 與元文件相關(guān)的設(shè)備描述表關(guān)聯(lián)。

CDC提供兩個(gè)函數(shù),GetLayout和SetLayout用于反轉(zhuǎn)設(shè)備描述表的布局。用于方便阿拉伯,希伯來(lái)的書(shū)寫(xiě)文化習(xí)慣的設(shè)計(jì),以及非歐洲表中的字體布局。

CDC包含兩個(gè)設(shè)備描述表,m_hDC和m_hAttribDC對(duì)應(yīng)于相同的設(shè)備,CDC為m_hDC指定所有的輸出GDI調(diào)用,大多數(shù)的GDI屬性調(diào)用由m_hAttribDC控制。(如,GetTextColor是屬性調(diào)用,而SetTextColor是一種輸出調(diào)用。)

例子:框架使用這兩個(gè)設(shè)備描述表,一個(gè)對(duì)象從物理設(shè)備中讀取屬性輸出到元文件。打印機(jī)預(yù)覽在框架中被執(zhí)行時(shí)也是相同的形式。你也可以編寫(xiě)代碼使用這兩個(gè)設(shè)備描述表在你的應(yīng)用程序中進(jìn)行類(lèi)似的操作。

3.使用方法

創(chuàng)建一個(gè)UseDC的MFC單文檔程序,定制7個(gè)按鈕用來(lái)選擇使用的DC,每個(gè)按鈕由一個(gè)成員變量標(biāo)識(shí)控制[互斥],分別是

bool m_bHDCDisplay ---- 使用整個(gè)屏幕的HDC; bool m_bHDC ---- 使用當(dāng)前視圖的對(duì)應(yīng)的DC; bool m_bCDC ---- 使用CDC類(lèi)[當(dāng)前視圖窗體]; bool m_bCClientDC ---- 使用CClientDC類(lèi)[視圖客戶(hù)區(qū)域DC]; bool m_bCPaintDC ---- 使用CPaintDC[視圖窗體]; bool m_bCWindowDC ---- 使用CWindowDC[整個(gè)視圖窗體]; bool m_bCMetaFileDC ---- 使用CMetaFileDC

添加7個(gè)按鈕的響應(yīng)函數(shù)以控制這些bool變量.(這里比較簡(jiǎn)單我就不提供代碼了)

視圖類(lèi)構(gòu)造函數(shù):

CUseDCView::CUseDCView()

{

this->m_bHDCDisplay = false; this->m_bHDC = false; this->m_bCDC = false; this->m_bCClientDC = false; this->m_bCPaintDC = false; this->m_bCWindowDC = false; this->m_bCMetaFileDC = false; m_hMetaFile = NULL;

}

視圖類(lèi)OnDraw函數(shù)

void CUseDCView::OnDraw(CDC* pDC)

{

CUseDCDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

//窗體在OnDraw中會(huì)自動(dòng)傳入關(guān)聯(lián)當(dāng)前視圖窗體客戶(hù)矩形區(qū)域的CPaintDC //才能獲取相應(yīng)的設(shè)備描述表

HDC HDCDisplay = NULL; //屏幕DC的句柄 對(duì)應(yīng)m_bHDCDisplay HDC hDC = NULL; //普通DC的句柄 對(duì)應(yīng)m_bHDC; CDC * pCDC = NULL; //對(duì)應(yīng)m_bCDC CClientDC * pClientDC = NULL; //對(duì)應(yīng)m_bCClientDC CPaintDC * pPaintDC = NULL; //對(duì)應(yīng)m_bCPaintDC CWindowDC * pWindowDC = NULL; //對(duì)應(yīng)m_bCWindowDC CMetaFileDC * pMetaFileDC = NULL; //對(duì)應(yīng)m_bMetaFileDC

HMETAFILE hMetaFile = NULL; <!--[if !supportLineBreakNewLine]--> <!--[endif]-->

RECT rect; //定義一個(gè)設(shè)備左上角的矩形區(qū)域 rect.left = 0; rect.top = 0; rect.right = 200; rect.bottom = 30;

//注意: HDCDisplay和hDC的::Release()中第一個(gè)參數(shù)HWND //與GetDC()的第一個(gè)參數(shù)必須對(duì)應(yīng)。 if(m_bHDCDisplay) { HDCDisplay = ::GetDC(NULL); //獲得整個(gè)顯示器區(qū)域的DC ::DrawText(HDCDisplay, "HDC of Display", 14, &rect, DT_LEFT|DT_TOP); ::ReleaseDC(NULL, HDCDisplay); HDCDisplay = NULL; } if(m_bHDC) //繪制在客戶(hù)區(qū)域 { hDC = ::GetDC(this->m_hWnd); //本窗體的DC ::DrawText(hDC, "HDC", 3, &rect, DT_LEFT|DT_TOP); ::ReleaseDC(this->m_hWnd, hDC); hDC = NULL; } else if(m_bCDC){ //必須釋放由程序框架傳入的pDC才能獲取當(dāng)前客戶(hù)區(qū)域設(shè)備描述表 pCDC = this->GetDC(); //當(dāng)前窗體(視圖)的設(shè)備描述表 pCDC->DrawText("Use class CDC", 13, &rect, DT_LEFT|DT_TOP); this->ReleaseDC(pCDC); pCDC = NULL; } else if(m_bCClientDC){ pClientDC = new CClientDC(this); //獲取本窗體客戶(hù)區(qū)域的DC pClientDC->DrawText("Use class CClientDC", &rect, DT_LEFT|DT_TOP); delete pClientDC; pClientDC = NULL; } else if(m_bCPaintDC) { //測(cè)試當(dāng)前傳入的CDC是不是CPaintDC pPaintDC = (CPaintDC*)pDC; pPaintDC->DrawText("Use class CPaintDC", &rect, DT_LEFT|DT_TOP); } else if(m_bCWindowDC){ pWindowDC = new CWindowDC(this); //獲取本窗體框架和客戶(hù)區(qū)域的DC //注意:繪制字符串的矩形區(qū)域空白部分覆蓋了視圖子窗體的邊緣. pWindowDC->DrawText("Use class CWindowDC", &rect, DT_LEFT|DT_TOP); delete pWindowDC; pWindowDC = NULL; } else if(m_bCMetaFileDC){ //傳入pDC->m_hDC使用pDC繪制,圖形在視圖窗體左上角 pMetaFileDC = new CMetaFileDC(); pMetaFileDC->m_hDC = pDC->m_hDC; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); delete pMetaFileDC; pDC->PlayMetaFile(m_hMetaFile); }

}

MFC程序中使用CPaintDC在視圖窗口中繪制圖象時(shí)要注意,應(yīng)該在OnPaint()編寫(xiě)關(guān)于CPaintDC相關(guān)的代碼,而不是在OnDraw()中.但是請(qǐng)注意,如果使用OnPaint()函數(shù)響應(yīng)WM_PAINT事件,OnDraw函數(shù)將會(huì)被屏蔽;

可以使用以下代碼測(cè)試:

在CUseDCView.h,CUseDCView的類(lèi)定義中語(yǔ)句DECLARE_MESSAGE_MAP()之前加上afx_msg void OnPaint(),在CUseDCView.cpp中BEGIN_MESSAGE_MAP (CUseDCView, CView)和END_MESSAGE_MAP()之間加上ON_WM_PAINT()。

void CUseDCView::OnPaint()

{ CPaintDC dc(this); RECT rect; rect.left = 0; rect.top = 0; rect.right = 200; rect.bottom = 30; dc.Draw3dRect(&rect, (COLORREF)0xff0000, (COLORREF)0x0000ff); }

使用CMetaFileDC

有興趣可以在以下語(yǔ)句中可以嘗試以下幾種情況:

else if(m_bCMetaFileDC){

... ...

}

情況1:(與上面的OnDraw函數(shù)中相同) //傳入pDC->m_hDC使用pDC繪制,圖形在視圖窗體左上角 pMetaFileDC = new CMetaFileDC(); pMetaFileDC->m_hDC = pDC->m_hDC; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); delete pMetaFileDC; pDC->PlayMetaFile(m_hMetaFile);

情況2:

//傳入pDC->m_hDC使用屏幕DC繪制,圖形在視圖窗體左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = ::GetDC(NULL); pMetaFileDC->m_hDC = pDC->m_hDC; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); delete pMetaFileDC; ::PlayMetaFile(hdc, m_hMetaFile); ::ReleaseDC(NULL, hdc);

情況3:

//傳入屏幕DC,使用屏幕DC繪制,圖像在屏幕左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = ::GetDC(NULL); pMetaFileDC->m_hDC = hdc; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); delete pMetaFileDC; ::PlayMetaFile(hdc, m_hMetaFile); ::ReleaseDC(NULL, hdc);

情況4:

//傳入屏幕DC,使用pDC繪制, 圖像在屏幕左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = ::GetDC(NULL); pMetaFileDC->m_hDC = hdc; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); delete pMetaFileDC; pDC->PlayMetaFile(m_hMetaFile); ::ReleaseDC(NULL, hdc);

情況5:

//傳入屏幕DC,使用pDC繪制,但是繪制前釋放屏幕DC, //沒(méi)有出錯(cuò),而且圖像繪制在屏幕左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = ::GetDC(NULL); pMetaFileDC->m_hDC = hdc; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); delete pMetaFileDC; ::ReleaseDC(NULL, hdc); pDC->PlayMetaFile(m_hMetaFile);

情況6:

//傳入屏幕pDC->hDC,使用CMetaFileDC繪制,圖像在視圖窗體左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = pDC->m_hDC; pMetaFileDC->m_hDC = hdc; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); pMetaFileDC->PlayMetaFile(m_hMetaFile); delete pMetaFileDC; ::ReleaseDC(NULL, hdc);

情況7:

//傳入屏幕DC,使用CMetaFileDC繪制,圖像在屏幕左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = ::GetDC(NULL); pMetaFileDC->m_hDC = hdc; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); pMetaFileDC->PlayMetaFile(m_hMetaFile); delete pMetaFileDC; ::ReleaseDC(NULL, hdc);

情況8:

//傳入屏幕DC,使用CMetaFileDC繪制,繪圖前釋放hdc //仍然沒(méi)有出錯(cuò),圖像在屏幕左上角 HDC hdc; pMetaFileDC = new CMetaFileDC(); hdc = ::GetDC(NULL); pMetaFileDC->m_hDC = hdc; pMetaFileDC->DrawText("Use class CMetaFileDC", &rect, DT_LEFT|DT_TOP); pMetaFileDC->Draw3dRect(200, 0, 300, 30, (COLORREF)0xffff00, (COLORREF)0x0000ff); m_hMetaFile = pMetaFileDC->Close(); ::ReleaseDC(NULL, hdc); pMetaFileDC->PlayMetaFile(m_hMetaFile); delete pMetaFileDC;

由上面代碼可見(jiàn)繪圖的位置與傳入CMetaFileDC::m_hDC的值有關(guān)。

使用CMetaFileDC需要注意:

使用CMetaFileDC對(duì)象調(diào)用一系列你想重復(fù)的CDC的GDI命令,只能使用CDC類(lèi)中GDI輸出命令。CDC的PlayMetaFile可以使用圖元文件句柄來(lái)執(zhí)行圖元文件中的命令,圖元文件也能使用CopyMetaFile使其存儲(chǔ)在磁盤(pán)上。當(dāng)不再需要圖元文件時(shí),調(diào)用 DeleteMetaFile從內(nèi)存中刪除它。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多