Windows圖形設備接口(GDI)有許多對象,這些對象定義着一個設備描述環境的功能。使用最普遍的GDI對象是筆、刷子和字體。其他GDI對象包括調色板、位圖和區域。首先了解一下筆、刷子和字體,然后轉向更為復雜的對象。
筆Pens, 刷子Brushes, and 字體Fonts
筆、刷子和字體都是簡明易懂的,先一一介紹一下這些對象以及TCanvas類如何使用它們的。
筆Pens
筆定義為用於畫線的對象。線可以是從一點到下一點的簡單直線,也可以是圍繞矩形、橢圓和菱形所畫的邊界。筆可以通過TCanvas類的Pen屬性存取並且它是TPen類的一個實例。
TPen類繼承關系如下:
下面表格中勒出了TPen的屬性。
表1. TPen屬性
屬性 描述 Color 設置線條顏色。 Handle 句柄,用於訪問GDI時。 Mode 指定畫布的ROP(raster operation光柵操作)模式(正向、反向等)。 Style 筆類型,不可視線、虛線、點划線、雙點划線、點線、內框和實線等。 Width 畫筆的筆寬(像素為單位)
這些屬性大部分可滿足用戶的使用。下面的例子為畫紅色虛線。
Canvas.Pen.Color := clRed; { 畫筆為紅色} Canvas.Pen.Style := psDash; { 畫筆樣式為虛線} Canvas.MoveTo(20, 20); Canvas.LineTo(120, 20);
要檢驗該段代碼,可在窗體上放置一個按鈕並將程序錄入到按鈕的OnClick事件中,運行程序點擊按鈕,直線就被畫在窗體上,如下圖:
Note
之后講解的所有簡單例子均可以用以上這種方式去檢驗。但是如果用其他應用程序覆蓋住該應用程序,然后再返回到該應用程序,這些圖畫都將要消失,這時因為這些圖畫是暫時的。如果需要圖畫長久保存,則要將圖畫代碼置於窗體的OnPaint事件中。一旦Windows窗口需要重畫,其OnPaint事件就產生了,圖畫代碼將被執行。
點划線(dotted and dashed)只適用於寬度為1的畫筆。psClear畫筆樣式用於清除Windows GDI在對象外邊所繪制的線條(如矩形、橢圓形以及填充的菱形)。
Tip
可通過放置在窗體上Shape組件,試驗TPen的各種屬性並修改圖形的Pen屬性,這些對於弄清TPen類的Mode屬性的作用尤為有用。
下面我們編寫了一個簡單的測試按鈕(具體請參看示例代碼),可以模擬顯示各種畫筆樣式的效果,如下圖:
刷子Brushes
畫布的刷子用於填充畫布上的區域和圖形。與TPen不同的是,畫筆用來在畫布上畫線,而刷子用不同的顏色、樣式和形狀來填充畫布的區域。
TCanvas類中有個Brush屬性,它可用來控制刷子的各種特性。Brush屬性是TBrush類的一個實例,具體繼承關系如下:
表2. TBrush屬性
屬性 描述 Bitmap 指定一個位圖,用於刷子的背景,位圖不能大於 8 x 8像素。 Color 刷子的顏色 Handle 句柄,用於直接訪問GDI。 Style 刷子的樣式,包括8種樣式。
默認時,Style屬性被設置為bsSolid,顏色為clWhite,沒有位圖。如果要填充圖案,應該設置Style屬性為bsHorizontal,bsVertical,bsFDiagonal,bsBDiagonal,bsCross或者bsDiagCross中的某一種。各種Style樣式效果如下圖:(具體詳見代碼示例中)
下面的例子就是利用45度圖案在窗體上畫圓,代碼如下:
Canvas.Brush.Color := clBlue; Canvas.Brush.Style := bsDiagCross; Canvas.Ellipse(20, 20, 220, 220);下圖就是上面代碼運行后顯示的效果:
使用圖案刷子時,刷子的Color屬性定義為構成圖案的線條顏色,由於某種原因,當使用圖案填充時,VCL自動使背景模式為透明的,這意味着刷子的背景色與圖形所在的Windows背景顏色相同。(如上圖中,圓的背景色與窗體相同,灰色),如果指定某種顏色,則需要避開VCL而利用API,如果需要在白色背景上使用藍色圖案,代碼如下:
Canvas.Brush.Color := clBlue; Canvas.Brush.Style := bsDiagCross; SetBkMode(Canvas.Handle, OPAQUE); SetBkColor(Canvas.Handle, clWhite); Canvas.Ellipse(20, 20, 220, 220);
現在刷子的背景色為白色了,如下圖顯示的圓。
刷子另一個有趣的特性就是位圖背景的選擇,先看看程序代碼,再討論位圖刷子,代碼如下:
Canvas.Brush.Bitmap := TBitmap.Create; Canvas.Brush.Bitmap.LoadFromFile('bkgnd.bmp'); Canvas.Ellipse(20, 20, 220, 220); Canvas.Brush.Bitmap.Free;
該代碼中第一行創建TBitmap對象並將它賦給刷子的Bitmap屬性,缺省時Bitmap屬性不被賦值。因此,必須明確創建一個TBitmap對象並將它賦給Bitmap屬性。
第二行是從文件中裝載位圖,位圖不能大於8 x 8像素,可以使用較大的位圖,但會被裁減到8 x 8。(在Win7測試可以使用大於 8 x 8像素的位圖)。
第三行畫橢圓。橢圓繪制完畢后,刪除刷子屬性,此時VCL不會刪除刷子屬性,因此必須手動刪除,否則會使內存溢出。
下圖顯示了位圖刷子所繪制的圓。
有時需要空心的刷子(hollow brush),空心刷子使北京顏色能夠顯露出來,要創建空心刷子,只需設置Style屬性為bsClear即可,仍以上面的例子為例,利用空心刷子在第一個圓內增加另一個圓,代碼如下:
Canvas.Brush.Bitmap := TBitmap.Create; Canvas.Brush.Bitmap.LoadFromFile('bkgnd.bmp'); Canvas.Ellipse(20, 20, 220, 220); Canvas.Brush.Style := bsClear; Canvas.Pen.Width := 5; Canvas.Ellipse(70, 70, 170, 170); Canvas.Brush.Bitmap.Free;
顯示效果如下圖:
若直接進入API可用刷子做其他事情,當然,大多數情況下,VCL TBrush類都可以處理這種工作的。
字體(Fonts)
字體對於大家來說不是什么新鮮東西。整個學習過程中都在一直用它,利用TCanvas類使用的字體同窗體或其他組件使用的字體屬性沒有什么區別。要改變畫布的字體,只需要輸入以下代碼即可。
Canvas.Font.Name := 'Courier New'; Canvas.Font.Size := 20; Canvas.Font.Style := Canvas.Font.Style + [fsBold]; Canvas.TextOut(20, 20, 'Testing');
顯示效果如下:
在之后的講解中還會詳細提到如何處理字體。
以上代碼均在Delphi7中測試通過,本講示例代碼下載:GDI對象之畫筆.rar