程序初始化后,就创建主窗体
procedure TMain.FormCreate(Sender: TObject);
beginTObjFactoryEx.Create([IMainForm,IFormMgr],self);SetSysSkin(dxSkinController);if not LoadSysModule then exit;LoadUserModule;if not Sys.Login.Login thenbeginApplication.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;
beginif FModuleCls<>nil thenbeginReg:=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;
beginResult:=E_NOINTERFACE;if self.GetInterface(IID,Obj) thenResult:=S_OKelse beginaFactory:=FactoryManager.FindFactory(IID);if Assigned(aFactory) thenbeginaFactory.prepare(FParam);Result:=aFactory.GetIntf(IID,Obj);end;end;
end;
查询接口时,会先通过GUID搜索,当搜索不到时会到工厂管理搜索
在这个框架下,接口都会先注册到工厂,这也是为什么任何框架下地模块都可以调用到不同模块的接口
而 as 操作会调用接口查询QueryInterface
所以才有SysService as IRegistry这一幕