| protected
end;
const
Class_Accemp: TGUID = ''''{561FA61C-A985-4F70-8B5A-DF40BA9A7ED8}'''';
implementation
uses ComServ;
initialization
TComObjectFactory.Create(ComServer, TAccemp, Class_Accemp,
''''Accemp'''', ''''实例分析'''', ciMultiInstance, tmApartment);
end.
我们对以上的代码作一个简短的分析:
Taccemp 是一个产生的类。回忆一下,在向导中我们指定Accemp为类名,Delphi自动的加入“T”。
Class_Accemp常量是一个代表COM服务器的GUID。服务器中实现的每个接口都会有自己的一个GUID;
单元的初始化部分包括一个单一却复杂的构造函数调用。这个调用建立了负责创建Taccemp COM对象的类厂。
TcomObjectFactory.Create在ComObj.Pas中定义如下:
constructor TComObjectFactory.Create(ComServer: TComServerObject;
ComClass: TComClass; const ClassID: TGUID; const ClassName,
Description: string; Instancing: TClassInstancing;
ThreadingModel: TThreadingModel);
begin
IsMultiThread := IsMultiThread or (ThreadingModel <> tmSingle);
if ThreadingModel in [tmFree, tmBoth] then
CoInitFlags := COINIT_MULTITHREADED else
if (ThreadingModel = tmApartment) and (CoInitFlags <> COINIT_MULTITHREADED) then
CoInitFlags := COINIT_APARTMENTTHREADED;
ComClassManager.AddObjectFactory(Self);
FComServer := ComServer;
FComClass := ComClass;
FClassID := ClassID;
FClassName := ClassName;
FDescription := Description;
FInstancing := Instancing;
FErrorIID := IUnknown;
FShowErrors := True;
FThreadingModel := ThreadingModel;
FRegister := -1;
end;
结合参数来理解这个过程。
在99%的情况下,用户简单地传递作为参数COMServer的全局ComServer对象。
第二个参数ComClass接受将由类厂创建的类。在此实例中,相要此类厂创建Taccemp实例。
第三个参数ClassID获得分配给Taccemp类的GUID。既Class_Accemp;
接下来,传递类名Accemp和类的描述Description。
Instancing参数仅应用于进程外COM服务器。在此可以忽略。
Delphi的COM对象向导填入了默认值ciMultiInstance。
最后一个参数接受一个表示线程模型的值,该模型由此对象支持。而以上所介始的各个参数都可以根据它的实现代码进行参考。其实,它的实现过程更多的就是将上边所列出的参数进行位置对应。这个过程留给读者朋友们分析。当然,即使对它的内部不是很了解,也无大碍。
由上边的描述,我们来分析一下:
TComObjectFactory.Create(ComServer, TAccemp, Class_Accemp,
''''Accemp'''', ''''实例分析'''', ciMultiInstance, tmApartment);
创建一个COM对象Taccemp的实例Accemp,其GUID是Class_Accemp所代表的常量描述为’实例分析’,支持多线程。
COM对象离不开接口,只有通过接口才可以将COM对象提供的服务真零点切切的被客户端去调用,接下来,我们需要进行接口的代码填充,因为要实现登录和算法的简单实现过程,按照前边所提及的,如果两个联系不是很密切的功能我们尽量放在不同的接口中,立求接口的相对独立性,其实,实际中的情况也是如此。因为接口有不变性。负责登录的接口我们仅仅需要实现两个功能于同一个接口中,如下:
IAccIntf = Interface
[''''{ADDFAFFE-32D0-474F-909C-155E3906F0D1}'''']
Function GetLogn(UserName , UserPass : String) : Boolean;
Function GetSysTime : String;
end;
再此,笔者再次提醒,GUID应该在每个接口声明时都需要创建,假设此处将不进行接口的创建,在后边的接口分离中会出现“不支持接口”的错误提示信息,不必担心GUID会被用完,纵然再有几百年也用不完我们现有的GUID。不要想着Copy – Paster GUID;
{Delphi中,Shift + Ctrl + G 可以产生一个唯一的GUID}
上一页 [1] [2] [3] [4] 下一页 |