熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

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

2013-11-23 17:45:05  來源: Delphi編程 
 我們平時看到的很多軟件(PhotoShopDMax)都會在啟動畫面中顯示當前正在啟動哪個模塊並在模塊加載失敗時給予提示這樣的好處是可以讓比較專業的軟件使用者知道當前軟件加載了哪些模塊或者在軟件發生啟動錯誤時讓用戶得以反饋是啟動的哪個模塊時發生了以及在長時間的軟件啟動過程中讓用戶知道軟件還在工作避免用戶對其失去信息

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

  我的這個類叫做TAppLoader首先要做的是讓它接管部分程序的初始化工作

  將工程dpr文件中的啟動代碼寫成這樣

var
GAppLoader:TAppLoader;

begin
ApplicationInitialize;
GAppLoader:=TAppLoaderCreate();
try
if GAppLoaderDoLoad() then begin
ApplicationRun;
end;
finally
GAppLoaderFree;
end;
end

  可以看到所有的啟動代碼都在TAppLoaderDoLoad()函數中了如果這個函數失敗則會返回false此時就跳過ApplicationRun();過程直接跳出程序

  接下來來看一下這個類的定義

TAppLoader = class (TObject)
private
FSplashForm: TfrmSplash;
FManagerList:TList;
protected
procedure InitializeManager(var AManager;AManagerClass:TCustomManagerClass);
procedure OnAppLoading(ASender:TObject;AEvent:String;ADelay:Integer=);
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類就可以調用該方法在啟動畫面上顯示文字了該事件實際會調用
TAppLoaderOnAppLoading()方法它的代碼如下

procedure TAppLoaderOnAppLoading(ASender:TObject;AEvent:String;
ADelay:Integer);
begin
if Assigned(FSplashForm) then begin
if Assigned(ASender) then begin
FSplashFormlblCaption:=ASenderClassName+: +AEvent;
end
else begin
FSplashFormlblCaption:=AEvent;
end;
FSplashFormUpdate;
if ADelay> then
Sleep(ADelay);
end;
end;

  其中FSplashForm就是啟動畫面了在TAppLoaderDoLoad()中調用各個Manager的Initialize()方法時這些Manager會根據自身當前初始化的內容回調這個OnAppLoading()函數此時就可以在啟動畫面上顯示文字了

  實際的Manager類中只要調用DoAppLoading()方法就可以將文字顯示到啟動畫面上了

procedure TFileImageManagerInitialize();
var
Directory:String;
FindHandle:THandle;
FindFileData:TWinFindData;
begin
Directory:=ExtractFilePath(ParamStr())+decoders\;
FindHandle:=FindFirstFile(PChar(Directory+*dcd)FindFileData);
if FindHandle = INVALID_HANDLE_VALUE then
exit;
repeat
if (FindFileDatadwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)<>FILE_ATTRIBUTE_DIRECTORY then begin
DoAppLoading(Loading + FindFileDatacFileName);
AddDecoder(Directory+FindFileDatacFileName);
end;
until not FindNextFile(FindHandleFindFileData);
WindowsFindClose(FindHandle);
end;

TAppLoader中還有這麼一個函數
procedure TAppLoaderInitializeManager(var AManager;AManagerClass:TCustomManagerClass);
var
Instance: TCustomManager;
begin
Instance := TCustomManager(AManagerClassNewInstance);
TCustomManager(AManager) := Instance;
try
InstanceCreate();
FManagerListAdd(@AManager);
InstanceOnAppLoading:=OnAppLoading;
InstanceInitialize();
InstanceOnAppLoading:=nil;
except
TCustomManager(AManager):= nil;
raise;
end;
end;

  它用來啟動一個Manager並將其加入TAppLoader的一個FManagerList列表中在TAppLoader析構時它會自動按照這個列表來釋放所有的Manager

  在Manager的Initialize()結束後比較保險的是將它的OnAppLoading重新設為空這樣如果在程序運行過程中由其它功能來調用Manager的Initialize()時就不會再回調到顯示啟動文字的部分了

  最後看一下DoLoad()函數

function TAppLoaderDoLoad: Boolean;
begin
Result:=false;
ApplicationTitle:=Ultra Album;
FSplashForm:=TfrmSplashCreate(nil);
try
try
FSplashFormShow;
OnAppLoading(nilStarting);
Sleep();

InitializeManager(GOptionManagerTOptionManager);
InitializeManager(GRdItemClassManagerTRdItemClassManager);
InitializeManager(GImageManagerTFileImageManager);
InitializeManager(GThemeManagerTFileThemeManager);
InitializeManager(GMaskManagerTFileMaskManager);

OnAppLoading(nilEnding);

ApplicationCreateForm(TfrmMain frmMain);
if ParamCount>= then begin //deal with the filename in the parameter
FSplashFormHide;
frmMainShow;
frmMainDoOpenFile(ParamStr());
end;

Result:=true;
except
on E:Exception do begin
MessageBox(ApplicationHandlePChar(EClassName+:+#+#+EMessage)
PChar(ApplicationTitle)MB_ICONERROR);
end;
end;
finally
FreeAndNil(FSplashForm);
end;
end;

  這個函數是我的一個軟件中的代碼它首先構造並顯示一個啟動畫面然後使用InitializeManager()分別初始化了個Manager類其中的GOptionManagerGRdItemClassManager都是全局對象在今後需要訪問時都使用這個全局對象來進行訪問這裡我沒有使用Singleton模式因為我覺得這幾個對象都必須在程序主窗體創建前完全初始化而Singleton的設計思路是在對象第一次使用時才創建它的實例在我的這個使用中不需要這樣的功能當然你也可以自己改造這些Manager類成為Singleton的改動代碼不會很多

  最後再將程序的主界面創建出來可以看到這個主界面的創建代碼就是我們從dpr文件中刪除的那行


From:http://tw.wingwit.com/Article/program/Delphi/201311/25015.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.