圖形裝置介面(GDI)
圖形裝置介面(GDI)是一個可執行程式,它接受Windows應用程式的繪圖請求(表現為GDI函數調用),並將它們傳給相應的裝置驅動程式,完成特定於硬體的輸出,象印表機輸出和螢幕輸出。
GDI負責Windows的所有圖形輸出,包括螢幕上輸出像素、在印表機上輸出硬拷貝以及繪製Windows使用者介面。
1、三種圖形輸出類型
應用程式可以使用GDI建立三種類型的圖形輸出:向量輸出、位元影像圖形輸出和文本輸出。
向量圖形輸出
向量圖形輸出指的是建立線條和填充圖形,包括點、直線、曲線、多邊形、扇形和矩形的繪製。
位元影像輸出
位元影像圖形的輸出是指位元影像圖形函數對以位元影像形式儲存的資料進行操作,它包括各種位元影像和表徵圖的輸出。
在螢幕上表現為對若干行和列的像素的操作,在印表機上則是若干行和列的點陣的輸出。
位元影像圖形輸出的優點是速度很快,它是直接從記憶體到顯存的拷貝操作。缺點是需要額外的記憶體空間。
文本輸出
與DOS字元方式下的輸出不同,Windows是按圖形方式輸出的。
這樣,在輸出文本時,必須以邏輯座標為單位計算文本的輸出位置,而不是象DOS下以文本行為單位輸出文本。這比DOS下的文本輸出要難一些。
按圖形方式輸出文本給文本輸出帶來很大的靈活性。使用者可以通過調用各種GDI函數,製造出各種文本輸出效果,包括加粗、斜體、設定顏色等。
Windows還提供了一種TrueType(寫真字型)。TrueType字型用一組直線和曲線命令及一些參數來描述字型的輪廓。Windows可以通過參數來調整直線的長度和曲線的形狀,從而實現對字型的自由縮放。
2、MFC中與GDI有關的類
為了支援GDI繪圖,MFC提供了兩種重要的類:
·裝置上下文類,用於設定繪圖屬性和繪製圖形;
·繪圖對象類,封裝了各種GDI繪圖對象,包括畫筆、刷子、字型、位元影像、調色盤和地區。
(1)裝置上下文類
裝置上下文類包括CDC和它的衍生類別CClientDC、CPaintDC、CWindowDC、CMetaFileDC。
·CDC是裝置上下文類的基類,除了一般的視窗顯示外,還用於基於案頭的全螢幕繪製和非螢幕顯示的印表機輸出。CDC類封裝了所有圖形輸出函數,包括向量、位元影像和文本輸出。
·CClientDC(客戶區裝置上下文)用於客戶區的輸出,它在建構函式中封裝了GetDC(),在解構函式中封裝了ReleaseDC()函數。一般在響應非視窗重畫訊息(如鍵盤輸入時繪製文本、滑鼠繪圖)繪圖時要用到它。
CClientDC dc(this);//this一般指向本視窗或當前即時檢視
dc.TextOut(10,10,str,str.GetLength());
·CPaintDC用於響應視窗重繪訊息(WM_PAINT)時的繪圖輸出。CPaintDC在建構函式中調用BeginPaint()取得裝置上下文,在解構函式中調用EndPaint()釋放裝置上下文。EndPaint()除了釋放裝置上下文外,還負責從訊息佇列中清除WM_PAINT訊息。因此,在處理視窗重畫時,必須使用CPaintDC,否則WM_PAINT訊息無法從訊息佇列中清除,將引起不斷的視窗重畫。CPaintDC也只能用在WM_PAINT訊息處理之中。
·CWindowDC用於視窗客戶區和非客戶區(包括視窗邊框、標題列、控制按鈕等)的繪製。除非要自己繪製視窗邊框和按鈕(如一些CD播放程式等),否則一般不用它。
·CMetaFileDC專門用於圖元檔案的繪製。圖元檔案記錄一組GDI命令,可以通過這一組GDI命令重建圖形輸出。使用CMetaFileDC時,所有的圖形輸出命令會自動記錄到一個與CMetaFileDC相關的圖元檔案中。
(2)繪圖物件類
繪圖物件類包括CGdiObject、畫筆、刷子、字型、位元影像、調色盤、地區等。
CGdiObject是繪圖物件類的基類,但該類不能直接為應用程式所使用。
要使用GDI對象,必須使用它的衍生類別:畫筆、刷子、字型、位元影像、地區等等。
使用繪圖物件要注意兩點:
a.同其他MFC對象一樣,GDI對象的建立也要分為兩步:第一步,是定義一個GDI繪圖對象類的執行個體;第二步調用該對象的建立方法真正建立對象。
b.建立對象:使用該對象,首先要調用CDC::SelectObject()將它選入到裝置上下文中,同時儲存原來的設定到一個GDI對象指標比如說pOldObject中。在使用完後,再用SelectObject(pOldObject)恢複原來的設定。
畫筆(CPen)
封裝GDI畫筆,可被選中裝置上下文中當前所用的筆。
畫筆用於繪製對象的邊框以及直線和曲線。預設畫筆畫一條與一個像素等寬的黑色實線。
要使用畫筆,首先要定義一個畫筆(CPen pen;)然後建立畫筆。
建立畫筆有兩種方法:
(1)使用CPen::CreatePen(int nPenStyle,int nWidth,DWORD crColor)進行初始化。
第一個參數是筆的風格。nPenStyle可選值有:PS_SOLID 實線、PS_DOT 虛線等。
第二個參數是線的寬度,按邏輯單位。若線寬設為0,則不管是什麼映射模式下,線寬始終為一個像素。
第三個參數是線的顏色,可以選16種VGA顏色中的一種。顏色的設定用一個RGB宏(COLORREF RGB(cRed,cGreen,cBlue))來指定。
(2)建立筆的另一個方法是使用庫存對象。
SelectStockObject可從以下庫存筆中選擇一個:BLACK_PEN 黑筆N、ULL_PEN 空筆(不畫線或邊框)、WHITE_PEN 白筆等。
刷子(CBrush)
封裝GDI刷子,可用作裝置上下文中當前刷子。
刷子用來填充一個封閉繪圖物件(如矩形、橢圓)的內部地區。預設的刷子將封閉圖形的內部填充成全白色。
可以用以下幾種方法建立刷子:
(1)CreateSolidBrush(DWORD crColor)建立一個實心刷子,用一種顏色填充一個內部地區。
(2)CreateHatchBrush(int nIndex,DWORD crColor);建立一個帶陰影的刷子,nIndex代表一種影線模式。
(3)用CreatePatternBrush(CBitmap* pBitmap)用一個位元影像作刷子,一般採用8X8的位元影像,因為刷子可以看作8X8的小位元影像。
(4)同樣可以使用SelectStockObject()從庫存刷子中選取一個:BLACK_BRUSH 黑色刷子、WHITE_BRUSH 白色刷子、GRAY_BRUSH 灰色刷子等
字型(CFont)
封裝了GDI字型對象,使用者可以建立一種GDI字型,並使用CFont的成員函數來訪問它。
位元影像(CBitmap)
封裝了GDI位元影像,它提供成員函數裝載和操作位元影像。
調色盤(CPalette)
封裝GDI調色盤,它儲存著系統可用的色多媒體訊息息,是應用程式和彩色輸出裝置內容相關的介面。
3、常見的繪圖任務
輸出文本
GetTextMetrics(); 返回當前使用字型的尺寸描述,用於進行字型大小計算。
SetTextColor(int nColor); 設定前景色彩。
SetBkColor(int nColor); 設定背景色。
TextOut:文字輸出。
TabbedTextOut:象TextOut一樣顯示本文,可以使用製表鍵Tab。
ExtTextOut:在指定的矩形中顯示本文。可以用該函數刪去超出矩形的本文,用本文背景填充矩形,調整字元間隔。
DrawText:在指定矩形種顯示本文,可以使用製表鍵Tab。在格式化矩形時調整本文靠左對齊、靠右對齊或置中;還可以在一個詞中斷開以適應矩形邊界。
畫點
SetPixel:在指定座標處按指定色彩畫一點。
畫線
MoveToEx將直線起點移動到指定座標處,LineTo從起點開始畫直線到終點處。使用的線型由當前所用畫筆指定。
畫弧
Arc(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
封閉圖形
矩形:Rectangle
圓角矩形:RoundRect
橢圓:Ellipse
餅形圖:Pie
封閉的多邊形:Polygon
其它繪圖函數
FillRect:用指定顏色填充矩形且不畫邊線。
FloodFill:用給定的顏色,利用當前所選的刷子填充顯示的底面被一個邊線所包圍的地區,如多邊形地區的填充。
ExtFloodFill:用給定的顏色,利用當前刷子填充表面被一個邊線包圍的地區,使用者可以有選擇地填充一個由指定顏色組成的地區。
InvertRect:在某一矩形地區內反顯現有顏色。