在C++Builder中实现动画

一、 直接使用Animate部件

  ----在 您的程序中只要增加一个Animate部件,并设置其部分属性就可实现动画,但缺点就在于Animate部件只能打开已有的AVI视屏文件(或使用Windows公用AVI),有一定的系统开销。
----在板2(Panel2)中加入一个Animate部件(Animate1),我们设置其FileName或CommonAVI及Active属性以使其执行某AVI视屏文件或Windows公用AVI。设置Animate1的CommonAVI属性值为aviFindFolder,它将执行我们常见的在搜索文件夹过程中的搜索动画。
----为控制Animate1的动作,为第一个复选框(CheckBox1)的OnClick事件增加代码如下:

void __fastcall TDemoForm::
CheckBox1Click(TObject *Sender)
{
Animate1 ->Active = CheckBox1 ->Checked;
}
二、 使用Timer部件定时绘制画面

----在C++Builder的System标签中有一个Timer部件,使用Timer部件实际上是使用Windows定时器,定时绘制部分画面,达到动画效果。
----准备几张连续的Bmp图片
----Pic0.bmp Pic1.bmp Pic2.bmp Pic3.bmp 在板3(Panel3)中加入Image部件(Image1),并预装入一幅图片(如:Pic3.bmp)。
----为在程序中存储这些图片,在主窗体的头文件中增加变量定义:

TPicture *pic[4]; // 存 储 图 片 的 指 针
int number; // 记 录 当 前 图 片 序 号
----并为主窗口的OnCreate事件增加代码,在程序主窗口创建时装入图片,即:
void __fastcall TDemoForm::FormCreate(TObject *Sender)
{
number = 0;
AnsiString Path = ExtractFilePath(Application ->ExeName);
for(int i=0; i<4; i + +) { pic[i]="new" TPicture(); try { pic[i] ->LoadFromFile(Path +
“pic" +IntToStr(i) +“.bmp");
}
catch(...) {
Application ->MessageBox
(“\n 无 法 打 开 图 片 文 件...\t\n",
“ 错 误", MB_ICONWARNING|MB_OK);
} }
}
----增加Timer部件(Timer1),设置其时间间隔Interval属性为200毫秒;另外,设置Timer1的Enabled属性值为false。为定时更换绘制图片,为Timer1的OnTimer事件增加代码如下:
void __fastcall TDemoForm::
Timer1Timer(TObject *Sender)
{
Image1 ->Canvas ->CopyRect
(Image1 ->ClientRect,
   pic[number] ->Bitmap ->Canvas,
   Rect(0, 0, pic[number] ->Width,
pic[number] ->Height));
number + +;
number %=4;
}
----为第二个复选框(CheckBox2)的OnClick事件增加代码如下,以控制动画的执行与停止:
void __fastcall TDemoForm::CheckBox2Click
(TObject *Sender)
{
Timer1 ->Enabled = CheckBox2 ->Checked;
}
----使用Timer部件,定时绘制画面也并不复杂,但因为要存储多幅图片,系统开销却是相当大的,但其动画效果却也相当好。

三、利用程序空闲时间更换/重绘画面

----OnIdle事件是TApplication类的事件之一。当应用程序空闲时,程序就会产生OnIdle事件,利用程序空闲执行动画不是很妙吗?
----首先在演示程序主窗体的第四个板(Panel4)上增加一个标签(Lable1),根据你的个人爱好设置其Caption及Font等属性。再在主窗体的类定义中增加一个OnIdle事件处理函数,它像普通函数一样定义,但需保证其原型正确。我们定义的OnIdle事件处理函数在主窗体的头文件中作如下申明:
----
void __fastcall MyIdleHandler(TObject *Sender, bool & Done); ----其完整代码为:

void __fastcall TDemoForm::MyIdleHandler
(TObject *Sender, bool &Done)
{
int StartTime = GetTickCount();
if(Label1 ->Top +Label1 ->Height>0) {
Label1 ->Top - -;
}
else {
Label1 ->Top = Panel4 ->Height;
}
while(GetTickCount() -StartTime <50); }


----请注意,为避免移动标签速度过快,使用了下面的代码段:
int StartTime = GetTickCount();
...
while(GetTickCount() -StartTime <50);

----它保证了动画的时间间隔不少于50毫秒。----为第三个复选框(CheckBox3)的OnClick事件增加代码如下:
void __fastcall TDemoForm::CheckBox3Click
(TObject *Sender)
{
if(CheckBox3 ->Checked) {
Application ->OnIdle = MyIdleHandler;
}
else {
Application ->OnIdle = NULL;
}
}
----为保证程序执行的安全性,还需在程序结束时做一些必要的处理(如释放程序运行过程中分配的空间)。为主窗体的OnDestroy事件增加代码如下:
void __fastcall TDemoForm::FormDestroy
(TObject *Sender)
{
for(int i=0; i<4; i + +) { delete pic[i]; } Application ->OnIdle = NULL;
}