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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HDC,CDC,CClientDC,CPaintDC,CWindowDC的区别

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

CDCMFCDC的一個類
HDC
DC的句柄,API中的一個類似指針的數(shù)據(jù)類型.
MFC
類的前綴都是C開頭的

H
開頭的大多數(shù)是句柄

首先說一下什么是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ù)使用時釋放掉。

c++ 編程中常會見到HDC,CDC,CClientDC,CPaintDC,CWindowDC這樣的類
HDC
DC的句柄,API中的一個類似指針的數(shù)據(jù)類型.
CDC
MFCDC的一個類
CDC
等設(shè)備上下分類,都含有一個類的成員變量:m_nHdc;HDC類型的句柄.


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


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è)置字體,打印機換碼,滾動,處理元文件。

?

其派生類:
1.PaintDC:
封裝BeginPaintEndPaint兩個API的調(diào)用
(1)
用于響應(yīng)窗口重繪消息(WM_PAINT)是的繪圖輸出。
(2)CPaintDC
在構(gòu)造函數(shù)中調(diào)用BeginPaint()取得設(shè)備上下文,在析構(gòu)函數(shù)中調(diào)用EndPaint()釋放設(shè)備上下文。EndPaint()除了釋放設(shè)備上下文外,還負責從消息隊列中清除WM_PAINT消息。因此,在處理窗口重畫時,必須使用CPaintDC,否則WM_PAINT消息無法從消息隊列中清除,將引起不斷的窗口重畫。
(3)CPaintDC也只能用在WM_PAINT消息處理之中。


2.CClientDC(客戶區(qū)設(shè)備上下文): 處理顯示器描述表的相關(guān)的窗體客戶區(qū)域。
用于客戶區(qū)的輸出,與特定窗口關(guān)聯(lián),可以讓開發(fā)者訪問目標窗口中客戶區(qū),其構(gòu)造函數(shù)中包含了GetDC,析構(gòu)函數(shù)中包含了ReleaseDC


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


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

?

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

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

?

下面用一些簡單的代碼看看如果使用這些類
HDC
使用, 每次畫線等操作都不MFC封裝的類多了個HDC的參數(shù)
執(zhí)行在哪個設(shè)備描述表操作
HDC hdc=::GetDC(m_hWnd);//m_hWnd == this->m_hWnd
即當前窗口句柄
MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);
LineTo(hdc,point.x,point.y);
::ReleaseDC(m_hWnd,hdc);//
必須和GetDC配對
可以看到HDC的使用較麻煩, 而且如果::GetDC::ReleaseDC不配對的話,會造成錯誤


CDC *pDC=GetDC();
pDC->MoveTo(m_ptOrigin);
pDC->LineTo(point);
ReleaseDC(pDC);

CClientDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

CWindowDC dc(this);
CWindowDC dc2(GetDesktopWindow());//
獲得整個桌面的句柄, 一些桌面特效程序使用
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

CPaintDC dc(this);
dc.MoveTo(m_ptOrigin);
dc.LineTo(point);

可以看到 MFC 的類使用方便很多, 因為它們都在構(gòu)造函數(shù)和析構(gòu)函數(shù)調(diào)用了響應(yīng)的函數(shù)進行DC的獲取和釋放.


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

CClientDCCWindowDC CPaintDC 的區(qū)別大點
DC的獲取方面 CClientDCCWindowDC 使用的是并只能是 GetDC ReleaseDC
CPaintDC 使用的是并只能是 BeginPaint EndPaint

CPaintDC 只能用在響應(yīng) WM_PAINT 事件
CClientDC,CWindowDC
只能用在響應(yīng) WM_PAINT 事件


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


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

?

?

相互轉(zhuǎn)換:


方法一: 此方法在設(shè)備結(jié)束時不會銷毀原來的資源(:hDC,hBitmap)
CDC *pDC = CDC::FromHandle(hDC);


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

?

?

?

總結(jié)

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

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