荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jek (好好学习天天向上), 信区: Program
标  题: 创世纪的 C++builder(2)
发信站: BBS 荔园晨风站 (Sun Mar 12 02:36:00 2000), 转信

第XX章 图形程式设计基本观念



XX-0 前言



由於Windows是一个图形界面的作业系统,所以传统的Windows程式设计方法在

处理有关图形设计时,多半是遵循自着Windows诞生以来的方法,透过所谓的GDI

(Graphics Device Interface)来实作图形的绘制。GDI式的绘图法对於早期

曾经在Dos下自行撰写绘图模组的程式设计师来说,虽然节省了不少

<重新发明轮子> 的麻烦,但是相对地也带来另外一种程式设计的思维模式转变,

相信曾经经历过这段过程的人都馀悸犹存。



对於完全没有任何程式经验的初学者来说,庞大复杂的GDI绘图系统更是一个难

以跨越的学习障疑。



在Windows中难道没有一个简易可行的绘图方法吗?有的,本章要为你介绍的C++

Builder绘图系统,就提供了一个高度抽象化的绘图模组,让你可以用非常直观

的方式来实作出Windows下的绘图功能。



XX-01 C++ Builder的神奇画布 (Canvas)



在C++ Builder中提供了一种称为Canvas的性质 (Property),在仔细观察後

你会发现,几乎所有的视觉化元件都包含这个性质,它就是C++

Builder为程式设计师所提供的神奇画布。



Canvas包含了许多和绘图有关的性质,如Pen、Brush、Pixels、Font等;另外

也包含了各种绘图的函式,如LineTo、Rectangle、MoveTo、Polygon等等。在

本单元中,我会一一为你介绍这些性质及工具的用法,相信在领略了C++

Builder的直觉式绘图法後,你再也不会为它所困扰。



对於Canvas,Pen,Brush等C++

Builder的关键字,往後我会采取直接使用原文而不翻译的方式,这是因为原文

非常简洁,译成中文反而饶舌,有画蛇添足之虞。当然,在某些时候,使用中文

可以使文意较为流畅时,我还不会择其善者而用之。



XX-02 C++ Builder的直觉绘图法



在进入主题前,我先以几个范例来说明C++ 恚∷淙慌哟蟮腉DI绘图系统具备通天彻地的完整
Windows绘图功能,

可是也许大部份的人要求的并不多,只是希望可以在Windows下画出自已心中理

想的图而已。



以下我以几个绘图范例来说明C++ Builder的绘图法。



简易绘图范例XX-01



范例一的输出



图X责绘图的FormPaint

部份,其中用了许多的三角函数如sin,cos,M_PI等运算,我在此就不另加说明

了,之所用使用了这些函数只是为了在介绍这些简单的函式时,利用这些简单函

式所产生的美丽图形,加深你的印象及学习效果罢了。电脑绘图之所以迷人也在

於此,它可以利用电脑强大的运算及绘图能力,很容易地将一些复杂的图显示出

来。



除了以上两个范例之外,我再为你示范两个同样使用简单的画线函式的绘图范

例,不过细节我就不再详述了,另外因为它的关键部份程式很短,为了避免你来

回读取档案交互叁考的困扰,我还是把它列出来,你可以尝试着修改其中的叁数,

说不定可以产生更为美观的图形呢!



范例三的输出



图XX-03



void __fastcall TForm1::FormPaint(TObject *Sender)

{

double A,x1,y1,x2,y2;

int D=100;

double E;

for (int i=0; i<720; i++)

{

A = i*M_PI/360;

E = D*(1+sin(4*A));

x1 = 320+E*cos(A);

x2 = 320+E*cos(A+M_PI/5);

y1 = 240+E*sin(A);

y2 = 240+E*sin(A+M_PI/5);

Canvas->MoveTo(x1,y1);

Canvas->LineTo(x2,y2);

}

}



范例四的输出





图XX-04



void __fastcall TForm1::FormPaint(TObject *Sender)

{

double A,x1,y1,x2,y2;

int D=80;

double E,F;

for (int i=0; i<960; i++)

{

A = i*M_PI/480;

E = D*(1+cos(20*A)/4);

F = E*(1+sin(4*A));

x1 = 320+F*cos(A);

x2 = 320+F*cos(A+M_PI/5);

y1 = 240-F*sin(A);

y2 = 240-F*sin(A+M_PI/5);

Canvas->MoveTo(x1,y1);

Canvas->LineTo(x2,y2);

}

}



以上四个范例程式是我先为你准备的开胃小菜,主要用以说明C++Builder

的Canvas绘图基本观念,同时也让你明了:利用几个简单的基本函式也可以做

出美丽的电脑绘突嵊谢嵊玫絋Canvas的Handle性质,它其实就是在Windows SDK

绘图函式中都必须要用到的DC (Device

Context)值。在Windows系统中,所有的绘图动作都必须透过DC来达成,

举例来说标准的SDK画线函式应该是这样的



BOOL LineTo(

HDC hdc, // device context handle

int nXEnd, // x-coordinate of line's ending point

int nYEnd // y-coordinate of line's ending point

);

因此在C++Builder中,使用Casvas->LineTo(x,y)

来绘图和呼叫标准SDK函式的LineTo((HDC)Canvas->Handle,x,y) 是一样的。



当然我不建议你在C++Builder中使用SDK语法来画图,但是我还是希望你对它

们两者之间的关系有一些了解,因为C++Builder的VCL虽然在Canvas中已经把

大部份的绘图函式实作出来,以物件的方式提供你使用,不过若是你要使用到

Canvas未提供的绘图函式时,你就可以利用Canvas->Handle来做为传入SDK函

式的叁数。



XX-04 TCanvas的TPen 性质



注:SDK加油站。

在SDK中使用Pen的方式是利用SelectObject函式来达成。它传入两个叁数,

一个是HDC值,它就是Canvas->Handle值,另一个则是HGDIOBJ值,它是一些

绘图工具的通称,以Pen而言,它就是HPEN值,同时也是Pen->Handle值。



HGDIOBJ SelectObject(

HDC hdc, // handle of device context

HGDIOBJ hgdiobj // handle of object

);





现在开始,我要为你一一介绍在TCanvas所使用的绘图工具。首先为你介绍的是

TPen性质。在往下进行之前,我先简单说明C++

Builder的命名怪形一嵋狼榭鼋换ナ褂弥?



TPen是你在Canvas画线所使用的”笔”,因此所有和线条有关的绘图函式都会

受TPen影响,如LineTo,Ellipse,Polygon,PolyLine,Rectangle等函式都

使用”笔”来画线,基本上我们可以将这些绘图工具归类为向量式的绘图工具,

所有的向量琒tyle,以及

Mode。你可以修改上述性质来达到改变线条颜色及样式的目的。



XX-04-01 Color性质



Color性质可以定出笔的颜色。在C++

Builder中提供了许多颜色的预定常数,这些预设颜色都以cl(cl代表color)

为启始字元命名。例如clRed代表红色,,clBlue代表蓝色,clGreen代表绿色

等等。另外C++

Builder也将Windows的基本颜色以常数定义,如clWindow及clMenu分别代表

Window及Menu的颜色。以下我列出部份C++

Builder定义的颜色常数,你不必完全记住它,只要有些印象即可,若是无法记

住,可以直接使用线上辅助说明,不过记住一些常用的常数会加快你程式写作的

效率。



颜色常数说明

值 意义

            clBlack 黑色

            clMaroon 茶色

            clGreen 绿色

            clOlive 橄榄绿

            clNavy 海蓝色

            clPurple 紫色

            clTeal 青紫色

            clGray 灰色

            clSilver 银色

            clRed 红色

            clLime 灰绿色

            clBlue 蓝色

            clFuchsia

            clAqua 淡绿青色

            clWhite 白色

            clBackground  非活动视窗的边界颜色

            clAppWorkSpace 视窗工作区域的颜色

            clHighlight 高亮度Windows颜色

            clHightlightText 被选取文字的颜

            clBtnFace Button颜色

            clBtnShadow Button影子颜色

            clGrayText 灰色文字色

            clBtnText Button内文字颜

            clBtnHighlight Button高亮度颜色





以下的程式会将画笔的颜色设为蓝色

Canvas->Pen->Color=clBlue;



另外我们也可以利用以下的叙述来改变颜色



Canvas->Pen->Color = TColordows系统的对应值。例如RGB(255,0,0)

的传回值是代表红色,所以Tcolor(RGB(255,0,0)) 所代表的意义和clRed是相

同的。你也可以利用ColorToRGB来将clRed等C++

Builder定义的常数值传换成Windows系统所代表的RGB颜色。



XX-04-02 Style性质



Style性质是用来改变画笔的型式,在C++ Builder中定义了以下几种画笔型式。

它们都以ps为启始字串 (ps代表Pen Style)。



psClear 清除线

psDash Dash线

psDashDot Dash和Dot交替线

psDashDotDot Dash和一堆Dot线

psSolid 实心线





图XX-05



XX-04-03 Width性质



笔的Width顾名思义,就是指笔的粗细,我在前面几个程式都已使用过了,所以

在此不再细述。



XX-04-04 Mode性质



Pen的Mode性质是用以决定Pen如何画在Canvas上,下表列出我们可以使用的

Mode,它们都以pm为启始字元,代表Pen Mode。



Mode 点的颜色

pmBlack 恒为黑色

pmWhite 恒为白色.

pmNop 不变色。

pmNot 萤幕的反相色。

pmCopy 使用Color性质的颜色(内定值).

pmNotCopy 使用Color性质的反相色。

pmMergePenNot Color和萤幕反相的 Merge。

pmMaskPenNot Color和萤幕反相的 Mask。

pmMergeNotPen桓龀S玫腗ode是

pmXor,它是用来让Pen->Color和  幕颜色做XOR运算,XOR运算最重要的特徵

是:和同一个值做两次XOR运算时,会恢复原来的值。

因此我们可以用XOR模式在同一位置画两次线,将原来的线擦掉。在本书的绘图

范例中就使用pmXor来处理滑鼠的画线,用以将上次的线条清除掉。同时XOR运

算也是一种最简单的编码演算法,不过这不在本书讨论范围内,因此我就不再多

说了。



XX-05 TCanvas的TBrush性质



TBrush可用来在Canvas的特定区域下着色。和TPen不同的是,TBrush可以用

不同的颜色、样式、及图案来填满Canvas的特定区域,而TPen则是用来在Canvas

上绘线。



XX-04-01 Style性质



TBrush共有bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal,

bsBDiagonal,

bsCross, bsDiagCross等几种 Style,你可以由图XX-06看出这几种不同的笔

刷型式有何不同。





图XX-06



XX-05 TCanvas的Pixels性质



Pixel性质,是一个二维的颜色阵列,它让你可以直接存取Canvas内的任何一

点。你可以利用和一般阵列相同的存取方法来取得Pixel内的值。此阵列的最大

索引值是X,Y的值。



除非必要,否则不要以Pixel来绘图,它是最慢的绘图方法。



XX-06 TCanvas的Font性质



Font性质是用来控制画在Canvas上的文字所使用的字形。你可以利用改变

Color,Name,Size,Style的方式来分别改变字形的颜色、使用的字形名称、

字形大小及字形的样式。



XX-06-1 TFont的Color、Name、Size性质。



TFont的Color性质和其他元件的Color性质相同。

Name性质表示使用字形的名称。你可以用以下的方式来设定字形名称。

Canvas->Font->Name=”标楷体“;

Size性质表示字形的大小。



XX-06-02 TFont的Style性质。



Style性质用以表示字型的样式。它包含以下几种样式:



fsBold 粗体

fsItalic 斜体

fsUnderline 底线

fsStrikeOut 穿越文字的水平直线。



<<< 以下待续 >>>



--
※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.118]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店