Delphi 图形设计(2)

来源:互联网 发布:批量网页录入数据 编辑:程序博客网 时间:2024/05/20 12:23

10.2 

       Windows是一个基于图形用户界面的操作系统。

    若要在窗口上作图,需要调用Windows提供的应用程序接口(Application Program InterfaceAPI),还要申请和维护句柄等资源。

    Delphi将这一切都封装在TCanvas类中,通过设置TCanvas类中的属性,调用其中的方法,就可以实现画图功能。

10.2.1 Canvas画布对象

       虽然在任何组件上都可以绘制图形,但由于很多组件上都有标题之类的文字,所以通常在窗体或面板之类的容器上绘制图形。

       例如,最常用的画图容器为FormPaintBox。这些容器的空白区域称为画布(Canvas),使用画布类TCanvas的方法可在画布上绘制直线、弧线、矩形或圆形等各种图形。

          CanvasTCanvas类的一个系统定义对象,称为画布对象,通常作为其他控件的一个属性出现,不单独使用。每个控件都有Canvas属性。例如,使用FormCanvas属性即可在窗体的工作区内绘图。由于Canvas是运行时属性,在程序运行时才能获得,所以必须写程序来完成设置。

 

Canvas的主要属性有PenBrushPixelsPenPos等,用于定义绘制图形的风格。

1Pen画笔

Pen画笔用于控制线条的颜色、模式、风格及宽度

Pen的类型为TPen类,属性有ColorModeStyleWidth

·  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属性值不能是PsDashPsDashDot     例如:

 Form1.Canvas.Pen.Color:=clRed;        //设置线条颜色为白色

 Form1.Canvas.Pen.Style:=psDashDot;    //设置线风格为点划线

  Form1.Canvas.Pen.Width:=1;               //设置线宽度为1,即细线

 

2Brush刷子

Brush刷子用于确定图形填充的颜色及填充方式。

Brush类型为TBrush类,属性有ColorStyle

·  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

垂直线填充

3Pixels像素

Pixels属性用于存储Canvas中每个像素点的颜色值。定义如下:

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

       Pixels是一个二维数组,下标表示某像素点在屏幕位置的坐标,元素类型是TColor。一个绘图过程实际上就是改变画布上有关像素点颜色的过程,从而在视觉效果上得到一幅特定的图。例如:

Form1.Canvas.Pixels[100,200]:=clYellow;     //将窗口内的一点涂上黄色

反之,读取Pixels数组的元素值则可取得相应坐标点的颜色值。

4PenPos画笔位置

PenPos属性表示当前画笔的位置,类型为TPoint。例如:

i:=Form1.Canvas.PenPos.x;                     //获得当前画笔位置

j:=Form1.Canvas.PenPos.y;

10.2.2 绘图方法

TCanvas类提供多种用于绘图和文字输出的方法。

1.绘图的坐标体系

    在组件上绘图的坐标体系与屏幕、窗口相同。

    水平方向是X轴,垂直方向是Y轴,左上角起始点坐标是(0,0),区域内任意一点的坐标用(xy)表示,右下角点的坐标值取决于屏幕分辨率,例如,屏幕分辨率为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方法用当前的PenBrush属性绘制一个矩形,声明如下:

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方法用当前PenBrush属性绘制并填充任意边数的多边形,声明如下:

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的标准控件都具有重画功能,像窗体、按钮、编辑框等,它们在窗口被激活时都能够自动地、完整地显示自身。

1FormOnPaint事件

    当窗口启动或被激活时,触发窗体的OnPaint事件。如果需要在窗口上绘图,则必须在FormOnPaint事件上写绘图程序。

当窗口启动时,Windows显示窗口及其中控件,执行窗体的OnPaint事件绘制用户设计的图形。

当窗口被激活时,Windows会向窗口发送一个WM_Paint消息。Delphi对该消息进行处理,先清除窗口上的图形,然后触发OnPaint事件,重新绘制图形。

2Repaint方法立即刷新

当程序需要主动刷新图形时,可以调用Repaint方法来刷新窗口

    Repaint方法自动产生一个WM_Paint消息,先清除窗口上的图形,再产生OnPaint事件,重新绘制同样的图形。

10.2.4 响应鼠标事件

在程序运行过程中,利用鼠标可以实现动态地作图,就像Windows的画图程序一样

利用鼠标作图,需要在程序中识别鼠标位置和鼠标动作,鼠标有3个动作:鼠标按下、鼠标移动和鼠标松开。在Delphi中,对应3个鼠标动作有3个不同的事件:

1)当鼠标按下时,发生OnMouseDown事件。

2)当鼠标松开时,发生OnMouseUp事件。

3)当鼠标移动时,发生OnMouseMove事件。

FormOnMouseDown事件声明为:

procedure TForm1.FormMouseDown(Sender: TObject;

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

其中的5个参数含义如下:

·   Sender探测鼠标动作的对象。

·   Button涉及的鼠标按钮:mbLeft左键,mbMiddle中键,mbRight右键。

·   Shift鼠标动作时,AltCtrlShift键的状态。

·   XY事件发生时鼠标的坐标。

OnMouseUpOnMouseMove事件声明和参数含义类似。

10.1拖动鼠标画直线并显示直线的动态变化情况。

本例通过绘制直线演示3个鼠标响应事件上语句的配合。程序运行时,随着鼠标的移动,用户可随时观测直线的变化。程序运行窗口如图10-1所示。

10-1 拖动鼠标画直线

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

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;

原创粉丝点击