📄 chap391.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>小结</title>
<link rel="stylesheet" href="../../../include/style.css">
</head>
<body>
<font SIZE="2">
<p><small><a href="../../../index.htm">首页</a> >> <a href="../../program.htm">程序设计</a>
>> <a href="../cbuilder.htm">C++ Builder</a> >> </small><font>具体而微的绘图程式</font>·小结</p>
<p align="left"><!--webbot bot="ImageMap" rectangle="(40,1) (71, 23) ../ch4/chap04.htm" rectangle="(4,1) (36, 23) chap39.htm" src="../ch1/NextBack.gif" width="72" height="24" alt="NextBack.gif (743字节)" border="0" startspan --><MAP NAME="FrontPageMap"><AREA SHAPE="RECT" COORDS="40, 1, 71, 23" HREF="../ch4/chap04.htm"><AREA SHAPE="RECT" COORDS="4, 1, 36, 23" HREF="chap39.htm"></MAP><a href="../../../_vti_bin/shtml.exe/program/C++/ch3/chap391.htm/map"><img ismap usemap="#FrontPageMap" border="0" height="24" alt="NextBack.gif (743字节)" src="../ch1/NextBack.gif" width="72"></a><!--webbot bot="ImageMap" endspan i-checksum="33674" --></p>
</font>
<p align="left"><font color="#FF0000" SIZE="2">·03-08小结</font></p>
<font SIZE="2">
<p>以上就是此绘图程式中所使用的各个物件的定义,此乃血统纯正的C++
写法的程式,不像C++Builder官方的范例是由Delphi的范例修改而来,充满了Object
Pascal的味道。</p>
<p>若你对C++
尚不太熟悉的话,请你一定要细细领略以上的精神。因为它是C++
式的物件导向程式最基本且精要的精神所在,当你了解了以上的精神,你就可谓掌握了C++
的封装、继承、及动态连结这叁把权仗的基本精神。</p>
<p>至於C++
老手,以上的定义都是很自然就可以接受的。也许有人会质疑以上的物件定义并未考虑到物件的永续性
(Object Persistence)。没错,不过这并不是我疏忽了,而是在本章的程式中图形的存取是以Timage来存取,因此所有向量式的物件都已转化成点阵图了,自然不需考虑到物件的储存问题。</p>
<p>在後续章节,我还会再针对物件的永续性来做一讨论。现在我们先就TImage的点阵图存取方式为平台讨论之。</p>
<p>最後,在完成了物件的定义之後,我们再将程式根据物件导向的方式再加以改写之。因为我目前尚未加入选择物件的方法,所以我只能用预设物件型态的方式来展示程式的结果。</p>
<p>// 表格建构函式,设定m_bDraw旗标初值</p>
<p>__fastcall TForm1::TForm1(TComponent* Owner)</p>
<p>: TForm(Owner)</p>
<p>{</p>
<p> m_bDraw = FALSE;</p>
<p>}</p>
<p>// Form的OnCreate事件处理函式。Form建立时引发。</p>
<p>// 1.设定笔的颜色及宽度。</p>
<p>// 2.产生一个CLine绘图物件。</p>
<p>// 注:你可以自行修改CLine成CPolyline、CPolygon、CRect等值。</p>
<p>void __fastcall TForm1::FormCreate(TObject *Sender)</p>
<p>{</p>
<p> Canvas->Pen->Color = clRed;</p>
<p> Canvas->Pen->Width = 2;</p>
<p> m_pObj = new CLine(Canvas);</p>
<p>}</p>
<p>// Form的OnClose事件处理函式。Form关闭时引发。</p>
<p>// 1.杀掉绘图物件。</p>
<p>void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)</p>
<p>{</p>
<p> delete m_pObj;</p>
<p>}</p>
<p>// 更改後的OnMouseDown物件处理函式。</p>
<p>// 1.将m_bDraw旗标设为 TRUE。</p>
<p>// 2.呼叫绘图物件的OnMouseDown函式。</p>
<p>void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,</p>
<p>TShiftState Shift, int X, int Y)</p>
<p>{</p>
<p> m_bDraw = TRUE;</p>
<p> m_pObj->OnMouseDown(X,Y);</p>
<p>}</p>
<p>// 更改後的OnMouseMove物件处理函式。</p>
<p>// 1.判断m_bDraw旗标是否为 TRUE。</p>
<p>// 2.若是则呼叫绘图物件的OnMouseMove函式。</p>
<p>void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,</p>
<p>int X, int Y)</p>
<p>{</p>
<p> if (m_bDraw)</p>
<p> m_pObj->OnMouseMove(X,Y);</p>
<p>}</p>
<p>// 更改後的OnMouseUp物件处理函式。</p>
<p>// 1.将m_bDraw旗标设为 FALSE。</p>
<p>// 2.若是则呼叫绘图物件的OnMouseUp函式。</p>
<p>void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,</p>
<p>TShiftState Shift, int X, int Y)</p>
<p>{</p>
<p> m_bDraw = FALSE;</p>
<p> m_pObj->OnMouseUp(X,Y);</p>
<p>}</p>
<p>瞧!这就是更改後的程式,是不是变得格外简洁呢?除此之外,它最大的优点在於,无论我们日後加入了多少绘图物件,你都不需再修改以上程式中关於绘图物件的处理部份,只要再自行增加一个物件宣告即可。和原先Borland公司产品内附由Object
Pascal修改而来的范例,它的C++
血统纯正多了。而且若是日後你想要将其修改成为一个物件式的绘图系统,也只需要很简单的修改而已。</p>
<p>好吧!让我们先检阅现在的成果。</p>
<p> </p>
<p><img SRC="Image11.gif" WIDTH="459" HEIGHT="348"></p>
<p>图XX-04 CLine绘图物件范例。</p>
<p><img SRC="Image12.gif" WIDTH="459" HEIGHT="348"></p>
<p>图05 CPolyline绘图物件范例(将程式改成new CPolyline)</p>
<p>04工具列(ToolBar)的使用</p>
<p>到目前为止我们已经将所有绘图物件定义完成,因此理论上你的程式应该可以画出各种不同的绘图物件了。但是前面我提到,目前我们尚未将绘图物件的选择功能实作出来,因此我们是以直接修改程式的方式来绘制不同的图形。这是为了说明方便的权宜之计。</p>
<p>在一般的绘图程式中都是以工具列的方式来实作出绘图功能的切换功能,如Windows
95内的小画家即是一典型例子。因此接下来我就为你说明在C++ Builder中实作出工具列的方法。</p>
<p><img SRC="Image13.gif" WIDTH="461" HEIGHT="352"></p>
<p>图06小画家使用的工具列</p>
<p>在C++ Builder中实作工具列的方式和其他的程式如Visual C++,Borland C++
不同。後两者都是直接使用Windows 95内建的工具列型别来达到此功能。然而在C++
Builder中因为有一种更为简单且直接的方式来做到,因此就不采用上述作法
(当然C++ Builder也可以用Windows 95内建的ToolBar型别,只是用法较为复杂。)。</p>
<p>那麽在C++ Builder中是如何来实作出工具列呢?说穿了其实很简单:那就是利用TPanel和TSpeedButton。</p>
<p>CPanel是一个多功能的容器元件,因此我们可以用它来做为工具列的平台,使用CPanel是因为它是少数几个可做为容器元件的元件,所以它会自动调整置於其上的软体元件的位置,因此很适合做为放置工具列的平台。</p>
<p>注:在C++ Builder的程式模式中大量使用TPanel来做为容器元件。它除了可以做为ToolBar的平台外,另外如状态列
(StatusBar)也可以用它来完成,而且它也可以用来做为画面分割的工具,来达成在MFC中类似分割视窗(Splitter
Window)效果。</p>
<p>TSpeedButton快速按钮元件在功能上本来就和工具列有几分类似,现在我们可以将相同属性的快速按钮元件整合在一个TPanel中即可完成我们所要的工具列了。</p>
<p>最後我再将工具列的作法按部就班详述之:</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -