![]() |
Object aus TreeView auslesen
Hallo,
ich habe ein Problem beim Anklicken eines Knoten in einem TreeView möchte ich das Object was an TreeView.Data hängt wieder auslesen. Nun ist es egal welchen Konten ich anklicke, es wird immer im Data das letzte Object zurückgegeben. Woran kann es liegen, was machen ich falsch?
Delphi-Quellcode:
Die Adresse in Data ist immer die gleiche.
procedure TForm1.TreeView1Click(Sender: TObject);
var MSBez3: TMSV1; strTest: string; Index: integer; begin MSBez3:= TMSV1.Create; MSBez3:= TMSV1(TreeView1.Selected.Data); // <---- Es wird immer das letzte Object zurückgegeben?! If msBez3 <> NIL then begin ShowMessage(MSBez3.MaNr+MSBez3.MSNr+MSBez3.MaInhalt+TreeView1.Selected.Text); end; end; Mit
Delphi-Quellcode:
wird der richtige Text vom angeklickten Knoten zurückgegeben!
TreeView1.Selected.Text
Bis bald Chemiker |
Re: Object aus TreeView auslesen
Hallo,
abgesehen davon, dass TMSV1.Create im gezeigten Code ein Speicherloch produziert, vermute ich die Fehlerursache eher dort, wo du die property Data initialisierst. Vielleicht solltest du erstmal überprüfen, ob die in Data abgelegten Zeiger sich wirklich unterscheiden. Freundliche Grüße |
Re: Object aus TreeView auslesen
Hallo marabu,
Die in 'Daten' abgespeicherten Daten unterscheiden sich. So werden die Objecte im TreeView gespeichert.
Delphi-Quellcode:
Der Zeiger beim Anklicken der Knoten von Data ist immer gleich.
for I := 1 to Anzahl do
begin MSBez.MSLesen:= i; For z:=0 to TreeView1.Items.Count -1 do begin if (TreeView1.Items[z].Text = MSBez.MaBez) then begin if (NOT (IsDuplicateEintrag(m_Ebene4, MSBez.MaNr+MSBez.MSNr,TRUE))) then begin Daten:= TMSV1.Create; Daten:= MSBez; m_Ebene4:= TreeView1.Items.AddChildObject(TreeView1.Items[z], MSBez.MaNr+MSBez.MSNr, Daten); {m_Ebene4.StateIndex:=3; } // MS nicht aktiv if MSBez.MSAktiv then begin m_Ebene4.StateIndex:= 4; end else begin m_Ebene4.StateIndex:= 3; end; If MSBez.DarstellungsArt= 2 then begin m_Ebene4.ImageIndex := 2; end else begin m_Ebene4.ImageIndex:= 1; end; end; end; end; Bis bals Chemiker |
Re: Object aus TreeView auslesen
Zeile 10+11:
Delphi-Quellcode:
verursacht, dass für jeden Knoten das gleiche Objekt angehängt wird. Dabei wird ja nur der Pointer gesetzt, d.h. wenn du in der Instanz des Objektes ein Attribut änderst, so wird das in allen Knoten eben genauso wiedergespiegelt.
Daten:= TMSV1.Create;
Daten:= MSBez; |
Re: Object aus TreeView auslesen
Hallo Jelly,
und wie kann ich das ändern? Bis bald Chemiker |
Re: Object aus TreeView auslesen
Indem Du dir klar machst, was ein Pointer ist :wink:
Ein Objekt, zumindest so wie es in Delphi angesprochen, ist ein 4 Byte grosser Speicherbereich, der lediglich auf den Speicherplatz verweist, wo deine Objektdaten abgelegt sind. Jetzt kannst Du natürlich 2 Variablen anlegen, die auf ein und die gleiche Objektinstanz verweisen. Das Ändern von Attributen bewirkt dann natürlich das Ändern in der gleichen Instanz, egal über welche Variable du zugreifst. Beispiel:
Delphi-Quellcode:
Ich das das sollte als Hinweis genug sein, damit Du dein Problem in den Griff kriegst. Du musst eben dafür Sorgen, dass Du unterschiedliche Objekte in den Data-Pointer reinpackst.
type
TTest = class public AnyText : string ; end ; implementation procedure TForm1.foo ; var T1, T2 : TTest ; begin T1 := TTest.Create ; T2 := T1 ; T1.AnyText := 'Jelly' ; showmessage (T2.AnyText) ; // Gibt Jelly aus end ; end. |
Re: Object aus TreeView auslesen
Den Create kannst du dir schon mal sparen.
Das Objekt ist ja in Data vorhanden !!! Bist du dir sicher das die Objekte zu diesen Zeitpunkt noch da sind ??? Wo erzeugst du sie ??? |
Re: Object aus TreeView auslesen
Hab gerade nochmal was nachgelesen :
Daten:= TMSV1.Create; // (1) Daten:= MSBez; Zeile (1) kannst du dir wirklich sparen. Du erzeugst ein Objekt Daten und dann setzt du Daten auf MsBez. Wie willst du jemals wieder auf das mit TMSV1.Create erzeugte Objekt zugreifen ???? |
Re: Object aus TreeView auslesen
Hallo,
jetzt funktioniert es, ich habe beim ersten Versuch übersehen das nur ein Zeiger übergeben wird und so wurden nur vom letzten Object die Daten angezeigt.
Delphi-Quellcode:
Um die Daten anzuzeigen gehe ich nun so vor:
for I := 1 to Anzahl do
begin MSBez.MSLesen:= i; For z:=0 to TreeView1.Items.Count -1 do begin if (TreeView1.Items[z].Text = MSBez.MaBez) then begin if (NOT (IsDuplicateEintrag(m_Ebene4, MSBez.MaNr+MSBez.MSNr,TRUE))) then begin Daten:= TMSV1.Create; // Daten von MSBez in Daten übertragen. with MSBez do begin Daten.MSDateiName:= MSDateiName; Daten.MaInhalt:= MaInhalt; Daten.MaInhaltDichte:= MaInhaltDichte; Daten.MSMECode:= MSMECode; Daten.MSBeschr:= MSBeschr; Daten.MaBez:= MaBez; Daten.MSMessBereichMin:= MSMessBereichMin; Daten.MSMessBereichMax:= MSMessBereichMax; Daten.MSMessMaxAenderung:= MSMessMaxAenderung; Daten.MSMessMinAenderung:= MSMessMinAenderung; Daten.MaGruppe1:= MaGruppe1; Daten.MaGruppe2:= MaGruppe2; Daten.DarstellungsArt:= DarstellungsArt; Daten.MaNr:= MaNr; Daten.MSNr:= MSNr; { Daten.MSId:= MSId; } Daten.MSAktiv:= MSAktiv; Daten.MSGeloescht:= MSGeloescht; end; m_Ebene4:= TreeView1.Items.AddChildObject(TreeView1.Items[z], MSBez.MaNr+MSBez.MSNr, Daten); if MSBez.MSAktiv then begin m_Ebene4.StateIndex:= 4; end else begin m_Ebene4.StateIndex:= 3; end; If MSBez.DarstellungsArt= 2 then begin m_Ebene4.ImageIndex := 2; end else begin m_Ebene4.ImageIndex:= 1; end; end; end; end;
Delphi-Quellcode:
procedure TForm1.TreeView1Click(Sender: TObject);
var MSBez3: TMSV1; strTest: string; Index: integer; begin MSBez3:= TMSV1.Create(); MSBez3:= TreeView1.Selected.Data; if MSBez3 <> NIL then begin MSBez:= MSBez3; Button2Click (self); end; end; Jetzt habe ich noch eine Frage bezüglich der Freigabe des Speichers der Daten von Data von TreeView, geschieht dies automatisch? Und wie kann man feststellen, dass man Speicherlöscher produziert oder nicht. |
Re: Object aus TreeView auslesen
Hallo,
im Ereignis OnDeletion() der TreeView kannst du deine Objekte wieder freigeben. Freundliche Grüße |
Re: Object aus TreeView auslesen
Hallo marabu,
haben Deinen Vorschlag aufgegriffen aber der Compiler meldet dann ‚Ungültiger Index’.
Delphi-Quellcode:
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
var z: integer; begin // Speicher wieder aufräumen! For z:=TreeView1.Items.Count-1 downto 0 do begin dispose(TreeView1.Items[z].data); end; end; Wie kann man feststellen, ob eine Anwendung Speicherlöscher hinterlässt? Kannst Du mir da einen Tipp geben. Hilft da einem der Debugger weiter und sagt das Object xyz ist noch nicht freigeben. Vielen Dank an alle, die mir schon weiter geholfen haben. Bis bald Chemiker |
Re: Object aus TreeView auslesen
Hallo Chemiker,
in dem Ereignis darfst du nur den Speicher des Knoten freigeben, der dir als Parameter übergeben wird. Speicherlöcher kannst du z.B. mit ![]() Freundliche Grüße |
Re: Object aus TreeView auslesen
Hallo marabu,
danke für die schnelle Antwort.
Delphi-Quellcode:
Werde mich mal mit dem Programm 'MemCheck' beschäftigen.
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
var z: integer; begin // Speicher wieder aufräumen! Node.delete; end; Zum Abschluss noch eine Frage. Wenn die Anwendung beendet wird, wird dann der Speicher auch freigegeben der innerhalb der Anwendung nicht ordnungsgemäß freigegeben worden ist? Bis bald Chemiker |
Re: Object aus TreeView auslesen
In der Regel ja. Das ist wie beim Fliegen: Runter kommen sie alle. Was mich an eine Anekdote vom Frankfurter Flughafen erinnert:
Auf der Besucherterasse des Flughafens hat mal ein älteres Fräulein den Erklärungen zur Problematik von Warteschleifen gelauscht und nach heftigem Sinnieren aufgeregt gefragt, was passiere, wenn einem Flieger beim Warten der Treibstoff ausgehe. Der PR-Mann hat kurz nachgedacht und ihr dann bestätigt, dass ein solcher Fall sehr tragisch sei, weil Crew und Passagiere dann mitunter mehrere Tage in der Warteschleife feststecken, bis man sie retten könne. Übrigens: Ich hatte mit etwas ähnlichem wie TObject(Node.Data).Free gerechnet, nicht mit Node.Delete! Gelöscht wird der Knoten ja in diesem Augenblick gerade, sonst würde das Ereignis nicht feuern. Und der Speicherplatz des mit Create erzeugten Object, welches in Node.Data abgelegt wurde, wird durch Node.Delete nicht wieder freigegeben. Gibt es da keine Zugriffsfehler? Gute Nacht |
Re: Object aus TreeView auslesen
Hallo marabu,
nein der Compiler meckert nicht. Wenn der Knoten gelöscht ist, ist doch auch der Zeiger von Data gelöscht oder? Ich muss mir morgen das ganze noch einmal genau ansehen. Bis bald Chemiker |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz