程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi 圖形設計(2)

Delphi 圖形設計(2)

編輯:Delphi

10.2  圖 形 設 計
       Windows是一個基於圖形用戶界面的操作系統。

    若要在窗口上作圖,需要調用Windows 提供的應用程序接口(Application Program Interface,API),還要申請和維護句柄等資源。

    Delphi將這一切都封裝在TCanvas類中,通過設置TCanvas類中的屬性,調用其中的方法,就可以實現畫圖功能。

10.2.1  Canvas畫布對象
       雖然在任何組件上都可以繪制圖形,但由於很多組件上都有標題之類的文字,所以通常在窗體或面板之類的容器上繪制圖形。

       例如,最常用的畫圖容器為Form和PaintBox。這些容器的空白區域稱為畫布(Canvas),使用畫布類TCanvas的方法可在畫布上繪制直線、弧線、矩形或圓形等各種圖形。

          Canvas是TCanvas類的一個系統定義對象,稱為畫布對象,通常作為其他控件的一個屬性出現,不單獨使用。每個控件都有Canvas屬性。例如,使用Form的Canvas屬性即可在窗體的工作區內繪圖。由於Canvas是運行時屬性,在程序運行時才能獲得,所以必須寫程序來完成設置。

 

Canvas的主要屬性有Pen、Brush、Pixels、PenPos等,用於定義繪制圖形的風格。

1.Pen畫筆
Pen畫筆用於控制線條的顏色、模式、風格及寬度。

Pen的類型為TPen類,屬性有Color、Mode、Style及Width。

·   Color屬性:控制線條的顏色。

·   Mode屬性:控制線條的模式,取值見表10-2。

表10-2 Canvas.Pen.Mode屬性取值


 含   義
 
pmBlack
 總為黑色
 
pmWhite
 總為白色
 
pmNop
 不改變
 
pmNot
 畫布背景的相反色
 
pmCopy
 用Color屬性指定的畫筆顏色
 
pmNotCopy
 畫筆顏色的相反色
 
pmMerge
 畫筆顏色與畫布背景色的合成顏色
 
pmXor
 畫筆顏色與畫布背景色的異或合成顏色
 
pmNotXor
 pmXor的相反色
 

·   Style屬性:控制線條的風格,包括實線、虛線和點劃線等,取值見表10-3。

表10-3 Canvas.Pen.Style屬性取值


 含   義
 值
 含   義
 
psSolid
 實線
 psDashDotDot
 兩點一劃線
 
psDash
 短劃線
 psClear
 不劃線,通常用於清除輪廓線
 
psDot
 點線
 psInsideFrame
 實線,Width屬性大於1時
 
psDashDot
 點劃線
 
 
 

·   Width屬性:控制線條的寬度。

Width屬性的值為整型,如果所給的值小於1,則按1處理。注意,Width屬性值會影響Style屬性值,當Width屬性值不是1時,Style屬性值不能是PsDash或PsDashDot。      例如:

  Form1.Canvas.Pen.Color:=clRed;        //設置線條顏色為白色

  Form1.Canvas.Pen.Style:=psDashDot;     //設置線風格為點劃線

  Form1.Canvas.Pen.Width:=1;                //設置線寬度為1,即細線

 

2.Brush刷子
Brush刷子用於確定圖形填充的顏色及填充方式。

Brush類型為TBrush類,屬性有Color、Style。

·   Color屬性:確定圖形的填充顏色。

·   Style屬性:確定圖形的填充方式,取值見表10-4。

例如:

Form1.Canvas.Brush.Color:=clRed;         //設置填充色為紅色

Form1.Canvas.Brush.Style:=bsSolid;      //設置填充方式為實填充

一般情況下,Brush為矩形、圓或多邊形提供內部的填充色和填充圖案,還為文本提供背景色,但它不影響線條的顏色和文本的前景色。

表10-4 Canvas.Brush.Style屬性取值

取   值
 含    義
 取   值
 含    義
 
bsSolid
 實填充
 bsCross
 十字交叉線填充
 
bsClear
 不填充
 bsDiagCross
 交叉線填充
 
bsBDiagonal
 右斜線填充
 bsHorizontal
 水平線填充
 
bsFDiagonal
 左斜線填充
 bsVertical
 垂直線填充
 

3.Pixels像素
Pixels屬性用於存儲Canvas中每個像素點的顏色值。定義如下:

property Pixels(x,y;integer):TColor;

       Pixels是一個二維數組,下標表示某像素點在屏幕位置的坐標,元素類型是TColor。一個繪圖過程實際上就是改變畫布上有關像素點顏色的過程,從而在視覺效果上得到一幅特定的圖。例如:

Form1.Canvas.Pixels[100,200]:=clYellow;      //將窗口內的一點塗上黃色

反之,讀取Pixels數組的元素值則可取得相應坐標點的顏色值。

4.PenPos畫筆位置
PenPos屬性表示當前畫筆的位置,類型為TPoint。例如:

i:=Form1.Canvas.PenPos.x;                      //獲得當前畫筆位置

j:=Form1.Canvas.PenPos.y;

10.2.2  繪圖方法
TCanvas類提供多種用於繪圖和文字輸出的方法。

1.繪圖的坐標體系
    在組件上繪圖的坐標體系與屏幕、窗口相同。

    水平方向是X軸,垂直方向是Y軸,左上角起始點坐標是(0,0),區域內任意一點的坐標用(x,y) 表示,右下角點的坐標值取決於屏幕分辨率,例如,屏幕分辨率為800×600,則右下角點的坐標為(799,599)。

2.繪制直線
      MoveTo(x,y)將畫筆當前位置設置到點(x,y) 處。畫筆當前位置在PenPos屬性中,改變畫筆當前位置使用MoveTo方法,而不要設法改變PenPos的值。

     LineTo(x,y)從當前位置至(x,y) 點畫一條線,並把畫筆當前位置移至(x,y) 處。所繪直線具有已定義Pen畫筆的各項屬性。例如:

Canvas.MoveTo(x1,y1);    //定位(x1,y1)

Canvas.LineTo(x2,y2);    //在(x1,y1)和(x2,y2)之間畫線

3.繪制矩形
     Rectangle方法用當前的Pen和Brush屬性繪制一個矩形,聲明如下:

procedure Rectangle(x1,y1,x2,y2:integer);

其中,(x1,y1) 和(x2,y2) 分別表示矩形左上角和右下角兩點坐標。若|x2 - x1|=|y2 - y1|,則該矩形成為正方形。

4.繪制橢圓
      Ellipse方法在指定的矩形內畫一個橢圓,聲明如下:

procedure Ellipse(x1,y1,x2,y2:integer);

其中,(x1,y1) 和(x2,y2) 分別表示矩形左上角和右下角兩點坐標。如果指定矩形為正方形時,橢圓就成為圓。

5.填充多邊形
       Polygon方法用當前Pen和Brush屬性繪制並填充任意邊數的多邊形,聲明如下:

procedure Polygon(Points:array of TPoint);

多邊形的多個坐標點存儲在數組Points中,Points數組的實際長度決定多邊形的邊數。一個可填充的多邊形應是封閉的,即首尾兩點坐標一致。

 

Points數組元素為TPoint,表示一個點的坐標。TPoint聲明如下:

type

    TPoint = packed record

      X: Longint;

      Y: Longint;

    end;

Types單元的Point函數將兩個整型值生成一個TPoint對象。Point函數聲明如下:

function Point(AX,AY:Integer):TPoint;

例如,下列程序段在矩形(x1 , y1 , x2 , y2)范圍內畫出一個等腰三角形。

var p:array [0..3] of TPoint;

p[0]:=point(x1 +(x2-x1) div 2,y1);

p[1]:=point(x1,y2);

p[2]:=point(x2,y2);

p[3]:=p[0];

Canvas.Polygon(p);

6.顯示字符串
Textout方法用當前Font屬性在指定位置(x,y)顯示指定字符串Text,聲明如下:

procedure TextOut(x,y;integer;const Text:string);

10.2.3  窗口繪圖事件
    在Windows中運行應用程序,窗口的基本操作由Windows控制執行。

    當窗口啟動時,Windows需要繪制窗口上全部的圖形圖像;當一個窗口被其他窗口覆蓋後再被激活時,Windows需要重新繪制該窗口上曾被覆蓋部分的圖形圖像。例如,窗口從最大化、最小化狀態還原時,或被其他窗口覆蓋、當其他窗口關閉或移開時,窗口被激活,Windows都將重畫標准控件的圖形圖像。

      Delphi的標准控件都具有重畫功能,像窗體、按鈕、編輯框等,它們在窗口被激活時都能夠自動地、完整地顯示自身。

1.Form的OnPaint事件
    當窗口啟動或被激活時,觸發窗體的OnPaint事件。如果需要在窗口上繪圖,則必須在Form的OnPaint事件上寫繪圖程序。

當窗口啟動時,Windows顯示窗口及其中控件,執行窗體的OnPaint事件繪制用戶設計的圖形。

當窗口被激活時,Windows會向窗口發送一個WM_Paint消息。Delphi對該消息進行處理,先清除窗口上的圖形,然後觸發OnPaint事件,重新繪制圖形。

2.Repaint方法立即刷新
當程序需要主動刷新圖形時,可以調用Repaint方法來刷新窗口。

    Repaint方法自動產生一個WM_Paint消息,先清除窗口上的圖形,再產生OnPaint事件,重新繪制同樣的圖形。

10.2.4  響應鼠標事件
在程序運行過程中,利用鼠標可以實現動態地作圖,就像Windows的畫圖程序一樣。

利用鼠標作圖,需要在程序中識別鼠標位置和鼠標動作,鼠標有3個動作:鼠標按下、鼠標移動和鼠標松開。在Delphi中,對應3個鼠標動作有3個不同的事件:

(1)當鼠標按下時,發生OnMouseDown事件。

(2)當鼠標松開時,發生OnMouseUp事件。

(3)當鼠標移動時,發生OnMouseMove事件。

Form的OnMouseDown事件聲明為:

procedure TForm1.FormMouseDown(Sender: TObject;

            Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

其中的5個參數含義如下:

·    Sender:探測鼠標動作的對象。

·    Button:涉及的鼠標按鈕:mbLeft左鍵,mbMiddle中鍵,mbRight右鍵。

·    Shift:鼠標動作時,Alt、Ctrl、Shift鍵的狀態。

·    X、Y:事件發生時鼠標的坐標。

OnMouseUp和OnMouseMove事件聲明和參數含義類似。

【例10.1】拖動鼠標畫直線並顯示直線的動態變化情況。

本例通過繪制直線演示3個鼠標響應事件上語句的配合。程序運行時,隨著鼠標的移動,用戶可隨時觀測直線的變化。程序運行窗口如圖10-1所示。

 

\

圖10-1  拖動鼠標畫直線

如果要在鼠標移動時隨時觀測直線的變化,則必須首先記住鼠標按下處的起始點位置。程序如下:

[delphi] view plaincopyprint?var Origin,MovePt:TPoint;                                  //直線的起始點與移動點  
 
    mouse_down:Boolean;                                     //鼠標是否按下的狀態  
 
procedure TForm1.FormMouseDown(Sender:TObject;        //鼠標按下事件  
 
    Button:TMouseButton;Shift:TShiftState;X,Y:Integer); 
 
begin 
 
    mouse_down:=true;                                       //鼠標已按下  
 
    Canvas.MoveTo(X,Y); 
 
    Origin:=Point(X,Y);                                    //記載直線的起始點位置  
 
    MovePt:=Origin;                                         //記載直線的移動點位置  
 
end; 
 
procedure TForm1.FormMouseMove(Sender:TObject;        //鼠標移動事件  
 
    Shift:TShiftState;X,Y:Integer); 
 
begin 
 
    if mouse_down                                           //鼠標按下時畫直線  
 
    then begin 
 
        Canvas.Pen.Mode:=pmNotXor;                       //畫筆線條為異或模式  
 
        Canvas.MoveTo(origin.X,origin.Y);               //擦除前一點的直線  
 
        Canvas.LineTo(MovePt.X,MovePt.Y); 
 
        MovePt := Point(X, Y); 
 
        Canvas.MoveTo(origin.X,origin.Y);              //重畫當前點的直線  
 
        Canvas.LineTo(MovePt.X,MovePt.Y); 
 
    end; 
 
end; 
 
  
 
procedure TForm1.FormMouseUp(Sender:TObject;           //鼠標松開事件  
 
                  Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
 
begin 
 
    Canvas.LineTo(X,Y);                                    //畫直線  
 
    mouse_down:= false;                                    //鼠標已松開  
 
end; 

var Origin,MovePt:TPoint;                                  //直線的起始點與移動點

    mouse_down:Boolean;                                     //鼠標是否按下的狀態

procedure TForm1.FormMouseDown(Sender:TObject;        //鼠標按下事件

    Button:TMouseButton;Shift:TShiftState;X,Y:Integer);

begin

    mouse_down:=true;                                       //鼠標已按下

    Canvas.MoveTo(X,Y);

    Origin:=Point(X,Y);                                    //記載直線的起始點位置

    MovePt:=Origin;                                         //記載直線的移動點位置

end;

procedure TForm1.FormMouseMove(Sender:TObject;        //鼠標移動事件

    Shift:TShiftState;X,Y:Integer);

begin

    if mouse_down                                           //鼠標按下時畫直線

    then begin

        Canvas.Pen.Mode:=pmNotXor;                       //畫筆線條為異或模式

        Canvas.MoveTo(origin.X,origin.Y);               //擦除前一點的直線

        Canvas.LineTo(MovePt.X,MovePt.Y);

        MovePt := Point(X, Y);

        Canvas.MoveTo(origin.X,origin.Y);              //重畫當前點的直線

        Canvas.LineTo(MovePt.X,MovePt.Y);

    end;

end;

 

procedure TForm1.FormMouseUp(Sender:TObject;           //鼠標松開事件

                  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

    Canvas.LineTo(X,Y);                                    //畫直線

    mouse_down:= false;                                    //鼠標已松開

end;


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved