• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Shuffy

            不斷的學習,不斷的思考,才能不斷的進步.Let's do better together!
            posts - 102, comments - 43, trackbacks - 0, articles - 19

            【轉(zhuǎn)自】http://blog.chinaunix.net/u/28371/showart.php?id=404687
            1.首先介紹一下什么是DC(設(shè)備描述表)

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

            2.CDC及其派生類

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

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

             

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

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

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

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

             

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

             

            3.使用方法

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

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

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

            視圖類構(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;

            }

            視圖類OnDraw函數(shù)

            void CUseDCView::OnDraw(CDC* pDC)

            {

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

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

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

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

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

            //注意: HDCDisplay和hDC的::Release()中第一個參數(shù)HWND
            //與GetDC()的第一個參數(shù)必須對應(yīng)。
            if(m_bHDCDisplay)
            {
            HDCDisplay = ::GetDC(NULL); //獲得整個顯示器區(qū)域的DC
            ::DrawText(HDCDisplay, "HDC of Display", 14, &rect, DT_LEFT|DT_TOP);
            ::ReleaseDC(NULL, HDCDisplay);
            HDCDisplay = NULL;
            }
            if(m_bHDC) //繪制在客戶區(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才能獲取當前客戶區(qū)域設(shè)備描述表
            pCDC = this->GetDC(); //當前窗體(視圖)的設(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); //獲取本窗體客戶區(qū)域的DC
            pClientDC->DrawText("Use class CClientDC", &rect, DT_LEFT|DT_TOP);
            delete pClientDC;
            pClientDC = NULL;
            }
            else if(m_bCPaintDC) { //測試當前傳入的CDC是不是CPaintDC
            pPaintDC = (CPaintDC*)pDC;
            pPaintDC->DrawText("Use class CPaintDC", &rect, DT_LEFT|DT_TOP);
            }
            else if(m_bCWindowDC){
            pWindowDC = new CWindowDC(this); //獲取本窗體框架和客戶區(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在視圖窗口中繪制圖象時要注意,應(yīng)該在OnPaint()編寫關(guān)于CPaintDC相關(guān)的代碼,而不是在OnDraw()中.但是請注意,如果使用OnPaint()函數(shù)響應(yīng)WM_PAINT事件,OnDraw函數(shù)將會被屏蔽;

            可以使用以下代碼測試:

            在CUseDCView.h,CUseDCView的類定義中語句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

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

            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,
            //沒有出錯,而且圖像繪制在屏幕左上角
            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
            //仍然沒有出錯,圖像在屏幕左上角
            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;

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

            使用CMetaFileDC需要注意:

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

            久久久久无码国产精品不卡| 国产精品久久久久久久久鸭| 久久99久久无码毛片一区二区| 国产成人精品白浆久久69| 国产V亚洲V天堂无码久久久 | 日韩精品无码久久一区二区三| 欧美粉嫩小泬久久久久久久| 99久久精品免费看国产一区二区三区| 久久久久AV综合网成人| 久久久久亚洲爆乳少妇无| 色婷婷综合久久久久中文| 伊人久久免费视频| 午夜精品久久久久久中宇| 国产精品熟女福利久久AV| 久久婷婷激情综合色综合俺也去| 成人亚洲欧美久久久久| 国内精品久久久久影院一蜜桃| 最新久久免费视频| 国产亚洲精午夜久久久久久| 久久精品中文闷骚内射| 亚洲国产一成久久精品国产成人综合| 久久99中文字幕久久| 亚洲欧美成人综合久久久| 亚洲&#228;v永久无码精品天堂久久| 丰满少妇高潮惨叫久久久| 国产亚洲精品久久久久秋霞| 欧美国产成人久久精品| 精品久久久久久久久久中文字幕 | 久久亚洲精品无码观看不卡| 久久国产精品久久国产精品| 久久久久成人精品无码中文字幕| 欧美日韩精品久久久免费观看| 久久久久亚洲AV无码专区网站 | 亚洲中文久久精品无码| 久久夜色精品国产www| 久久久久亚洲精品男人的天堂| 99久久亚洲综合精品网站| 国产成人综合久久综合| 99久久免费国产精精品| 国产精品久久久久天天影视| 久久99热精品|