Как проверить, реализует ли класс интерфейс с соблюдением надмножеств?
Я изучаю COM и интерфейсы и имею следующий экспериментальный код:
type
IA = interface(IInterface)
['{C9C5C992-3F67-48C5-B215-7DCE6A61F0E8}']
end;
IB = interface(IA)
['{F1799437-AD12-471B-8716-F1D93D1692FC}']
end;
IC = interface(IB)
['{01780E8C-C47D-468E-8E42-4BFF3F495D51}']
end;
TBO = class(TInterfacedObject, IB)
end;
procedure TForm1.FormCreate(Sender: TObject);
var
x: TBO;
a: IInterface;
begin
x := TBO.Create;
IInterface(x)._AddRef;
if Assigned(TBO.GetInterfaceEntry(IA)) then memo1.lines.add('GetInterfaceEntry IA: OK'); // Why not?
if Assigned(TBO.GetInterfaceEntry(IB)) then memo1.lines.add('GetInterfaceEntry IB: OK');
if Assigned(TBO.GetInterfaceEntry(IC)) then memo1.lines.add('GetInterfaceEntry IC: OK');
if x.QueryInterface(IA, a)=S_OK then memo1.lines.add('QueryInterface TA: OK'); // Why not?
if x.QueryInterface(IB, a)=S_OK then memo1.lines.add('QueryInterface TB: OK');
if x.QueryInterface(IC, a)=S_OK then memo1.lines.add('QueryInterface TC: OK');
if Supports(TBO, IA) then memo1.lines.add('Supports TA: OK'); // Why not?
if Supports(TBO, IB) then memo1.lines.add('Supports TB: OK');
if Supports(TBO, IC) then memo1.lines.add('Supports TC: OK');
if Supports(x, IA, a) then memo1.lines.add('Supports(2) TA: OK'); // Why not?
if Supports(x, IB, a) then memo1.lines.add('Supports(2) TB: OK');
if Supports(x, IC, a) then memo1.lines.add('Supports(2) TC: OK');
end;
Выход:
GetInterfaceEntry IB: OK
QueryInterface TB: OK
Supports TB: OK
Supports(2) TB: OK
Но мне нужно:
GetInterfaceEntry IA: OK
GetInterfaceEntry IB: OK
QueryInterface TA: OK
QueryInterface TB: OK
Supports TA: OK
Supports TB: OK
Supports(2) TA: OK
Supports(2) TB: OK
Я это понимаюIB
это надмножествоIA
из-за наследования интерфейса. В моем понимании, так какTBO
инвентарьIB
, он автоматически реализуетIA
, Но почемуSupports()
, QueryInterface()
, GetInterfaceEntry()
вернуть ложь?
Как я могу запросить, еслиTBO
инвентарьIA
прямо или косвенно, т. е. путем реализации надмножестваIA
? Мне нужны оба, статическая функция класса, какGetInterfaceEntry
и вариант ссылки на динамический объект, такой какQueryInterface
.