Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi AddObject mit einem Interface? (https://www.delphipraxis.net/111755-addobject-mit-einem-interface.html)

angelika81 8. Apr 2008 21:05


AddObject mit einem Interface?
 
Hallo!

Ich habe folgendes Problem:
Bei einer Combobox möchte ich ein paar Einträge hinzufügen, außerdem zu jedem Eintrag ein Objekt abspeichern.
Dies mache ich mit der AddObject-Methode der Combobox, dabei übergebe ich den Typ des Interfaces, welches das Objekt implementiert.

Also:
Delphi-Quellcode:
procedure Eintragen(Objekt: IMyInterface);
begin
  cmbTest.AddObject('Test', Objekt);
end;
Wenn ich das Objekt hinterher wieder herausholen möchte, bekomme ich aber eine AccessViolation:
Delphi-Quellcode:
var
  obj: TObject;
begin
  obj := cmbDatenbank.Items.Objects[cmbDatenbank.ItemIndex];
  if Supports(obj, IMyInterface, dbcs) then <----- Hier scheppert es...!
      dbcs.DoSomething;
end;
Ich schätze, es ist nicht sauber, ein Interface per AddObject zu hinterlegen, weil bei Interfaces der Speicher anders verwaltet wird, richtig?
Was kann ich denn tun? Was haltet ihr davon, wenn ich eine Klasse mache, die das Interface in einer Variablen (sozusagen eine Wrapperklasse) speichert und diese Klasse dann per AddObject in der Combobox speichere?

Ich freue mich auf ein paar Tipps!
Danke, Angelika

mkinzler 8. Apr 2008 21:11

Re: AddObject mit einem Interface?
 
Versuch es mal mit TObject als Typ

semo 8. Apr 2008 21:14

Re: AddObject mit einem Interface?
 
Zitat:

Was haltet ihr davon, wenn ich eine Klasse mache, die das Interface in einer Variablen (sozusagen eine Wrapperklasse) speichert und diese Klasse dann per AddObject in der Combobox speichere?
--> So ähnlich.

Du deklarierst eine neue Klasse, welche das Interface verwendet:
Delphi-Quellcode:
TMyClass = class(IMyInterface)
public
  Name: string;
end;
Dann kannst du bequem deine Objekte verwalten:
Delphi-Quellcode:
procedure Eintragen(Objekt: TMyClass);
begin
  if Assigned(Objekt) then
    cmbTest.AddObject(Objekt.Name, Objekt);
end;

Apollonius 8. Apr 2008 21:20

Re: AddObject mit einem Interface?
 
Das funktioniert doch nicht. Was soll sie denn machen, falls die Interfaces von einer anderen Klasse stammen?

Wenn du es gerne sauber hast, solltest du es so machen, wie du es selbst vorgeschlagen hast, eine Klasse mit entsprechender Membervariable. Oder du kannst manuell mit _AddRef- und _Release-Aufrufen die Referenzzählung austricksen und einfach nach TObject casten.

Hansa 8. Apr 2008 23:41

Re: AddObject mit einem Interface?
 
Ich wundere mich immer wieder, woher die Kerle hellsehen können. :lol: Wo wird die Prozedur "Eintragen" definiert ? Wie heißt die, wo der Fehler auftaucht (Kopf fehlt) ? Dann wundert mich etwas die Kenntnis der Objects-Eigenschaft. Die ist nämlich weitgehend unbekannt. Wie sieht das konkrete TObject denn überhaupt aus ? Rest : siehe mkinzler.

xaromz 8. Apr 2008 23:53

Re: AddObject mit einem Interface?
 
Hallo,

das Ganze ist eigentlich ziemlich einfach (aber mit einigen Schweinereien verbunden):
Delphi-Quellcode:
procedure Eintragen(Objekt: IMyInterface);
begin
  cmbTest.AddObject('Test', Pointer(Objekt));
end;
Delphi-Quellcode:
var
  Intf: IInterface;
begin
  Intf := IInterface(Pointer(cmbDatenbank.Items.Objects[cmbDatenbank.ItemIndex]);
  if Supports(Intf, IMyInterface, dbcs) then
    dbcs.DoSomething;
end;
Man sollte aber beachten, dass dabei die Referenzzählung den Bach runter geht.

Gruß
xaromz

Hansa 9. Apr 2008 00:05

Re: AddObject mit einem Interface?
 
Der nächste Hellseher. 8) Was muss in das TInterface rein ??? Du willst doch offensichtlich irgendwelche zusätzlichen Informationen in der ComboBox haben, oder nicht ??

gmc616 9. Apr 2008 01:18

Re: AddObject mit einem Interface?
 
Zitat:

Zitat von angelika81
Bei einer Combobox möchte ich ein paar Einträge hinzufügen, außerdem zu jedem Eintrag ein Objekt abspeichern.
Dies mache ich mit der AddObject-Methode der Combobox, dabei übergebe ich den Typ des Interfaces, welches das Objekt implementiert.

Wieso nur "den Typen des Interfaces, welches das Objekt implementiert" und nicht das Objekt ansich?
Schließlich erwartet AddObject auch ein TObject und kein TInterface. :gruebel:

xaromz 9. Apr 2008 08:23

Re: AddObject mit einem Interface?
 
Hallo,
Zitat:

Zitat von Hansa
Der nächste Hellseher. 8) Was muss in das TInterface rein ??? Du willst doch offensichtlich irgendwelche zusätzlichen Informationen in der ComboBox haben, oder nicht ??

Was soll der Kommentar? Es ist offensichtlich, dass hier an irgendwelche TStrings Interfaces gebunden werden sollen. Das macht mein Code. Also was willst Du?

Gruß
xaromz

shmia 9. Apr 2008 10:02

Re: AddObject mit einem Interface?
 
Da muss man etwas tricksen:
Delphi-Quellcode:
procedure Eintragen(IntPtr: IMyInterface);
begin
  IntPtr._AddRef; // Referenzzählung "austricksen"
  cmbTest.AddObject('Test', TObject(IntPtr));
end;
Würde man nicht mit AddRef eingreifen, kann es passieren, dass das Objekt auf den der Interfacezeiger verweist,
automatisch freigegeben wird. (=> Access Violation)

Beim löschen ist dann ebenfalls eine Korrektur nötig:
Delphi-Quellcode:
var
   p :Pointer;
begin
   p := Pointer(stringliste.Objects[i]);
   if Assigned(p) then
      IUnknown(p)._Release;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:06 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz