据说dispinterface就是纯分发接口,未实现IUnknown的
在用连接点的时候,需要给它一个dispinterface的接口,通常就是给它IDispatch接口,但是因为不能实现dispinterface接口,弄得每次QueryInterface的时候要比较GUID,如果是某个dispinterface,就返回对应的IDispatch,而不能使用QueryInterface的默认实现。大家在自己手动使用事件连接点的时候一般怎么干的啊?还有,有没有好一点的办法能够直接将Invoke调用映射到一系列方法上去?Delphi编译器有没有对它的默认实现?
在用连接点的时候,需要给它一个dispinterface的接口,通常就是给它IDispatch接口,但是因为不能实现dispinterface接口,弄得每次QueryInterface的时候要比较GUID,如果是某个dispinterface,就返回对应的IDispatch,而不能使用QueryInterface的默认实现。大家在自己手动使用事件连接点的时候一般怎么干的啊?还有,有没有好一点的办法能够直接将Invoke调用映射到一系列方法上去?Delphi编译器有没有对它的默认实现?
type
IStringsDisp = dispinterface
['{EE05DFE2-5549-11D0-9EA9-0020AF3D82DA}']
property ControlDefault[Index: Integer]: OleVariant dispid 0; default;
function Count: Integer; dispid 1;
property Item[Index: Integer]: OleVariant dispid 2;
procedure Remove(Index: Integer); dispid 3;
procedure Clear; dispid 4;
function Add(Item: OleVariant): Integer; dispid 5;
function _NewEnum: IUnknown; dispid -4;
end;
或许是我语法不懂,貌似TMyObject = class(TObject, IStringsDisp)不行?
Stdvcl;
IDispatch = interface(IUnknown)
['{00020400-0000-0000-C000-000000000046}']
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
end;
其中 2 个方法最为重要, GetIDsOfNames和 Invoke注意 GetIdsOfNames 中参数
Names 是一个 c 数组
DispIDs 实际是一个整形数组
这里面的内容就是 函数名 <--> Disp id 之间的关系现在是 Invoke 参数, 跟上面很有关系
DispId 是用 name 查出来的 Id, 并不支持 Name 调用
... 下面是参数之类换句话说你如果直接知道 DispID 就可以直接调用 Invoke 而不必用 GetIDsOfNames(用函数名称取得 id)
IStringsDisp = dispinterface
['{EE05DFE2-5549-11D0-9EA9-0020AF3D82DA}']
property ControlDefault[Index: Integer]: OleVariant dispid 0; default;
function Count: Integer; dispid 1;
property Item[Index: Integer]: OleVariant dispid 2;
procedure Remove(Index: Integer); dispid 3;
procedure Clear; dispid 4;
function Add(Item: OleVariant): Integer; dispid 5; function _NewEnum: IUnknown; dispid -4;
end;
注意看后面的 dispid xx, 这个实际就是用于调用 Invoke 中 DispId 的参数
很显然, 没实现 IDispatch 的接口是不能用 dispinterface 的
不是很显然的是, dispinterface 实际上并不是接口, 它不能用于实现, dispinterface 只是一个对接口的描述表, 知道了上面的原理后得出, 任何实现了 IDispatch 的接口都可以定义一个 dispinterface 纯描述文件, 任何 IDispatch 实现类都可以 as 成 dispinterface(是不是相同就你自已认定了)实现一个可远程的 stringlist 类只要自已申明并实现一个 IStringList = IDispatch, delphi 实现为 IStringsAdapter, 而不是 IStringsDisp, IStringsDisp 只是描述了 IStringsAdaper 的函数的 disp id