日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC中的DC,CDC和HDC

發(fā)布時間:2024/9/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC中的DC,CDC和HDC 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

設備描述表(DC是Windows中的一種數(shù)據(jù)結(jié)構(gòu),它包含GDI需要的所有關(guān)于顯示界面情況的描述字段,包括相連的物理設備和各種各樣的狀態(tài)信息。

??????? 圖形顯示功能是由顯卡來完成的,你想要利用顯卡的圖形顯示功能來完成你的圖形輸出,怎么辦,給你一塊硬件能用嗎?好,現(xiàn)在廠商給你提供一個驅(qū)動程序,給你一些調(diào)用的接口,你就可以訪問了吧。但這種訪問是在驅(qū)動層,很麻煩,更麻煩的是,每個廠商給自己顯卡提供的驅(qū)動程序還不一樣,那我們寫的圖形輸出程序豈不是換臺機器(不一樣的顯卡)就得修改,一個字:累,兩個字:麻煩。現(xiàn)在一個救世主出現(xiàn)了,Bill兄,他讓他的兄弟們在驅(qū)動之上實現(xiàn)一個抽象層,當然也可以認為是一個中間層的軟件代碼(我們管他叫設備上下文如何,也叫設備描述表DC),由這些代碼和驅(qū)動打交道(當然,這些驅(qū)動得支持Windows平臺)。然后,他將這種實現(xiàn)封裝到動態(tài)鏈接庫中提供給我們使用,我們能通過動態(tài)鏈接庫暴露的API函數(shù)(相關(guān)概念見VC下半部分),得到一個這種實現(xiàn)(可以說是一種資源)的句柄,設備上下文的句柄(HDC),利用的這個句柄,就好像有了訪問這中實現(xiàn)的鑰匙了,以后就可以.......,剩下的參照VC上半部分的內(nèi)容。

?????? 設備描述表DC是一個定義一組圖形對象及其屬性、影響輸出的數(shù)據(jù)結(jié)構(gòu)。windows提供設備描述表,用于應用程序和物理設備之間進行交互,從而提供了應用程序設計的平臺無關(guān)性。設備描述表又稱為設備上下文,或者設備環(huán)境。?
  設備描述表是一種數(shù)據(jù)結(jié)構(gòu),它包括了一個設備(如顯示器和打印機)的繪制屬性相關(guān)的信息。所有的繪制操作通過設備描述表進行。設備描述表與大多WIN32結(jié)構(gòu)不同,應用程序不能直接訪問設備描述表,只能由各種相關(guān)API函數(shù)通過設備描述表的句柄(HDC)間接訪問該結(jié)構(gòu)。?
  設備描述表總是與某種系統(tǒng)硬件設備相關(guān)。比如屏幕設備描述表與顯示設備相關(guān),打印機設備描述表與打印設備相關(guān)等等。?
  屏幕設備描述表,一般我們簡單地稱其為設備描述表。它與顯示設備具有一定的對應關(guān)系,在windows GDI界面下,它總是相關(guān)于某個窗口或這窗口上的某個顯示區(qū)域。通常意義上窗口的設備描述表,一般指的是窗口的客戶區(qū),不包括標題欄、菜單欄所占有的區(qū)域,而對于整個窗口來說,其設備描述表嚴格意義上來講應該稱為窗口設備描述表,它包含窗口的全部顯示區(qū)域。二者的操作方法完全一致,所不同的僅僅是可操作的范圍不同而已。?

windows?窗口一旦創(chuàng)建,它就自動地產(chǎn)生了與之相對應的設備描述表數(shù)據(jù)結(jié)構(gòu),用戶可運用該結(jié)構(gòu),實現(xiàn)對窗口顯示區(qū)域的GDI操作,如劃線、寫文本、繪制位圖、填充等,并且所有這些操作均要通過設備描述表句柄了進行。?

要說設備描述表就必須先說GDI(圖形設備接口)。我們要在程序窗口上顯示圖形或文本等,就可以使用這些GDI函數(shù)在程序上“畫畫”、“寫字”。設備描述表(DC)實際上是GDI內(nèi)部保存的數(shù)據(jù)結(jié)構(gòu)。設備描述表中的有些值是圖形化的“屬性”,這些屬性定義了一些GDI函數(shù)工作的情況,如:文本顏色、圖形填充的情況等。HDC是設備描述表句柄類型,句柄可以簡單的理解為指針,被定義為32位的無符號整數(shù)。??

?????????????以上內(nèi)容轉(zhuǎn)自:http://longzxr.blog.sohu.com/187934817.html

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

????????在c++?編程中常會見到HDC,CDC,CClientDC,CPaintDC,CWindowDC這樣的類。

????????HDC是DC的句柄,API中的一個類似指針的數(shù)據(jù)類型。

??????? CDC是MFC的DC的一個類。

??????? CDC等設備上下分類,都含有一個類的成員變量:m_nHdc;即HDC類型的句柄。

????? CDC及其派生類的繼承視圖:

??????CObject
????? public |------CDC
????? public |------|------CClientDC
??????public |------|------CPaintDC
????? public |------|------CWindowDC
????? public |------|------CMetaFileDC
????? (
注意:?除CMetaFileDC以外的三個派生類用于圖形繪制.)

??????? CDC類定義了一個設備描述表相關(guān)的類,其對象提供成員函數(shù)操作設備描述表進行工作,如顯示器,打印機,以及顯示器描述

表相關(guān)的窗口客戶區(qū)域。

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

其派生類:

???????? 1.CPaintDC:封裝BeginPaint和EndPaint兩個API的調(diào)用。
(1)用于響應窗口重繪消息(WM_PAINT)的繪圖輸出。
(2)CPaintDC在構(gòu)造函數(shù)中調(diào)用BeginPaint()取得設備上下文,在析構(gòu)函數(shù)中調(diào)用EndPaint()釋放設備上下文。 EndPaint()除了釋放設備上下文外,還負責從消息隊列中清除WM_PAINT消息。因此,在處理窗口重畫時,必須使用CPaintDC,否則 WM_PAINT消息無法從消息隊列中清除,將引起不斷的窗口重畫。
(3)CPaintDC也只能用在WM_PAINT消息處理之中。
???????? 2.CClientDC(客戶區(qū)設備上下文): 處理顯示器描述表的相關(guān)的窗體客戶區(qū)域。

?????構(gòu)造時自動調(diào)用GetDC函數(shù),析構(gòu)時自動調(diào)用ReleaseDC函數(shù).一般應用于客戶區(qū)窗口的繪制。

?????當需要處理一個鼠標的單擊,然后馬上畫出一個圓,你不能等到下一個WM_PAINT的消息到來才畫圖,而是馬上,這是就需要CclientDC了。它可以在OnPaint的外面創(chuàng)建一個客戶區(qū)域DC

????void?CMainWindow::OnLButtonDown?(UINT?nFlags,?CPoint?point)
????{
????????CRect?rect;
????????GetClientRect?(&rect);

????????CClientDC?dc?(this);
????????dc.MoveTo?(rect.left,?rect.top);
????????dc.LineTo?(rect.right,?rect.bottom);
????????dc.MoveTo?(rect.right,?rect.top);
????????dc.LineTo?(rect.left,?rect.bottom);
????}


???????? 3.CWindowDC: 處理顯示器描述表相關(guān)的整個窗體區(qū)域,包括了框架和控 件(子窗體)。
(1)可在非客戶區(qū)繪制圖形,而CClientDC,CPaintDC只能在客戶區(qū)繪制圖形。
(2)坐標原點是在屏幕的左上角,CClientDC,CPaintDC下坐標原點是在客戶區(qū)的左上角。
(3)關(guān)聯(lián)一特定窗口,允許開發(fā)者在目標窗口的任何一部分進行繪圖,包含邊界與標題,這種DC同WM_NCPAINT消息一起發(fā)送。

????? 4.CMetaFileDC:與元文件相關(guān)的設備描述表關(guān)聯(lián)。

?

下面說下一些細點的知識點
1、CClientDC,CWindowDC?
區(qū)別不大, 可以說 CWindowDC包含了CClientDC。 就拿記事本來說,CClientDC 就只是我們可以編輯文字的那個區(qū)域,是客戶區(qū),CWindowDC 除了上面說的區(qū)域, 還包括菜單欄和工具欄等。

2、CClientDC和CWindowDC與 CPaintDC 的區(qū)別大點,在DC的獲取方面 CClientDC和CWindowDC 使用的是并只能是GetDC 和 ReleaseDC。CPaintDC 使用的是并只能是 BeginPaint 和 EndPaint。

3、CPaintDC只能用在響應 WM_PAINT?事件CClientDC,CWindowDC 只能用在響應非WM_PAINT 事件

4、關(guān)于 WM_PAINT事件
???????? 系統(tǒng)會在多個不同的時機發(fā)送WM_PAINT消息:當?shù)谝淮蝿?chuàng)建一個窗口時,當改變窗口的大小時,當把窗口從另一個窗口背后移出時,當最大化或最小化窗口時,等等,這些動作都是由系統(tǒng)管理的,應用只是被動地接收該消息,在消息處理函數(shù)中進行繪制操作;大多數(shù)的時候應用也需要能夠主動引發(fā)窗口中的繪制操作,比如當窗口顯示的數(shù)據(jù)改變的時候,這一般是通過InvalidateRect和InvalidateRgn函數(shù)來完成的。InvalidateRect和 InvalidateRgn把指定的區(qū)域加到窗口的Update Region中,當應用的消息隊列沒有其他消息時,如果窗口的Update Region不為空時,系統(tǒng)就會自動產(chǎn)生WM_PAINT消息。

??????? 系統(tǒng)為什么不在調(diào)用Invalidate時發(fā)送WM_PAINT消息呢?又為什么非要等應用消息隊列為空時才發(fā)送WM_PAINT消息呢?這是因為系統(tǒng)把在窗口中的繪制操作當作一種低優(yōu)先級的操作,于是盡可能地推后做。不過這樣也有利于提高繪制的效率:兩個WM_PAINT消息之間通過 InvalidateRect和InvaliateRgn使之失效的區(qū)域就會被累加起來,然后在一個WM_PAINT消息中一次得到更新,不僅能避免多次重復地更新同一區(qū)域,也優(yōu)化了應用的更新操作。像這種通過InvalidateRect和InvalidateRgn來使窗口區(qū)域無效,依賴于系統(tǒng)在合適的時機發(fā)送WM_PAINT消息的機制實際上是一種異步工作方式,也就是說,在無效化窗口區(qū)域和發(fā)送WM_PAINT消息之間是有延遲的;有時候這種延遲并不是我們希望的,這時我們當然可以在無效化窗口區(qū)域后利用SendMessage 發(fā)送一條WM_PAINT消息來強制立即重畫,但不如使用Windows GDI為我們提供的更方便和強大的函數(shù):UpdateWindow和RedrawWindow。UpdateWindow會檢查窗口的Update Region,當其不為空時才發(fā)送WM_PAINT消息;RedrawWindow則給我們更多的控制:是否重畫非客戶區(qū)和背景,是否總是發(fā)送 WM_PAINT消息而不管Update Region是否為空等。
5、HDC和CDC相互轉(zhuǎn)換:

(1)、HDC到CDC的轉(zhuǎn)換:
方法一: 此方法在設備結(jié)束時不會銷毀原來的資源(即:hDC,hBitmap)
CDC *pDC = CDC::FromHandle(hDC);

方法二:此方法在設備結(jié)束時會銷毀原來的資源(即:hDC,hBitmap)
CDC dc;
dc.Attach(hDC);

(2)、CDC到HDC的轉(zhuǎn)換:

?? CDC??dc;

???HDC??hDC;

???hDC?=?dc.GetSafeHdc();

6、首先:CDC 不可以釋放。 FromHandle 是通過 HDC 來創(chuàng)建了一個CDC 對象,以方便操作,釋放 DC 的操作應該針對于HDC 而非此CDC , 如果釋放了它?? pDC->ReleaseDC,就會造成隱患。?
????? HDC?? hDC?? =?? GetDC(hWnd);??
????? CDC?? *pDC?? =?? CDC::FromHandle(hDC);???
????? 這兩者是指向的一個DC對象,只能釋放一次,而這個釋放應該針對 hDC 而非 pDC。

??????然后:GetDC和ReleaseDC的調(diào)用匹配,CreateDC和DeleteDC的調(diào)用匹配。GetDC是從窗口獲取現(xiàn)有的DC,而CreateDC是創(chuàng)建DC,所以ReleaseDC和DeleteDC的作用一個是釋放,一個是銷毀。

總結(jié)

以上是生活随笔為你收集整理的MFC中的DC,CDC和HDC的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。