亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

軟件啟動畫面中啟動狀態的顯示

2019-11-18 18:03:40
字體:
來源:轉載
供稿:網友
 

我們平時看到的很多軟件(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文件中刪除的那行。


上一篇:支持多線程的日志類,可以在線程中使用,用來與主窗口通訊

下一篇:自動生成拼音(漢字反查到拼音)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产福利在线| 一区二区三区回区在观看免费视频| 成人乱人伦精品视频在线观看| 热久久这里只有精品| 亚洲第一精品夜夜躁人人躁| 亚洲天堂免费观看| 日韩免费在线播放| 久久97精品久久久久久久不卡| 日韩国产激情在线| 国产精品嫩草影院久久久| 国产精品69精品一区二区三区| 久久精品国产欧美亚洲人人爽| 国产精品无av码在线观看| 国产精品一区二区久久久| 日本视频久久久| 久久久精品国产一区二区| 亚洲字幕在线观看| 97超级碰碰人国产在线观看| 国产又爽又黄的激情精品视频| 欧美精品一本久久男人的天堂| 最近2019中文字幕一页二页| 欧美日韩中文字幕| 欧美性xxxx18| 欧美福利视频在线| 精品亚洲一区二区三区四区五区| 777国产偷窥盗摄精品视频| 久久久久久综合网天天| 国产精品亚洲一区二区三区| 亚洲国产精品va在线观看黑人| 日韩精品999| 欧美午夜女人视频在线| 国产精品第七影院| 久久99精品久久久久久噜噜| 国产成人福利视频| 77777亚洲午夜久久多人| 欧美日韩亚洲一区二区| 成人性生交大片免费看小说| 国产精品视频色| 欧美成aaa人片在线观看蜜臀| 亚洲一区二区三区视频| 亚洲欧美日韩国产成人| 成人午夜激情网| 亚洲精品免费一区二区三区| 欧美精品在线播放| 欧美精品videos性欧美| 日韩一区二区精品视频| 精品香蕉在线观看视频一| 久久久亚洲福利精品午夜| 亚洲三级 欧美三级| 九九热在线精品视频| 久久免费视频观看| 亚洲图片欧美日产| 国产精品一区二区久久久久| 亚洲欧美制服丝袜| 久久艳片www.17c.com| 亚洲国产免费av| 91免费版网站入口| 亚洲激情免费观看| 欧美日韩国产va另类| 国产精品日韩在线| 国产精品视频成人| 亚洲精品国产成人| 在线精品视频视频中文字幕| 精品国产一区久久久| 亚洲精品日韩欧美| 国产不卡av在线免费观看| 欧美激情视频播放| 亚洲a∨日韩av高清在线观看| 91精品国产色综合久久不卡98| 亚洲色图17p| 色综合久久88色综合天天看泰| 亚洲最大成人网色| 国产精品美女网站| 亚洲国产成人精品久久久国产成人一区| 亚洲国产精品va| 中日韩午夜理伦电影免费| 亚洲国产三级网| 美女视频黄免费的亚洲男人天堂| 人人澡人人澡人人看欧美| 久久中文久久字幕| 日韩av在线免费| 日韩欧美中文字幕在线观看| 国产成人aa精品一区在线播放| 午夜精品www| 国产精品jvid在线观看蜜臀| 久久久av亚洲男天堂| 人人澡人人澡人人看欧美| 久久久精品久久久| 日韩精品在线视频| 91亚洲精品在线观看| 亚洲香蕉在线观看| 亚洲香蕉成视频在线观看| 欧美电影免费观看高清完整| 欧美视频在线看| 日本欧美国产在线| 久久久久中文字幕2018| 中文字幕久久久| 色老头一区二区三区在线观看| 国产一区二区三区视频| 日韩欧美国产激情| 欧美性猛交xxxx乱大交蜜桃| 欧美日韩另类字幕中文| 欧美麻豆久久久久久中文| 欧美在线免费观看| 视频在线观看一区二区| 日本精品中文字幕| 色偷偷av亚洲男人的天堂| 久久精品视频一| 久久99国产精品久久久久久久久| 日本伊人精品一区二区三区介绍| 狠狠躁夜夜躁人人躁婷婷91| 久久久久成人精品| 亚洲美腿欧美激情另类| 久久久久久久久久久91| 欧美日韩在线免费| 国产女精品视频网站免费| 亚洲精品一区二区三区婷婷月| 97精品国产97久久久久久春色| 日韩不卡中文字幕| 国产精品高清在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整| 日韩在线观看成人| 日韩欧美在线网址| 日韩av最新在线观看| 中文字幕亚洲欧美日韩高清| 欧美性猛交视频| 2019中文字幕全在线观看| 日韩成人激情在线| 亚洲成av人片在线观看香蕉| 国产精品∨欧美精品v日韩精品| 欧美黑人一级爽快片淫片高清| 奇米影视亚洲狠狠色| 97国产精品视频| 91国产精品视频在线| 91日本视频在线| 欧美视频免费在线观看| 亚洲最大的免费| 国产精品一区二区三区久久| 97国产真实伦对白精彩视频8| 这里只有精品视频在线| 久久99久久久久久久噜噜| 国产精品视频久久| 亚洲最新av在线网站| 中文字幕亚洲综合| 精品国产成人在线| 欧美一级片在线播放| 日韩专区在线播放| 亚洲第一网站免费视频| 97精品免费视频| 欧美激情国产精品| 欧美疯狂做受xxxx高潮| 欧美精品午夜视频| 久久99久久99精品免观看粉嫩| 蜜月aⅴ免费一区二区三区| 91高清视频免费观看| 日本国产一区二区三区| 国产精品午夜视频| xvideos亚洲人网站| 亚洲成av人片在线观看香蕉| 国产精品视频资源| 亚洲精品不卡在线| 久久中文字幕国产| 高清一区二区三区日本久| 成人免费观看网址|