Author: Max Kleiner
It's more efficient to control Interfaces in a List and ask with QueryInterface()
which objects support an Interface
Answer:
First we need some Interfaces (the same goes also in Kylix, pure Interfaces are
independent from COM, it's a feature of ObjectPascal):
//type
IKiss = interface(IUnknown)
['{19A231B1-269F-45A2-85F1-6D8A629CC53F}']
procedure kiss; stdcall;
end;
ISpeak = interface(IUnknown)
['{B7F6F015-88A6-47AC-9176-87B6E313962D}']
procedure sayHello; stdcall;
end;
//Second the interfaces must be implemented:
TDog = class(TInterfacedObject, ISpeak)
public
procedure sayHello; stdcall;
end;
TFrench = class(TInterfacedObject, ISpeak, IKiss)
public
procedure kiss; stdcall;
procedure sayHello; stdcall;
end;
TEnglish = class(TInterfacedObject, ISpeak)
public
procedure sayHello; stdcall;
end;
//e.g. the dog with
procedure TDog.sayHello;
begin
showmessage('dog is barking wauwau');
end;
Now we add the instances of the interface in the list, using the defined type
TInterfaceList so we are able to ask with QueryInterface if an object supports an
Interface, in our example if a dog as an object can kiss or just sayhello:
1 2 procedure TForm1.btnCollectClick(Sender: TObject);
3 var4 collection: TInterfaceList;
5 i: Integer;
6 aObjspeak: ISpeak;
7 aObjKiss: IKiss;
8 begin9 collection := TinterfaceList.create;
10 try11 with collection do12 begin13 add(TEnglish.create);
14 add(TFrench.create);
15 add(TDog.create);
16 end;
17 for i := 0 to collection.count - 1 do18 begin19 aObjSpeak := collection[i] as ISpeak; //TFrench, TEnglish, TDog20 if aObjSpeak <> nilthen21 aObjSpeak.sayHello;
22 collection[i].queryInterface(IKiss, aObjKiss); //only TFrench23 if aObjKiss <> nilthen24 aObjKiss.kiss;
25 end;
26 finally27 collection.free;
28 end;
29 end;