設備上下文

設備上下文,是一種包含有關某個設備(如顯示器或印表機)的繪製屬性信息的 Windows 數據結構。所有繪製調用都通過設備上下文對象進行,這些對象封裝了用於繪製線條、形狀和文本的 Windows API。

設備上下文是一種包含有關某個設備(如顯示器或印表機)的繪製屬性信息的 Windows 數據結構。所有繪製調用都通過設備上下文對象進行,這些對象封裝了用於繪製線條、形狀和文本的 Windows API。設備上下文允許在 Windows 中進行與設備無關的繪製。設備上下文可用於繪製到螢幕、印表機或者圖元檔案
CPaintDC 對象將 Windows 的常見固定用語進行封裝,調用 BeginPaint 函式,然後在設備上下文中繪製,最後調用 EndPaint 函式。CPaintDC 構造函式為您調用 BeginPaint,析構函式則調用 EndPaint。該簡化過程將創建 CDC 對象、繪製和銷毀 CDC 對象。在框架中,甚至連這個過程的大部分也是自動的。具體說來,框架給 OnDraw 函式傳遞(通過 OnPrepareDC)準備好的 CPaintDC,您只需繪製到 CPaintDC 中。根據調用 OnDraw 函式的返回,CPaintDC 被框架銷毀並且將基礎設備上下文釋放給 Windows。
CClientDC 對象封裝對一個只表示視窗工作區的設備上下文的處理。CClientDC 構造函式調用 GetDC 函式,析構函式調用 ReleaseDC 函式。CWindowDC 對象封裝表示整個視窗(包括其框架)的設備上下文。
CMetaFileDC 對象將繪製封裝到 Windows 圖元檔案中。與傳遞給 OnDraw 的 CPaintDC 相反,在這種情況下您必須自己調用 OnPrepareDC。
設備上下文(Device Context)DC
DC實際上是GDI內部保存的數據結構。
DC與特定的顯示設備(如顯示器或印表機)相關。
對於顯示器,DC總是與顯示器上的特定視窗相關。
DC中的有些值是圖形「屬性」,這些屬性定義了GDI繪圖函式工作的細節。
例如,對於TextOut,DC的屬性確定了文字的顏色、文字的背景色、x座標和y座標映射到視窗的顯示區域的方式,以及顯示文字時Windows使用的字型。
MSDN的解釋: 一個DC是一個結構,它定義了一系列圖形對象的集合以及它們相關的屬性,以及影響輸出效果的一些圖形模式。這些圖形對象包括一個畫線的筆,一個填充和painting的畫刷,一個用來向螢幕拷貝的點陣圖,一個定義了一系列顏色集合的調色板,一個用來剪裁等操作的區域,一個做painting和drawing操作的路徑。
一個應用程式從不直接地訪問(access)dc,常見的取得dc的方式有以下幾種:
SDK's way:
1. BeginPaint
case WM_PAINT: HDC hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps);
MSDN的解釋: BeginPaint函式自動地設定dc的剪裁區域,這個剪裁區域,剪裁的是由InvalidateRect 或 InvalidateRgn 函式觸發的視窗無效區域,或者是系統給出的無效區域,當視窗被sizing, moving, creating, scrolling, or any other operation that affects the client area.
一個應用程式從不調用BeginPaint,除了在收到一個WM_PAINT訊息的時候;每一BeginPaint調用之後,需要調用EndPaint函式。
2.GetXXXDC
GetDC取得與視窗客戶區相關的dc,GetWindowDC取得與整個視窗(包括客戶區和非客戶區)相關的dc。
還有一類重要的dc,記憶體DC,是一個虛擬的記憶體設備上下文,我們對它進行繪圖等操作,不會顯示在螢幕或印表機上,而我們可以在它完成之後,拷貝到螢幕上或印表機上來輸出,這樣我們可以避免因為操作而給螢幕帶來的閃爍,對於印表機而言,列印只能是從上往下打,而我們在MEMDC中,可以隨意進行操作,這樣可以輸出直接在印表機上輸出所達不到的效果.
在視窗上貼圖一般總是要用到記憶體DC,將所有的繪製工作先繪製在記憶體DC上,然活一次性拷貝到螢幕DC上,就是這樣了。
這裡是使用mfc進行的說明,對hdc進行了封裝,但是道理是一樣的。
1.創建記憶體DC
CDC m_MenDC; //聲明記憶體DC
CDC m_MenDC2; //聲明記憶體DC
CBitmap m_Bitmap1; //聲明一個點陣圖
m_MenDC.CreateCompatibleDC(GetDC());//創建記憶體DC
m_MenDCMap.CreateCompatibleDC(GetDC());//創建記憶體DC
m_Bitmap1.CreateCompatibleBitmap(GetDC(),1024,768); //創建一個兼容點陣圖,這是一個空的點陣圖,我們可以把它想像成一個螢幕,可以在上面畫線,輸出文字等,自己製作一個簡單的點陣圖。
m_hbmpBK = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path+"Bk4.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//我們也可以從硬碟導入一張點陣圖。
2,為記憶體DC選入一張點陣圖,或兼容點陣圖。
m_MenDC.SelectObject(m_hbmpBK);
m_MenDC2.SelectObject(m_Bitmap1);
注意,想要在記憶體dc上作圖,必須先為它選入一張點陣圖,或兼容點陣圖。想想前面,不管BeginPaint還是getDC都有一個相關的區域。這裡的點陣圖就是相關區域。
3.接著我們就可以像在視窗上作圖一樣,使用gdi函式(drawline,textout...)在記憶體dc上作圖了。同時也可以從一個記憶體dc拷貝點陣圖到另一個記憶體dc。
m_MenDC2.BitBlt(0,0,1024,768,&m_MenDC,0,0,SRCCOPY);
4,繪製結果的顯示,將這些東西拷到螢幕DC(getdc取得的dc)上
// 所謂的雙緩衝就是把所有的繪製工作都做在一個記憶體DC上。
// 最後一次拷到螢幕DC上,只能有一次
dc.BitBlt(0,0,1024,768,&m_MenDC2,0,0,SRCCOPY);//這裡的dc是通過getdc取得的螢幕或者某個視窗的dc。
這裡所強調的“一次”;是不要連續將幾個記憶體DC的內容都拷到螢幕DC上,這樣沒有起到雙緩衝的效果。如果你搞了很多個記憶體DC,想把這些東西都顯示出來,那你應該先把這多個記憶體DC的內容同時拷到另外一個記憶體DC上,再把這個記憶體DC的內容拷到螢幕DC上。

相關詞條

相關搜尋

熱門詞條

聯絡我們