程序初始化后,就创建主窗体
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这一幕