程序初始化后,就创建主窗体
procedure TMain.FormCreate(Sender: TObject); begin TObjFactoryEx.Create([IMainForm,IFormMgr],self); SetSysSkin(dxSkinController); if not LoadSysModule then exit; LoadUserModule; if not Sys.Login.Login then begin Application.ShowMainForm:=False; Application.Terminate; end; Sys.ERPInit.InitSYS; Sys.ERPInit.InitMenu(dxBarManager); CloseSplash; BringToFront; End;
主窗体创建时做了以下事情
1.通过实例工厂,将主窗体Self与接口IMainForm,IFormMgr绑定,
这样当访问这两接口时就会调用主窗体里的实现代码,有关类厂将在后期讲解
2.设置系统皮肤
3.加载系统模块和用户模块,这里进行了模块管理
4.系统登陆
5.系统初始化(和用户相关)
先说说接口吧,一切从这里开始,先说说一些初学者不好理解的地方
在SysModuleMgr.pas里有一段代码
procedure TTangramModule.UnInstall; var Reg:IRegistry; begin if FModuleCls<>nil then begin Reg:=SysService as IRegistry; FModuleCls.UnRegisterModule(Reg); end; end;
其中 SysService 是TSysService对象
TSysService=Class(TObject,IInterface,ISysService)
与IRegister接口没有任何继承关系,可为什么可以直接 as 呢?
这是因为TSysService重新实现了IInterface接口
function TSysService.QueryInterface(const IID: TGUID; out Obj): HResult; var aFactory:TFactory; begin Result:=E_NOINTERFACE; if self.GetInterface(IID,Obj) then Result:=S_OK else begin aFactory:=FactoryManager.FindFactory(IID); if Assigned(aFactory) then begin aFactory.prepare(FParam); Result:=aFactory.GetIntf(IID,Obj); end; end; end;
查询接口时,会先通过GUID搜索,当搜索不到时会到工厂管理搜索
在这个框架下,接口都会先注册到工厂,这也是为什么任何框架下地模块都可以调用到不同模块的接口
而 as 操作会调用接口查询QueryInterface
所以才有SysService as IRegistry这一幕