C++ MFC圖形設備接口

圖形設備接口(Graphics Device Interface,GDI),把應用程序的函數調用傳遞給圖形設備驅動程序,由設備驅動程序來執行與硬件相關的函數。GDI嚮應用程序提供了一個設備無關的編程,同時以設備相關的格式和具體的硬件設備交互。

在MFC中使用GDI進行繪圖操作一般會涉及兩個對象,一是設備上下文對象,包括CDC及其派生類;二是GDI對象,包括CFont、CBrush、CPen等。

設備上下文

設備上下文(Device Context,DC),是一種Windows數據結構,包括與設備繪製屬性相關的信息。利用設備上下文可以實現向屏幕、打印機的輸出。

在應用程序中,通常在繪圖之前調用BeginPaint函數,然後在設備上下文中進行一系列繪圖操作,最後調用EndPaint函數結束繪製過程。

MFC中的設備上下文包括:CDC、CClientDC、CPaintDC、CWindowsDC等。他們之間的關係如圖4-1-1所示:

圖4-1-1 MFC中常見的設備上下文之間的關係

MFC把不同的上下文對象用不同的類進行了封裝,如下所示:
1) CDC:所有設備上下文類的基類。封裝了所有圖形輸出函數,包括矢量、光柵和文本輸出。

2) CClientDC:用於客戶區域的圖形輸出,需要直接在客戶區域進行繪製時使用。一般在響應非窗口重繪消息(如鍵盤輸入時繪製文本、鼠標繪圖)時使用,在其構造函數中自動調用GetDC,在其析構函數中自動調用ReleaseDC函數。CClientDC對象聯繫的DC是窗口的客戶區。

3) CPaintDC:用於響應窗口重繪消息消息(WM_PAINT)時的繪製輸出。CPaintDC繼承自CDC,在其構造函數中自動調用BeginPaint函數。在其析構函數中自動調用EndPaint函數。EndPaint除了釋放設備上下文外,還負責從消息隊列中清除WM_PAINT消息。因而在處理窗口重繪時,必須使用CPaintDC,否則WM_PAINT消息無法從消息隊列中清除,將引起不斷的窗口重繪。CPaintDC也只能用在WM_PAINT消息處理中。

4) CWindowsDC:用於窗口客戶區和非客戶區(包括窗口邊框、標題欄、控制按鈕等)的繪製。

獲取整個屏幕區域,包括客戶區和非客戶區。一句話概括:

CDC 任何dc 相當於CreateDC、DeleteDC
CClientDC 客戶區dc 相當於GetDC、ReleaseDC
CPaintDC 無效區dc 相當於BeginPaint、EndPaint
CWindowDC 整窗口dc 相當於GetWindowDC、 ReleaseDC


設備上下文相關函數整理如下:

  • GetSafeHdc: 返回輸出設備上下文m_hDC。
  • SaveDC:保存設備上下文當前狀態。
  • RestoreDC:  恢復SaveDC保存的設備上下文以前狀態。
  • ResetDC:更新m_hAttribDC設備上下文。
  • GetDeviceCaps: 獲取有關給定顯示設備功能的指定類型指定設備信息。
  • IsPrinting:確定正在使用的設備上下文是否用於打印。

GDI對象

繪圖不僅需要場景,也需要工具。可以把設備上下文理解爲GDI繪圖的場景,那麼GDI對象就是工具。MFC主要提供了以下幾種GDI對象:
CPen:用來繪製線條;
CBursh:用來填充繪製對象的內部;
CBitmap:用來操作位圖對象;
CFont:用來繪製文本;
CPalette:用於應用程序和彩色輸出設備(如顯示器)之間的接口。

GDI繪圖

使用GDI進行圖形繪製的一般流程如下所示:

  • 創建GDI對象;
  • 創建或取得設備上下文對象;
  • 使用SelectObject把GDI對象選入設備上下文;
  • 使用圖形輸出函數在指定上下文中繪製圖形。


GDI繪圖過程經常會遇到出現抖動的問題,主要原因是對屏幕設備DC操作太過頻繁,解決辦法是首先把所有繪圖操作都在內存DC中操作,然後這些內存DC統一繪製到一個總的內存DC中,然後再把這個總的內存DC一次性繪製到屏幕DC,這樣就不會出現抖動。這就是通常所說的“雙緩存技術”,將在第4.4節中以實例的形式介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章