• 用DELPHI中Canvas特性开发图形软件TCanvas方法说明


    http://www.yesky.com/20000713/93524.shtml

    2000-07-13· ·-··-

    p>  以往开发Windows图形软件大多用 VC ++ 作为开发工具, VC++强大的图形功能可以让程序员编制出许多优秀的与图形相关的软件。

      VC++ 中与绘图相关的函数都封装在CDC及其衍生的CClientDC,CpaintDC,CwindowDC中。 

      Delphi中也有一个与CDC相类似的类Tcanvas,它封装了Delphi 中的绘图函数。我们可以把Delphi和VC中相同或相近的方法做个有趣的比较。

      (一)Canvas和 CDC绘图方法比较:

      我们可以从以下表格中看到Tcanvas和 CDC相似的函数:

    表 1--1

    Canvas方法CDC方法功能
    ArcArc画一个椭圆弧
    ChordChord画一根玄。
    CopyRect拷贝指定矩形区域中图象到指定矩形
    DrawBitBlt拷贝位图
    EllipseEllipse画椭圆
    FillRectPaintRgn使用刷子填充一个又一个矩型
    FloodFillFloodFill用当前刷子填充区域
    FrameRectFrameRect画一个矩形框
    LinetoLineto画线到
    MovetoMoveto移到
    PiePie画扇形
    PolygonPolygon画多边形
    PolyLinePolyLine画多根相连的线
    RectangleRectangle画一个实心矩形
    RoundRectRoundRect画一个圆角的矩形
    StretchDrawStretchBlt从源图象中
    移动图象到指定矩形
    TextWidthGetCharWidth返回字符宽
    TextOutTextOut在指定坐标写字
    TextRectExtTextOut在制定矩形中写字

    上表中,我们只列出部分绘图函数,详细了解,请参阅有关Delphi和VC书籍.

      与VC++ 相类似, Delphi也提供了绘图工具,如Tpen,Tbrush等,与VC不同的是, Delphi的绘图工具封装在Tcanvas中。Delphi也提供字形及字体大小的类Tfont,下面我们用具体例子来分析它们的用法。

      (二)用Delphi 制作Window95/NT图形软件。

       象使用VC 一样,我们先用Delphi的Wizard建立一个 SDI 应用程序。Delphi 自动建立SDI 框架, 先运行一次。程序现在还不能干任何事。下一步开始添加代码。

       编辑主菜单。 增加Write,Draw俩个下拉菜单项。 在"Write"下增加"HelloWorld!!","Iamateacher","Font.."菜单项.在 aw"下增加"Arc","Line","Polygon","RoundRect","Rectangle","color.","LineStyle","WidthLine". 在"LineStyle"菜单下增加"Solid","Dash","Dot","DashDot","DashDotDot" 子菜单。

      相应的在SdiForm中增加ColorDialog,FontDialog,控件。

      在OnPaint事件中增加如下代码:

    procedureTSDIAppForm.FormPaint(Sender:TObject);
    begin
    canvas.FillRect(rect);{清空桌面画布}
    withSDIappformdo
    posx:=clientwidthdiv2;
    posy:=clientheightdiv2;{确定客户区中心点}
    casedetectIof
    1:
    begin
    setpenstate;
    canvas.Ellipse(posx-50,posy-50,posx+50,posy+50);
    //pen=oldwidth;
    end;{在客户区中心点画圆}
    2:
    begin
    setpenstate;
    canvas.MoveTo(posx-60,posy-60);
    canvas.LineTo(posx+60,posy+60);
    //pen=oldwidth;
    end;{在客户区画直线}

    3:
    begin
    fposx:=trunc(50*cos(pi/6));
    fposy:=trunc(50*sin(pi/6));
    setpenstate;
    Canvas.Polygon([Point(posx-fposy,posy-fposx),
    Point(posx+fposy,posy-fposx),
    Point(posx+50,posy),Point(posx+fposy,posy+fposx),
    point(posx-fposy,posy+fposx),point(posx-50,posy)]);
    //pen=oldwidth;
    end;{在客户区中心点画多边形}
    4:
    begin
    setpenstate;
    canvas.RoundRect(posx-100,posy-50,posx+100,posy+50,
    20,20);
    end;{在客户区中心点画带圆角的矩形}

    5:
    begin
    setpenstate;
    sdiappform.Canvas.Brush.Color:=clred;
    canvas.Rectangle(posx-100,posy-50,posx+100,posy+50);
    sdiappform.Canvas.Brush.Color:=bcolor;
    end{在客户区中心点用红色刷子画矩形}
    else
    begin
    canvas.Font:=formfont;
    canvas.TextOut(30,posy,str);
    end;
    end;{写字}
    end;
    上面程序中出现的变量在事件OnCreate中初始化。
    procedureTSDIAppForm.FormCreate(Sender:TObject);
    begin
    str:=;{要写在画布上的字符串}
    formfont:=canvas.font;{字体和大小}
    detectI:=0;{确定画布上出现何种图形的参数}
    rect:=sdiappform.ClientRect;{客户区矩形}
    old=sdiappform.Canvas.Pen.Width;{最初画笔宽度}
    pen=oldwidth;{画笔宽度}
    penstyle:=sdiappform.Canvas.Pen.Style;{画笔类型}
    pencolor:=sdiappform.Canvas.Pen.Color;{画笔颜色}
    bcolor:=sdiappform.Canvas.Brush.Color;{画刷颜色}
    end;

    为了减少代码,定义了一个Public过程,设定画笔。代码如下:
    procedureTSDIAppForm.setpenstate;
    begin
    withsdiappform.Canvas.Pendo
    begin
    color:=pencolor;
    style:=penstyle;
    =penwidth;
    end;
    end;
    响应每一个菜单项OnClick事件本程序设计得非常简单,如果有兴趣,读者也可以加上一些代码,完成许多复杂的工作。
    procedureTSDIAppForm.LineColor1Click(Sender:TObject);
    begin
    ifcolordialog1.Executethen
    begin
    pencolor:=colordialog1.Color;
    SdiAppForm.Canvas.Pen.Style:=psInsideFrame;
    ifpenwidth$#@60;1then
    SdiAppForm.Canvas.Pen.Width:=3;
    SdiAppForm.Canvas.Pen.Color:=pencolor;
    invalidate;
    end;
    end;{完成画笔颜色设定}
    //{完成画笔笔形设定}
    procedureTSDIAppForm.Solid1Click(Sender:TObject);
    begin
    penStyle:=pssolid;
    invalidate;
    end;


    procedureTSDIAppForm.Dot1Click(Sender:TObject);
    begin
    PenStyle:=psdot;
    invalidate;
    end;

    procedureTSDIAppForm.Dash1Click(Sender:TObject);
    begin
    penStyle:=psdash;
    invalidate;
    end;

    procedureTSDIAppForm.DashDot1Click(Sender:TObject);
    begin
    PenStyle:=psdashdot;
    invalidate;
    end;

    procedureTSDIAppForm.DashDotDot1Click(Sender:TObject);
    begin
    penStyle:=psdashdotdot;
    invalidate;
    end;
    //////////////////////////////////
    procedureTSDIAppForm.RoundRect1Click(Sender:TObject);
    begin
    detectI:=4;
    invalidate;
    end;

    procedureTSDIAppForm.Rectangle1Click(Sender:TObject);
    begin
    detectI:=5;
    invalidate;
    end;

    procedureTSDIAppForm.Helloworld1Click(Sender:TObject);
    begin
    detectI:=0;
    str:=helloworld!!;
    Invalidate;

    end;

    procedureTSDIAppForm.Imateacher1Click(Sender:TObject);
    begin
    detectI:=0;
    str:=Iamateacher!!;
    Invalidate;
    end;

    procedureTSDIAppForm.Fonts1Click(Sender:TObject);
    begin
    iffontdialog1.Executethen
    begin
    detectI:=0;
    formfont:=fontdialog1.font;
    invalidate;
    end;
    end;{设定字体和大小}

    编译并运行,可以看到画图的效果。

      (三)图形的拷贝和剪贴

      通过剪贴板可以完成拷贝和剪贴的功能。Canvas不直接支持剪贴板,完成Canvas上图画拷贝和张贴关键技巧是通过一个Tbitmap变量,把Canvas上的图形先复制到Tbitmap上,再把Tbitamp和window的剪贴板连起来,反过来也一样。

      Delphi通过鉴定Wizard建立的SDI程序中,有关Edit命令的Click事件定义在ActionList控件中,相关代码如下:

    //拷贝图形到剪贴板
    procedureTSDIAppForm.EditCopy1Execute(Sender:TObject);
    var
    bmp:tbitmap;//设置一个图形变量
    begin
    bmp:=tbitmap.Create;
    bmp.Width:=rect.Right+10;
    bmp.Height:=rect.Bottom+10;
    bmp.canvas.CopyRect(rect,sdiappform.canvas,rect);
    clipboard.Assign(bmp);
    bmp.free;
    end;
    //从剪贴板上复制
    procedureTSDIAppForm.EditPaste1Execute(Sender:TObject);
    var
    bmp:tbitmap;//设置一个图形变量
    begin
    ifclipboard.HasFormat(CF_BITMAP)then
    begin
    bmp:=tbitmap.create;
    bmp.Assign(clipboard);
    sdiappform.Canvas.draw(0,0,bmp);
    bmp.free;
    end
    elseifclipboard.HasFormat(CF_TEXT)then
    begin
    str:=clipboard.AsText;
    detectI:=0;
    invalidate;
    end;

    end;
    //剪下图形拷贝到剪贴板
    procedureTSDIAppForm.EditCut1Execute(Sender:TObject);
    begin
    EditCopy1Execute(sender);
    withsdiappform.Canvasdo
    begin
    copymode:=cmwhiteness;
    copyRect(rect,sdiappform.Canvas,rect);
    CopyMode:=cmSrcCopy;
    end;
    end;

    也可以把已有的图形文件直接拷贝在Canvas上,本程序通过菜单Open命令完成这一操作。
    procedureTSDIAppForm.FileOpen1Execute(Sender:TObject);
    var
    bmp:Tbitmap;
    currentfile:string;
    begin
    ifOpenDialog.Executethen
    begin
    currentfile:=OpenDialog.filename;
    ifcurrentfile$#@60;$#@62;then
    try
    bmp:=tbitmap.Create;
    bmp.LoadFromFile(currentfile);
    sdiappform.Canvas.StretchDraw(rect,bmp);
    finally
    bmp.Free;
    end;

    end;

    end;

    本程序只是简单的讨论了Canvas绘图功能,离图形软件包还相差很远,而且打开图形文件显示在Canvas中还有些问题,希望读者中编程高手能帮我改正。

  • 相关阅读:
    业务安全相关安全产品的反思
    离线安装selenium
    pytorch在cpu和gpu运算的性能差别
    Qt音视频开发33ffmpeg安卓版
    python怎么安装selenium库?如何使用?
    .NET 中 GC 的模式与风格
    .NET性能优化使用结构体替代类
    Pytorch快速入门及在线体验
    语音识别开源工具PyTorchKaldi:兼顾Kaldi效率与PyTorch灵活性
    如何让setTimeout方法间隔时间更为精确
  • 原文地址:https://www.cnblogs.com/chulia20002001/p/1915100.html
Copyright © 2020-2023  润新知