2004. május 3., hétfő

Add Interfaces to a List


Problem/Question/Abstract:

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:

procedure TForm1.btnCollectClick(Sender: TObject);
var
  collection: TInterfaceList;
  i: Integer;
  aObjspeak: ISpeak;
  aObjKiss: IKiss;
begin
  collection := TinterfaceList.create;
  try
    with collection do
    begin
      add(TEnglish.create);
      add(TFrench.create);
      add(TDog.create);
    end;
    for i := 0 to collection.count - 1 do
    begin
      aObjSpeak := collection[i] as ISpeak; //TFrench, TEnglish, TDog
      if aObjSpeak <> nil then
        aObjSpeak.sayHello;
      collection[i].queryInterface(IKiss, aObjKiss); //only TFrench
      if aObjKiss <> nil then
        aObjKiss.kiss;
    end;
  finally
    collection.free;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése