( 一)Canvas和CDC绘图方法比较:
我们可以从以下表格中看到Tcanvas和CDC相似的函数:
表 1--1
Canvas方法    CDC方法    功能
Arc        Arc        画一个椭圆弧
Chord        Chord        画一根玄。
CopyRect            拷贝指定矩形区域中图象到指定矩形
Draw        BitBlt        拷贝位图
Ellipse        Ellipse        画椭圆
FillRect    PaintRgn    使用刷子填充一个又一个矩型
FloodFill    FloodFill    用当前刷子填充区域
FrameRect    FrameRect    画一个矩形框
Lineto        Lineto        画线到
Moveto        Moveto        移    到
Pie        Pie        画扇形
Polygon        Polygon        画多边形
PolyLine    PolyLine    画多根相连的线
Rectangle    Rectangle    画一个实心矩形
RoundRect    RoundRect    画一个圆角的矩形
StretchDraw    StretchBlt    从源图象中
移动图象到指定矩形
TextWidth    GetCharWidth    返回字符宽
TextOut        TextOut        在指定坐标写字
TextRect    ExtTextOut    在制定矩形中写字

----上表中,我们只列出部分绘图函数,详细了解,请参阅有关Delphi和VC书籍.
----与VC++ 相类似,Delphi也提供了绘图工具,如Tpen, Tbrush等,与VC不同的是,  Delphi的绘图工具封装在Tcanvas中。Delphi也提供字形及字体大小的类Tfont,下面我们用具体例子来分析它们的用法。

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

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

----  编辑主菜单。增加Write,Draw 俩个下拉菜单项。  在"Write"下增加"Hello World!!" , "I am a teacher ", "Font.." 菜单项. 在"Draw"下增加"Arc" ,"Line", "Polygon", "RoundRect" ,"Rectangle" ,"color." ,"Line Style ","Width Line" .   在 "Line Style" 菜单下增加 "Solid", "Dash", "Dot" ,"DashDot", "DashDotDot" 子菜单。

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

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

procedure TSDIAppForm.FormPaint(Sender: TObject);
begin
canvas.FillRect(rect);  {清空桌面画布}
with SDIappform do
posx:=clientwidth div 2;
posy:=clientheight div 2;  {确定客户区中心点}
case  detectI  of
1 :
begin
setpenstate;
canvas.Ellipse(posx-50,posy-50,posx+50,posy+50);
//      penwidth:=oldwidth;
end; {在客户区中心点画圆}
2:
begin
setpenstate;
canvas.MoveTo(posx-60,posy-60);
canvas.LineTo(posx+60,posy+60);
//      penwidth:=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)]);
//        penwidth:=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中初始化。
procedure TSDIAppForm.FormCreate(Sender: TObject);
begin
str:='';  {要写在画布上的字符串}
formfont:=canvas.font;  {字体和大小}
detectI:=0;  {确定画布上出现何种图形的参数}
rect:=sdiappform.ClientRect;  {客户区矩形}
oldwidth:=sdiappform.Canvas.Pen.Width;  {最初画笔宽度}
penwidth:=oldwidth; {画笔宽度}
penstyle:=sdiappform.Canvas.Pen.Style;  {画笔类型}
pencolor:=sdiappform.Canvas.Pen.Color;  {画笔颜色}
bcolor:=sdiappform.Canvas.Brush.Color;  {画刷颜色}
end;

----为了减少代码,定义了一个Public过程,设定画笔。代码如下:
procedure TSDIAppForm.setpenstate ;
begin
with sdiappform.Canvas.Pen do
begin
color:=pencolor;
style:=penstyle;
width:=penwidth ;
end;
end;

----响应每一个菜单项OnClick事件本程序设计得非常简单,如果有兴趣,也可以加上一些代码,完成许多复杂的工作。
procedure TSDIAppForm.LineColor1Click(Sender: TObject);
begin
if colordialog1.Execute then
begin
pencolor:=colordialog1.Color;
SdiAppForm.Canvas.Pen.Style:=psInsideFrame;
if penwidth < 1 then
SdiAppForm.Canvas.Pen.Width:=3    ;
SdiAppForm.Canvas.Pen.Color:=pencolor;
invalidate;
end;
end;  {完成画笔颜色设定}
// {完成画笔笔形设定}
procedure TSDIAppForm.Solid1Click(Sender: TObject);
begin
penStyle:=pssolid;
invalidate;
end;
procedure TSDIAppForm.Dot1Click(Sender: TObject);
begin
PenStyle:=psdot;
invalidate;
end;
procedure TSDIAppForm.Dash1Click(Sender: TObject);
begin
penStyle:=psdash;
invalidate;
end;
procedure TSDIAppForm.DashDot1Click(Sender: TObject);
begin
PenStyle:=psdashdot;
invalidate;
end;
procedure TSDIAppForm.DashDotDot1Click(Sender: TObject);
begin
penStyle:=psdashdotdot;
invalidate;
end;
//////////////////////////////////
procedure TSDIAppForm.RoundRect1Click(Sender: TObject);
begin
detectI:=4;
invalidate;
end;
procedure TSDIAppForm.Rectangle1Click(Sender: TObject);
begin
detectI:=5;
invalidate;
end;
procedure TSDIAppForm.Helloworld1Click(Sender: TObject);
begin
detectI:=0;
str:='hello world!!';
Invalidate;
end;
procedure TSDIAppForm.Imateacher1Click(Sender: TObject);
begin
detectI:=0;
str:='I am a teacher!!';
Invalidate;
end;
procedure TSDIAppForm.Fonts1Click(Sender: TObject);
begin
if fontdialog1.Execute then
begin
detectI:=0;
formfont:=fontdialog1.font ;
invalidate;
end;
end; {设定字体和大小}

----编译并运行,可以看到画图的效果。
----( 三)图形的拷贝和剪贴

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

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

//拷贝图形到剪贴板
procedure TSDIAppForm.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;
//从剪贴板上复制
procedure TSDIAppForm.EditPaste1Execute(Sender: TObject);
var
bmp :tbitmap; // 设置一个图形变量
begin
if clipboard.HasFormat(CF_BITMAP) then
begin
bmp:=tbitmap.create;
bmp.Assign(clipboard);
sdiappform.Canvas.draw(0,0,bmp);
bmp.free;
end
else if clipboard.HasFormat(CF_TEXT) then
begin
str:=clipboard.AsText;
detectI:=0;
invalidate;
end  ;
end;
//剪下图形拷贝到剪贴板
procedure TSDIAppForm.EditCut1Execute(Sender: TObject);
begin
EditCopy1Execute(sender);
with sdiappform.Canvas do
begin
copymode:=cmwhiteness;
copyRect(rect,sdiappform.Canvas,rect);
CopyMode:=cmSrcCopy;
end;
end;

----也可以把已有的图形文件直接拷贝在Canvas上,本程序通过菜单Open命令完成这一操作。
procedure TSDIAppForm.FileOpen1Execute(Sender: TObject);
var
bmp : Tbitmap;
currentfile : string;
begin
if OpenDialog.Execute then
begin
currentfile:=OpenDialog.filename;
if currentfile< >'' then
try
bmp:=tbitmap.Create;
bmp.LoadFromFile(currentfile);
sdiappform.Canvas.StretchDraw(rect,bmp);
finally
bmp.Free;
end;
end;
end;

----本程序只是简单的讨论了Canvas绘图功能,离图形软件包还相差很远,而且打开图形文件显示在Canvas中还有些问题。

posted on 2012-02-16 13:28  del88  阅读(2)  评论(0编辑  收藏  举报