Delphi生成的ActiveX创建模板的研究--Com对象是如何创建的

Delphi 生成的XXX_TLB.pas文件中生成了一个类

TActiveFormX = class(TOleObject)

end;

另外在XXX_Impl.pas文件中同样生成了一个类:TActiveFormX,经过研究,这两个类的确是
一个是接口,一个是实现类。

前者TActiveFormX从TOleObject继承,并且实现了方法:

procedure TActiveFormX.InitControlData;
const
CEventDispIDs: array [0..8] of DWORD = (
$000000C9, $000000CA, $000000CB, $000000CC, $000000CD, $000000CE,
$000000CF, $000000D0, $000000D1);
CTFontIDs: array [0..0] of DWORD = (
$FFFFFE00);
CControlData: TControlData2 = (
ClassID: ‘{B90C2778-2158-48F5-A279-3A52BA87B423}’;
EventIID: ‘{8791E2BA-D57D-4CC9-91DA-81403D4E1144}’;
EventCount: 9;
EventDispIDs: @CEventDispIDs;
LicenseKey: nil (*HR:$80040154*);
Flags: $0000001D;
Version: 401;
FontCount: 1;
FontIDs: @CTFontIDs);
begin
ControlData := @CControlData;
TControlData2(CControlData).FirstEventOfs := Cardinal(@@FOnActivate) – Cardinal(Self);
end;

该方法负责定义这个OLE控件的类ID,事件接口ID,在TOleObject的方法TOleControl.createInstance中
则利用到了这些注册信息,创建COM对象:

procedure TOleControl.createInstance;
var
ClassFactory2: IClassFactory2;
LicKeyStr: WideString;

procedure LicenseCheck(Status: HResult; const Ident: string);
begin
if Status = CLASS_E_NOTLICENSED then
raise EOleError.createFmt(Ident, [ClassName]);
OleCheck(Status);
end;

begin
if not (csDesigning in ComponentState) and
(FControlData^.LicenseKey <> nil) then
begin
//创建COM对象,其中FControlData^.ClassID为子类定义的COM对象的ID
OleCheck(CoGetClassObject(FControlData^.ClassID, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, nil, IClassFactory2, ClassFactory2));
LicKeyStr := PWideChar(FControlData^.LicenseKey);
LicenseCheck(ClassFactory2.cr&#101;ateInstanceLic(nil, nil, IOleObject,
LicKeyStr, FOleObject), SInvalidLicense);
end else
LicenseCheck(Cocr&#101;ateInstance(FControlData^.ClassID, nil,
CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IOleObject,
FOleObject), SNotLicensed);
end;

COM对象的实现单元XXX_Impl.pas则定义了该COM对象的实现,并且创建了一个TActiveXControlFactory,
用于生成该COM对象:

initialization
TActiveFormFactory.cr&#101;ate(
ComServer,
TActiveFormControl,
TActiveFormX,
Class_ActiveFormX,
1,
”,
OLEMISC_SIMPLEFRAME or OLEMISC_ACTSlik&#101;LABEL,
tmApartment);
end.

因此前一个TActiveXForm 被称为OLEProxy,即Ole的调用网关。

COM系统CocreateInstance(IID)的时候会请求相应的TActiveFormFactory调用相应的createIntance方法。

913 次阅读

发表评论

电子邮件地址不会被公开。 必填项已用*标注