Delphi 信息化管理系统开源框架 @ 启动时刻

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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程序的启动时刻

以上是关于Delphi 信息化管理系统开源框架 @ 启动时刻的主要内容,如果未能解决你的问题,请参考以下文章

delphi开源问题编译

翻译在GitHub上通过星级评估排名前10的最受欢迎的开源Delphi项目

浅析Delphi Container库(有开源的DCLX)

delphi 如何让Combobox下拉菜单时,显示一个树形结构

Delphi 框架关闭形式

开源分布式任务调度工具,和你一起记住生命中每一个重要的时刻