編程實用篇—C++Builder開發(fā)動畫DLL

字號:

我們在Windows98環(huán)境下執(zhí)行拷貝文件、查找文件等計算機耗時較長的操作時,Windows會顯示一個小 的動畫,指示正在進(jìn)行的操作,與死板的靜止圖像相比增色不少。那么我們自己開發(fā)軟件時,能否也 顯示一個這樣的動畫提示呢?筆者開發(fā)了一個能夠在PB下調(diào)用的動畫DLL,由于采用多線程編程,PB調(diào)用的DLL函數(shù)能夠及時將控制權(quán)交還給PB,不影響應(yīng)用系統(tǒng)的運轉(zhuǎn)。
    一、代碼與編譯選項
    在C++Builder中創(chuàng)建一個空白的DLL項目。
    創(chuàng)建一個空白的Form,修改它的屬性為:
     BorderStyle=bsDialog
    BorderIcons 的 子 屬 性 均 為False
    FormStyle=fsStayOnTop
    Position= poScreenCenter
    Name=StatusForm
    在Form上添加一個Win32下的Animate控件Animate1,修改它的屬性為Align=alTop
    在Form上添加一個Standard 下的Button 控件Button_Cancel,再添加System下的Timer控件Timer1, 設(shè)置定時Interval時間位250,較快響應(yīng)用戶的取消請求。
    因為PB應(yīng)用系統(tǒng)與動畫窗體代碼分別屬于兩個線程,不能采用PB線程直接關(guān)閉動畫窗體線程的窗口, 否則會引起系統(tǒng)運行不正常,因此采用PB線程設(shè)置關(guān)閉標(biāo)志,而動畫線程采用Timer控件定時檢查標(biāo) 志,一旦檢測到關(guān)閉標(biāo)志,就關(guān)閉窗口,清除線程標(biāo)志,結(jié)束動畫線程。
    下面給出編碼及編碼原理:
    (1)DLL主體代碼:
     / *DLL 主 體 代 碼
     * 定 義DLL 公 用 變 量
    *g_CommonAVI 對Animate 控 件
    動 畫 類 型 索 引
    *gi_Canceled Button_Cancel
    按 鈕 是 否 被 選 擇 過
    *gi_AVIType 要 顯 示 的 動 畫 類 型,
    由DLL 輸 出 函 數(shù) 做 為 參 數(shù) 輸 入
    *gi_RequestClose 請 求 動 畫 線 程 關(guān) 閉 標(biāo) 志
    *gi_WindowActive 動 畫 窗 口 所 處 的 狀 態(tài)
    *lpsWinTitle 動 畫 窗 體 的 標(biāo) 題,
    由DLL 輸 出 函 數(shù) 做 為 參 數(shù) 輸 入
    */
      TCommonAVI g_CommonAVI[]={
       aviNone, aviFindFolder,
       aviFindFile, aviFindComputer,
      aviCopyFiles, aviCopyFile,
       aviRecycleFile, aviEmptyRecycle,
      aviDeleteFile
      };
      int gi_Canceled=0,gi_AVIType=0;
      int gi_RequestClose=0,gi_WindowActive=0;
      char lpsWinTitle[256];
      HWND hWndParent=NULL;
      / * 定 義DLL 輸 出 函 數(shù) */
      extern “C" __declspec(dllexport) int pascal Dll
     EntryPoint(HINSTANCE hinst, unsigned
    long reason, void *);
      extern “C" __declspec(dllexport) int pascal
    ShowStatus Window
    (int AVIType,LPSTR WinTitle,long hWnd);
    extern “C" __declspec(dllexport)
    int pascal GetStatus(int ai_CloseWin);
    extern “C" __declspec(dllexport)
    int pascal CloseStatusWindow();
       / * 定 義 線 程TformThread: */
      class TFormThread : public TThread{
      public: // User declarations
      __fastcall TFormThread(bool CreateSuspended);
      void __fastcall Execute(void);
      };
      __fastcall TFormThread::
    TFormThread(bool CreateSuspended):
    TThread(CreateSuspended){
      }
    / * 動 畫 線 程 執(zhí) 行 代 碼,
    動 畫 窗 體 的 定 時 器 控 件 會 關(guān) 閉 它,
    清 除 窗 體 存 在 標(biāo) 志 后 結(jié) 束 線 程 的 運 行
    */
      void __fastcall TFormThread::Execute(void){
      gi_WindowActive=1;
       StatusForm=new TStatusForm(NULL);
       StatusForm ->Caption=lpsWinTitle;
       StatusForm ->ShowModal();
       gi_WindowActive=0;
       delete StatusForm;
       gi_RequestClose=0;
      }
      / * 定 義 一 個 線 程 實 例 指 針 */
      TFormThread *FormThread;
       / * 輸 出 函 數(shù) 代 碼 實 現(xiàn) 部 分
       * DllEntryPoint 32 位DLL 入 口
       * ShowStatusWindow 顯 示 動 畫 窗 口,
    它 通 過 創(chuàng) 建 一 個 線 程 來 創(chuàng) 建 窗 口,
    避 免 由 于 窗 口 的MODAL 屬 性 而 使
    控 制 權(quán) 不 能 及 時 的 返 還 給 調(diào) 用 者
       * GetStatus 取 得“ 取 消” 狀 態(tài),
    即 用 戶 有 沒 有 選 擇“ 取 消” 按 鈕
       * CloseStatusWindow 關(guān) 閉 動 畫 窗 口,
       */
      __declspec(dllexport) int WINAPI DllEntryPoint
    (HINSTANCE hinst, unsigned long reason, void *)
      {
      return 1;
      }
    __declspec(dllexport) int pascal ShowStatusWindow
    (int AVIType,LPSTR WinTitle,long hWnd){
    hWndParent=(HWND)hWnd;
    memset(lpsWinTitle,0,sizeof(lpsWinTitle));
    strncpy(lpsWinTitle,WinTitle,sizeof(lpsWin Title) -1);
    if (AVIType>0 & & AVIType<=8) gi_AVIType="AVIType;"    
     FormThread="new" TFormThread(true);      
     FormThread ->Priority = tpNormal;
       FormThread ->Resume();
      }
    __declspec(dllexport) int pascal GetStatus
    (int ai_CloseWin){
      if (gi_Canceled)
      if (gi_WindowActive){
      gi_RequestClose=1;
       while(gi_RequestClose);
       }
       return gi_Canceled;
      }
      __declspec(dllexport) int pascal CloseStatusWindow(){
       if (gi_WindowActive){
      gi_RequestClose=1;
       while(gi_RequestClose);
      }
       return gi_Canceled;
      }