<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      軟件打開畫面中打開狀態的顯示

      [摘要]我們平時看到的很多軟件(PhotoShop,3DMax)都會在啟動畫面中顯示當前正在啟動哪個模塊,并在模塊加載失敗時給予提示,這樣的好處是,可以讓比較專業的軟件使用者知道當前軟件加載了哪些模塊,或者在軟件發生啟動錯誤時,讓用戶得以反饋是啟動的哪個模塊時發生了,以及在長時間的軟件啟動過程中,讓用戶知...
      我們平時看到的很多軟件(PhotoShop,3DMax)都會在啟動畫面中顯示當前正在啟動哪個模塊,并在模塊加載失敗時給予提示,這樣的好處是,可以讓比較專業的軟件使用者知道當前軟件加載了哪些模塊,或者在軟件發生啟動錯誤時,讓用戶得以反饋是啟動的哪個模塊時發生了,以及在長時間的軟件啟動過程中,讓用戶知道軟件還在工作,避免用戶對其失去信息。。。

      好了,說了那么多廢話,就來看看我是怎么制作這樣一個程序的,由于本人平時基本上都用Delphi來開發,所以以下代碼也都是Delphi的,但是基本框架有了,相信要用其它語言實現也不會很難。另外,以下這些代碼是我在過去的歷次開發過程中組部提煉出來的,雖然還無法達到不修改即使用的地步,但是要修改的內容也不會很多。。

      我的這個類叫做TAppLoader,首先要做的是,讓它接管部分程序的初始化工作。
      將工程dpr文件中的啟動代碼寫成這樣:
      var
        GAppLoader:TAppLoader;

      begin
        Application.Initialize;
        GAppLoader:=TAppLoader.Create();
        try
          if GAppLoader.DoLoad() then begin
            Application.Run;
          end;
        finally
          GAppLoader.Free;
        end;
      end.
      可以看到,所有的啟動代碼都在TAppLoader.DoLoad()函數中了,如果這個函數失敗,則會返回false,此時就跳過Application.Run();過程,直接跳出程序。
      接下來,來看一下這個類的定義:
        TAppLoader = class (TObject)
        private
          FSplashForm: TfrmSplash;
          FManagerList:TList;
        protected
          procedure InitializeManager(var AManager;AManagerClass:TCustomManagerClass);
          procedure OnAppLoading(ASender:TObject;AEvent:String;ADelay:Integer=5);
        public
          constructor Create();
          destructor Destroy(); override;
          function DoLoad: Boolean;
        end;

      除了剛才說到的DoLoad()函數外,還可以看到這么兩個函數:InitializeManager()和OnAppLoading()。
      在說明InitializeManager()函數前,需要先介紹這么一個類:
        TCustomManagerClass = class of TCustomManager;

        TCustomManager = class(TObject)
        private
          FOnAppLoading:TAppLoadingEvent;
        protected
          procedure Initialize();virtual;abstract;
          procedure Finalize();virtual;abstract;
          procedure DoAppLoading(AEvent:String);
          property OnAppLoading:TAppLoadingEvent read FOnAppLoading write FOnAppLoading;
        public
          constructor Create();virtual;
        end;
      在我的程序中,將所有的全局的資源管理類都叫做TxxxManager,而TCustomManager就定義了這些類的一些基本行為。說道這里,可能還有必要解釋一下什么是資源管理類,說白了,也就是將整個軟件運行期需要經常訪問的資源、使用的功能都集中起來管理,比如我將數據庫連接叫做:TDataManager,將串口通訊功能類叫做:TCommManager,等等。。。

      這個基類定義了Initialize()和Finalize()兩個虛方法,是用來讓TAppLoader啟動或關閉服務用的,這兩個方法不同與構造與析構函數,它們初始化的不是類本身的資源,而是一些外部連接資源,(比如網絡連接,文件句柄,串口端口等等),它們可以允許在不銷毀對象的前提下,進行重新連接,也就是說,除了在TAppLoader中會調用Initialize()和Finalize()方法,你也可以在軟件的使用過程中調用這兩個方法,(比如用戶選擇了新的串口端口號)。

      接著,可以看到TCustomManager中有一個OnAppLoading事件,在Initialize()的過程中,實際的Manager類就可以調用該方法,在啟動畫面上顯示文字了。該事件實際會調用TAppLoader.OnAppLoading()方法,它的代碼如下:
      procedure TAppLoader.OnAppLoading(ASender:TObject;AEvent:String;
              ADelay:Integer);
      begin
        if Assigned(FSplashForm) then begin
          if Assigned(ASender) then begin
            FSplashForm.lbl1.Caption:=ASender.ClassName+': '+AEvent;
          end
          else begin
            FSplashForm.lbl1.Caption:=AEvent;
          end;
          FSplashForm.Update;
          if ADelay>0 then
            Sleep(ADelay);
        end;
      end;
      其中FSplashForm就是啟動畫面了,在TAppLoader.DoLoad()中調用各個Manager的Initialize()方法時,這些Manager會根據自身當前初始化的內容,回調這個OnAppLoading()函數,此時就可以在啟動畫面上顯示文字了。

      實際的Manager類中只要調用DoAppLoading()方法,就可以將文字顯示到啟動畫面上了,如:
      procedure TFileImageManager.Initialize();
      var
        Directory:String;
        FindHandle:THandle;
        FindFileData:TWin32FindData;
      begin
        Directory:=ExtractFilePath(ParamStr(0))+'decoders\';
        FindHandle:=FindFirstFile(PChar(Directory+'*.dcd'),FindFileData);
        if FindHandle = INVALID_HANDLE_VALUE then
          exit;
        repeat
          if (FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)<>FILE_ATTRIBUTE_DIRECTORY then begin
            DoAppLoading('Loading ' + FindFileData.cFileName);
            AddDecoder(Directory+FindFileData.cFileName);
          end;
        until not FindNextFile(FindHandle,FindFileData);
        Windows.FindClose(FindHandle);
      end;

      TAppLoader中還有這么一個函數:
      procedure TAppLoader.InitializeManager(var AManager;AManagerClass:TCustomManagerClass);
      var
        Instance: TCustomManager;
      begin
        Instance := TCustomManager(AManagerClass.NewInstance);
        TCustomManager(AManager) := Instance;
        try
          Instance.Create();
          FManagerList.Add(@AManager);
          Instance.OnAppLoading:=OnAppLoading;
          Instance.Initialize();
          Instance.OnAppLoading:=nil;
        except
          TCustomManager(AManager):= nil;
          raise;
        end;
      end;
      它用來啟動一個Manager,并將其加入TAppLoader的一個FManagerList列表中,在TAppLoader析構時,它會自動按照這個列表,來釋放所有的Manager。
      在Manager的Initialize()結束后,比較保險的是將它的OnAppLoading重新設為空,這樣如果在程序運行過程中,由其它功能來調用Manager的Initialize()時,就不會再回調到顯示啟動文字的部分了。

      最后,看一下DoLoad()函數:
      function TAppLoader.DoLoad: Boolean;
      begin
        Result:=false;
        Application.Title:='Ultra Album';
        FSplashForm:=TfrmSplash.Create(nil);
        try
          try
            FSplashForm.Show;
            OnAppLoading(nil,'Starting...');
            Sleep(100);

            InitializeManager(GOptionManager,TOptionManager);
            InitializeManager(GRdItemClassManager,TRdItemClassManager);
            InitializeManager(GImageManager,TFileImageManager);
            InitializeManager(GThemeManager,TFileThemeManager2);
            InitializeManager(GMaskManager,TFileMaskManager);

            OnAppLoading(nil,'Ending...',0);

            Application.CreateForm(TfrmMain, frmMain);
            if ParamCount>=1 then begin   //deal with the filename in the parameter
              FSplashForm.Hide;
              frmMain.Show;
              frmMain.DoOpenFile(ParamStr(1));
            end;

            Result:=true;
          except
            on E:Exception do begin
              MessageBox(Application.Handle,PChar(E.ClassName+':'+#13+#10+E.Message),
                  PChar(Application.Title),MB_ICONERROR);
            end;
          end;
        finally
          FreeAndNil(FSplashForm);
        end;
      end;
      這個函數是我的一個軟件中的代碼,它首先構造并顯示一個啟動畫面,然后使用InitializeManager()分別初始化了5個Manager類,其中的GOptionManager,GRdItemClassManager。。。都是全局對象,在今后需要訪問時,都使用這個全局對象來進行訪問,這里我沒有使用Singleton模式,因為我覺得這幾個對象都必須在程序主窗體創建前完全初始化,而Singleton的設計思路是在對象第一次使用時才創建它的實例,在我的這個使用中不需要這樣的功能。當然,你也可以自己改造這些Manager類成為Singleton的,改動代碼不會很多。
      最后,再將程序的主界面創建出來,可以看到這個主界面的創建代碼就是我們從dpr文件中刪除的那行。




      日韩精品一区二区三区高清