在C++ Builder中實現動畫
2019-09-06 23:33:54
供稿:網友
一、 直 接 使 用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="new" TPicture(); try { pic ->LoadFromFile(Path +
“pic" +IntToStr(i) +“.bmp");
}
catch(...) {
Application ->MessageBox
(“ 無 法 打 開 圖 片 文 件...",
“ 錯 誤", 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; } Application ->OnIdle = NULL;
}