Delphi 图形设计(2)

页面导航:首页 > 软件编程 > Delphi > Delphi 图形设计(2)

Delphi 图形设计(2)

来源: 作者: 时间:2016-01-18 15:42 【

10.2 图 形 设 计 Windows是一个基于图形用户界面的操作系统。 若要在窗口上作图,需要调用Windows 提供的应用程序接口(Application Program Interface,API),还要申请和维护句柄等资源。 Del

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  拖动鼠标画直线

如果要在鼠标移动时随时观测直线的变化,则必须首先记住鼠标按下处的起始点位置。程序如下:

[] 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;


 

Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<