程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi 信息化管理系統開源框架 @ 啟動時刻,delphi開源

Delphi 信息化管理系統開源框架 @ 啟動時刻,delphi開源

編輯:Delphi

Delphi 信息化管理系統開源框架 @ 啟動時刻,delphi開源


這篇文章首先走馬觀花了解一下程序啟動那一刻都做了些什麼

 1 Program StarOfficeMain;
 2 
 3 uses
 4   StarOfficeApplication,
 5   MainForm in 'Form\MainForm.pas' {frmMain},
 6   StarMainFormInterface in 'Interface\StarMainFormInterface.pas';
 7 
 8 {$R *.res}
 9 
10 begin
11   ReportMemoryLeaksOnShutdown:=True;
12   Application.Initialize;
13   Application.MainFormOnTaskbar := True;
14   Application.CreateForm(TfrmMain, frmMain);
15   Application.Run;
16 end.

這是主程序的工程文件,和默認工程相比,是把原本的Forms替換成StarOfficeApplication

1 unit StarOfficeApplication;
2 
3 var
4   Application:TStarOfficeApplication;

StarOfficeApplication定義了一個TStarOfficeApplication對象的全局變量Application,所以替換了Forms的Application

1 constructor TStarOfficeApplication.Create;
2 begin
3   FModuleMgr:=TStarModuleManager.Create;
4 end;

TStarOfficeApplication構造函數裡創建了一個TStarModuleManager對象,該對象負責框架的模塊管理

1 procedure TStarOfficeApplication.Run;
2 begin
3   Forms.Application.Run;
4   FModuleMgr.final;
5 end;

當工程文件裡執行Application.Run的時候,實際調用的是TStarOfficeApplication的Run函數

Run函數首先是調用了Forms文件裡的 Application.Run;使程序運行起來

但程序退出時FModuleMgr.final;是對模塊的卸載

1 constructor TStarModuleManager.Create;
2 begin
3   FLoadBatch:='';
4   FModuleList := TObjectList.Create(True);
5   TStarObjectFactoryExt.Create([IStarModuleInfoEnum,IStarModuleLoader], self);
6 end;

模塊管理類TStarModuleManager構造函數裡注冊了一個IStarModuleLoader接口實例對象

TStarObjectFactoryExt實例擴展工廠繼承自TStarBaseFactoryExt,在TStarBaseFactoryExt的構造函數裡

創建了類廠管理對象FFactoryManager

 1 constructor TStarBaseFactoryExt.Create(const IIDs: array of TGUID);
 2 var i:Integer;
 3 begin
 4   FIIDList:=TStringList.Create;
 5   
 6   for i:=low(IIDs) to high(IIDs) do
 7   begin
 8     if StarOfficeFactory.Exists(IIDs[i]) then
 9       Raise Exception.CreateFmt(Err_IntfExists,[GUIDToString(IIDs[i])]);
10       
11     FIIDList.Add(GUIDToString(IIDs[i]));
12   end;
13   StarOfficeFactory.RegisterFactory(self);
14 end;
1 function StarOfficeFactory:TStarFactoryManager;
2 begin
3   if FFactoryManager=nil then
4     FFactoryManager:=TStarFactoryManager.Create;
5 
6   Result:=FFactoryManager;
7 end;

從代碼可以看出,不管何時調用StarOfficeFactory函數,只會在首次調用創建一個類廠管理對象

同理,通知管理,事件管理也在程序啟動之時被創建,並添加到類廠管理對象中

 1 procedure TfrmMain.FormCreate(Sender: TObject);
 2 var Intf: IStarModuleLoader;
 3 begin
 4   TStarObjectFactory.Create(IStarMainForm,Self);;
 5 
 6   Intf:=StarOffice as IStarModuleLoader;
 7   Intf.LoadBegin;
 8   Intf.LoadModulesFromDir;
 9   Intf.LoadFinish;
10 
11   (StarOffice as IStarEventManager).EnumEvent(Self);
12 end;
1 function StarOffice: IInterface;
2 begin
3   if not Assigned(FSysService) then
4     FSysService := TStarOfficeService.Create;
5 
6   Result := FSysService;
7 end;

StarOffice 返回的是一個IInterface對象,該對象由TStarOfficeService類創建

StarOffice返回的IInterface對象並沒有與接口IStarModuleLoader有任何繼承關系,可為什麼可以 as 呢?

這是接口的特性之接口查詢

1 TStarOfficeService = class(TObject, IInterface)
2   private
3     FRefCount: Integer;
4   protected
5     function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
6     function _AddRef: Integer; stdcall;
7     function _Release: Integer; stdcall;
8   public
9   end;

TStarOfficeService 類實現了IInterface的接口函數

 1 function TStarOfficeService.QueryInterface(const IID: TGUID; out Obj): HResult;
 2 var
 3   aFactory: TStarFactory;
 4 begin
 5   Result := E_NOINTERFACE;
 6   if self.GetInterface(IID, Obj) then
 7     Result := S_OK
 8   else
 9   begin
10     aFactory := StarOfficeFactory.FindFactory(IID);
11     if Assigned(aFactory) then
12     begin
13       aFactory.CreateInstance(IID, Obj);
14       Result := S_OK;
15     end;
16   end;
17 end;

當對一個接口對象進行 as 操作時就會調用 QueryInterface 函數,這是接口的機制

首先會調用默認的GetInterface函數進行接口查詢,GetInterface會從繼承關系中查找接口,當找不到時再從接口工廠中尋找接口工廠

如果找到了就通過相應工廠創建接口實例對象

這就是統一接口調用的原理

回到主程序的窗體創建函數,調用了IStarModuleLoader接口的LoadModulesFromDir函數,該接口函數實現了將當前程序目錄下的模塊全部加載進來

(StarOffice as IStarEventManager).EnumEvent(Self);

則調用了事件管理接口的事件枚舉函數,將所有注冊到事件管理的事件枚舉出來並依此動態創建菜單

這就是DEMO程序的啟動時刻

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved