AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

TVirtualStringTree AddChild access violation

Ein Thema von EricMeyer · begonnen am 28. Nov 2019 · letzter Beitrag vom 9. Dez 2019
Antwort Antwort
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#1

AW: TVirtualStringTree AddChild access violation

  Alt 28. Nov 2019, 18:29
Wenn ich du wäre würde ich das alles noch einmal komplett umschreiben.
AddChild benutzt man nicht!

Man fügt Nodes über RootNodeCount hinzu und einer Liste mit Klasseninstanzen.
  Mit Zitat antworten Zitat
EricMeyer

Registriert seit: 31. Mai 2012
Ort: Berlin
23 Beiträge
 
#2

AW: TVirtualStringTree AddChild access violation

  Alt 28. Nov 2019, 19:03
Bin nur diesem Tutorial gefolgt: http://www.soft-gems.net/supplement/download.php?ID=79

Aber dann lese ich mich mal in RootNodeCount ein. Danke dafür!
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#3

AW: TVirtualStringTree AddChild access violation

  Alt 28. Nov 2019, 19:18
Ganz grob also:

du hast eine Klasse mit Proberties und Informationen von allem was du so sin deinen Baum brauchst.
Davon erzeugst du Instanzen und packst die in eine Liste. RootNodeCount ist so groß wie deine Liste groß ist.
In Den VST Events greifst du jetzt auf diese Liste zu.
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.291 Beiträge
 
Delphi 12 Athens
 
#4

AW: TVirtualStringTree AddChild access violation

  Alt 9. Dez 2019, 07:14
Wenn ich du wäre würde ich das alles noch einmal komplett umschreiben.
AddChild benutzt man nicht!

Man fügt Nodes über RootNodeCount hinzu und einer Liste mit Klasseninstanzen.
Das wird seit Jahren immer wieder erzählt. Ich benutze den VST als vollständigen Ersatz für den Standard-TTreeView. Den nutze ich gar nicht mehr. In Szenarien, wo man kleine Bäume hat mit ~ 100 Nodes, arbeitet es sich mit AddChild wesentlich eleganter als mit über zig Events verteilten Initialisierungen. Selbst bei 10.000 Nodes fällt auf modernen Rechnern der Laufzeitunterschied kaum mehr ins Gewicht, besonders wenn man BeginUpdate und EndUpdate drumherum macht.

Der VST entstand IMHO zu Zeiten von Delphi 4 und Pentium-Prozessoren mit 90 MHz Takt. Da war der Unterschied zum TTreeView noch gewaltig, selbst bei kleineren Bäumen.

Klar kannst du mit GetTickCount messen, dass zwischen einer AddChild-Schleife und einer RootNodeCount-Zuweisung soundsoviel Millisekunden Unterschied liegen. Aber das ist Jammern auf hohem Niveau. Im vorliegenden Fall dürfte ohnehin das Auslesen der Datenträgerinfos zum Flaschenhals werden und nicht das Initialisieren vom Tree.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#5

AW: TVirtualStringTree AddChild access violation

  Alt 9. Dez 2019, 08:49
Das wird seit Jahren immer wieder erzählt
Das wird erzählt, weil man die Daten im besten Fall in einer Liste speichert. In dem Beispiel hier unten, was ich von oben kopiert habe, wird nichts in einer Liste gespeichert
Delphi-Quellcode:
function TFrameTreeView.CreateFirstNode(Adir : string):PVirtualNode ;
var
  LFirstNode : PVirtualNode;
  LData : PTreeData;
begin
   LFirstNode := TreeView2.AddChild(nil);
   LData := TreeView2.GetnodeData(LFirstNode);
   LData^.FFirstFolder := True;
   LData^.FPath := ADir;
   LData^.FFolderName := Adir;
   TreeView2.NodeDataSize := SizeOf(TTreeData);
   TreeView2.ValidateNode(LFirstNode, False);
   Result := LFirstNode;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.291 Beiträge
 
Delphi 12 Athens
 
#6

AW: TVirtualStringTree AddChild access violation

  Alt 9. Dez 2019, 09:21
Das wird erzählt, weil man die Daten im besten Fall in einer Liste speichert.
Was ich damit sagen will: Es gibt Fälle, wo die Erzeugung und Verwaltung einer Liste nur Overhead produziert, aber keinen Mehrwert. Der klassische Anwendungsfall vom VST waren dynamisch erzeugte Records. Der VST verwaltete Zeiger darauf, die Nodes im Baum waren in sich selbst eine Liste. Die einzelnen Records kann man z.B. auch per Zeiger verketten. In dem Fall nützt dir eine Liste herzlich wenig. Deshalb würde ich nicht vom "besten Fall" sprechen. Vielmehr muss man sich fallspezifisch damit auseinander setzen, was Sinn macht und was nicht.

Im vorliegenden Fall hast du eine Dateisystem-Struktur. Willst du jetzt für jeden Ordner, jedes Laufwerk und jeden Symlink ein extra Objekt instantiieren und in einer ObjectList verwalten, nur damit du dir ein bisschen Arbeit beim Freenode sparen kannst?

Ich möchte am Beispiel des Erstposters dezent darauf hinweisen, dass ein TSearchRec bereit ein Record ist. Warum nicht den gleich an den Node beppen, wenn er denn schon mal da ist? Subnodes würde ich gar nicht initial mit erzeugen sondern erst on-demand wenn der Anwender einen Ordner-Node aufklappt. So macht das auch der Explorer. Sonst würde das Öffnen auf einer normalen Windows-Installation ja jedesmal 5 Minuten dauern, weil ein komplettes rekursives Listing gemacht werden müsste

@EricMeyer: Die Zugriffsverletzung in deinem Codebeispiel kommt daher, dass du zuerst versuchst, den Node zu erzeugen und danach erst NodeDataSize zuweist. NodeDataSize brauchst du in deinem Fall nur ein einziges Mal zuweisen und zwar bevor du überhaupt in deine Repeat-Schleife gehst. Der Hinweis mit dem TTreeData statt PTreeData war übrigens richtig. Man kann übrigens auch völlig verschiedene Records innerhalb des selben VST benützen. Deshalb speichert jeder PVirtualNode die NodeDataSize auch separat. Für solche Fälle gibt es das Event OnGetNodeDataSize, das z.B. von der Methode GetNodeData aufgerufen wird.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden

Geändert von Codehunter ( 9. Dez 2019 um 09:29 Uhr)
  Mit Zitat antworten Zitat
EricMeyer

Registriert seit: 31. Mai 2012
Ort: Berlin
23 Beiträge
 
#7

AW: TVirtualStringTree AddChild access violation

  Alt 9. Dez 2019, 10:20
  TreeView2.NodeDataSize := SizeOf(PTreeData); natürlich muss hier TTreeData rein. Sorry ich hatte rumgespielt mit diesem Punkt, um zu schauen, ob es daran liegt und es dann falsch zurück verbessert.

Und dank des Tipps hier, habe ich herausgefunden woran es lag. Die Zeile
  TreeView2.NodeDataSize := SizeOf(TTreeData); habe ich noch vor das Beginupdate des Treeviews gesetzt und dann lief es.

Und jetzt macht auch alles Sinn. Es ist abgeschmiert, als ich zum Parent zurückgekommen bin. Der hatte seine Daten verloren. Ich finde es immer noch etwas seltsam, dass der Parent in der ersten Iteration funktioniert hat, dann aber später, als er von tieferen Rekursionen zurück zur obersten gekommen ist, nicht mehr. Es erklärt auch, warum der Node assigned war, nur eben die Daten nicht. Dennoch denke ich mir, eigentlich müsste er doch dann beim Zugriff auf die Daten und nicht beim addchildnode abschmieren. Weil der ursprüngliche Speicherplatz des Nodes doch mindestens ausreichen müsste, damit der Node selbst erkannt wird. Aber ich kenne mich mit Pointern nicht genug aus.

Trotzdem vielen Dank!
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.416 Beiträge
 
Delphi XE5 Professional
 
#8

AW: TVirtualStringTree AddChild access violation

  Alt 9. Dez 2019, 14:16
 TreeView2.NodeDataSize := SizeOf(TTreeData); Das solltest du nach der Formular-Erzeugung einmalig machen.
z.B. im Form.OnCreate
Am besten bevor du irgend etwas anderes im Baum anstellst.
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:42 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