AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Nodes einer VirtualStringTree hinzufügen - aber schneller!
Thema durchsuchen
Ansicht
Themen-Optionen

Nodes einer VirtualStringTree hinzufügen - aber schneller!

Ein Thema von Jim Carrey · begonnen am 5. Okt 2016 · letzter Beitrag vom 6. Okt 2016
Antwort Antwort
Seite 4 von 6   « Erste     234 56      
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#31

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 12:54
Ich sehe gerade, dass ich das Projekt im Release Build hochgeladen habe. Habe die Buildkonfiguration nicht umgestellt. Daher funktionieren wohl auch die Breakpoints nicht (wie ich bereits in einem der vorherigen Beiträge erwähnt hatte).

Stell mal die Konfiguration um indem du in der Projektverwaltung die Build-Konfiguration öffnest und dann doppelt auf Debug klickst. Siehe Bild im Anhang. Wenn Sie aktiv ist, dann wird sie fett markiert.

Aviator, ich glaube ich bleibe lieber bei meiner standard-Variante. Ich bekomme deine Version nicht zum Laufen.

Im VSTGetText steht einzig und allein
Delphi-Quellcode:
var
 Data: PTreeData;
begin
 Data := VST.GetNodeData(Node);

 case Column of
  0: ShowMessage(Data^.sFileName);
 end;
Das führt zu einer Zugriffsverletzung.
Auf die ObjectList kann ich auch nicht zugreifen, da er dann meckert dass Integer und TreeData nicht zusammenpassen.
Mit meiner Standard-Methode müsste aber doch eigentlich auch der Speicher freigegeben werden. NodeFree wird doch aufgerufe, ich verstehe das nicht.
Nicht so schnell aufgeben. Das ist als Programmierer sehr schlecht. Wenn du meine Version kompilierst, bekommst du dann irgendwelche Fehlermeldungen? Wenn ja, welche? Kopier die mal und poste die hier.

Wenn die funktioniert, dann poste mal deine komplette Unit in der du den VST verwendest. Ich glaube das wäre dann einfacher wenn wir hier zusammen mal drüber schauen. Generics sollten kein Problem machen, da die auch in XE3 schon existierten.

Ich kompiliere mal parallel noch mit XE3. Die Version habe ich zufällig gerade zur Hand. Ich schaue mal, ob das bei mir fehlerfrei funktioniert. Wenn nicht, dann suche ich den Fehler bei mir und berichte.

EDIT: Also mit XE3 lässt sich mein Projekt so wie ich es hochgeladen habe problemlos kompilieren. Funktioniert das denn bei dir? Wenn das funktioniert, dann können wir zum nächsten Schritt gehen der dann wäre, dass du uns die Fehlermeldungen und den SourceCode postest.
Miniaturansicht angehängter Grafiken
buildconfig.png  

Geändert von Aviator ( 6. Okt 2016 um 13:09 Uhr)
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#32

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 13:16
Ich kann es zwar jetzt kompilieren aber ich verstehe noch immer etwas nicht.

Einmal steht in GetText:
Delphi-Quellcode:
{$IFDEF WITHCARDINAL}
   CellText := FMyDataClasses[NodeData^].Name;
{$ELSE}
   CellText := NodeData^.Name;
{$ENDIF}
Und ein anderes mal in InitChildren:
Delphi-Quellcode:
{$IFDEF WITHCARDINAL}
 NodeData^ := Node^.Index;
{$ELSE}
 NodeData^ := FMyDataClasses[Node^.Index];
{$ENDIF}
WITHCARDINAL ist also vertauscht. Was ist das richtige?
Ich bin wieder zu meiner alten Version umgestiegen und gucke mal wie ich deine bei mir einbauen kann.
Ich verstehe einfach nicht, wieso der Speicher nicht freigegeben wird OBWOHL er in FreeNode einsteigt.
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#33

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 13:32
Ich kann es zwar jetzt kompilieren aber ich verstehe noch immer etwas nicht.

Einmal steht in GetText:
Delphi-Quellcode:
{$IFDEF WITHCARDINAL}
   CellText := FMyDataClasses[NodeData^].Name;
{$ELSE}
   CellText := NodeData^.Name;
{$ENDIF}
Und ein anderes mal in InitChildren:
Delphi-Quellcode:
{$IFDEF WITHCARDINAL}
 NodeData^ := Node^.Index;
{$ELSE}
 NodeData^ := FMyDataClasses[Node^.Index];
{$ENDIF}
WITHCARDINAL ist also vertauscht. Was ist das richtige?
Hallo Jim,

vertauscht ist da nichts. Das ist schon alles richtig so. In der Version WITHCARDINAL habe ich in NodeData^ nur den Index des Objektes in der TObjectList. Folglich muss ich bei GetText auf das Object in der TObjectList mit dem Index NodeData^ zugreifen.

Ich hatte mit den Compilerschaltern nur zeigen wollen, dass man entweder mit einem Index ODER mit einem (Zeiger auf ein) Objekt arbeiten kann. Das war jetzt vielleicht etwas verwirrend. Am besten suchst du dir eine Variante aus und löschst dann alles was nicht dazu gehört. Dann wird aus dem oben gezeigten SourceCode bspw. folgendes:

Ich bleibe jetzt mal bei der Variante mit dem Object. Die ist nachher an allen anderen Stellen im SourceCode wesentlich übersichtlicher.

Delphi-Quellcode:
procedure TForm1.vst1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
var
  NodeData: PMyDataClass;
begin
  if (vst1.GetNodeLevel(Node) = 0) then begin
    NodeData := vst1.GetNodeData(Node);
    CellText := NodeData^.Name;
  end else
    CellText := 'SubItem ' + IntToStr(Node^.Index + 1);
end;

procedure TForm1.vst1InitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
  var InitialStates: TVirtualNodeInitStates);
var
  NodeData: PMyDataClass;
begin
  NodeData := vst1.GetNodeData(Node);

  NodeData^ := FMyDataClasses[Node^.Index];

  if (vst1.GetNodeLevel(Node) = 0) then begin // Nur auf dem ersten NodeLevel Children zulassen
    if (NodeData^.HasChildren) then begin
      Include(InitialStates, ivsHasChildren); // Hier wird im Status der Node vermerkt, dass die Node mindestens 1 ChildNode hat und das + Symbol angezeigt werden soll
    end;
  end;
end;
Im Init wird einmal das Objekt zugewiesen und nachher wird mit Hilfe von NodeData^ immer wieder direkt darauf zugegriffen. Ich hoffe das hier macht es etwas übersichtlicher. Wenn nicht, dann frag nochmal nach. Ich helfe dir gerne. Stand anfangs vor dem selben Problem und hatte mich immer ein Stückchen weiter vorgearbeitet.
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#34

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 14:06
Danke für deine Geduld, jetzt funktioniert es nachdem ich mich noch einmal in Ruhe hingesetzt habe. Wo vorher der Fehler war, weiß ich nicht aber ich denke es war ein ungücklicher Tippfehler.

Ich habe nun folgendes beobachtet.
Der speicher meiner Anwendung geht von 11 MB auf 49 MB hoch, wenn ich meine ListView mit 100000 Einträgen fülle.
Ein anschließendes freigeben der ObjectList (schließen des Formulars, Ende der Routine) lässt den Speicher auf 28 MB sinken.

Bei 10000 Dateien geht der Speicherverbrauch von 11 MB hoch auf 14 MB und beim Ende der Routine geht der Speicher -nicht- runter.
Ich denke mir, die Anwendung behält sich da etwas im Speicher oder ähnliches.

Dein Projekt-Beisiel:
bei 100000 Einträgen geht der Speicher von 3 MB hoch auf 23 MB. Beim Freigeben der ObjectList sinkt der speicherverbrauch auf 11 MB.
Auch hier behält sich die Anwendung (Laienwissen) eventuell etwas im Speicher?

Also alles OK?
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#35

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 14:17
Ich würde mal sagen ja. Bei einer anderen Anwendung bei der ich sehr viele Daten aus einer SQLite Datenbank lade habe ich den Effekt zwar nicht, aber solange alles freigegeben wird, ist da alles in Ordnung.

Zur Kontrolle kannst du in deiner DPR Datei mal die Zeile ReportMemoryLeaksOnShutdown := True; einfügen. Dann erhälst du nach dem Beenden deines Programms ein Fenster in der MemoryLeaks aufgelistet werden, wenn denn überhaupt welche vorhanden sind.

Funktioniert dein Programm denn jetzt mit InitNode so wie in meinem Beispiel? Oder hakt es noch irgendwo. Dein erster Satz klingt sehr positiv, daher würde ich mal davon ausgehen das alles funktioniert. Aber eine Kontrolle schadet ja nie.
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.919 Beiträge
 
Delphi 10.4 Sydney
 
#36

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 14:26
Den präzisen Speicherverbrauch einer Anwendung zu messen ist nicht trivial. Der Taskmanager ist hierfür kein besonders gutes Werkzeug, da er nur einen groben Wert widerspiegelt. Es ist bei der Speicherverwaltung von Windows (und auch anderen Betriebssystemen) durchaus möglich, dass ein Speicherbereich intern als "frei" gekennzeichnet wird, dem Prozess aber weiterhin zugeordnet wird, da die Wahrscheinlichkeit, dass dieser wieder Speicher brauchen wird i.A. recht hoch ist.

Du kämpfst an vielen Fronten gleichzeitig. Baue Dir ein kleines Beispiel und mache Dir daran die Speicherverwaltung des TreeViews klar - dann übertrage das auf andere Lösungen. Lasse Dich aber nicht von Seiteneffekten wie der Speicheranzeige des Taskmanagers verwirren.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#37

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 14:38
@Aviator ja es funktioniert jetzt.
Nur was mir jetzt erst aufgefallen ist > meine CheckBoxen im VirtualStringTree sind verschwunden.
Ich weiß gerade nicht ob es am Update von VST liegt oder nicht. Muss ich prüfen.

Daniel:
das habe ich zum Glück bereits gemacht. Ich habe alles was das VST angeht aus dem Projekt kopiert und in eine saubere kleine Spiele-Wiese-Anwendung gepackt.
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#38

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 14:48
@Aviator ja es funktioniert jetzt.
Super!
meine CheckBoxen im VirtualStringTree sind verschwunden.
Welche Checkboxen?

Möglicherweise wurde seit deiner letzten Version in den TreeOptions etwas verändert und du musst noch einen zusätzlichen Haken setzen. Ich gehe mal davon aus, dass du die Checkboxen vor den Nodes meinst mit denen du diese auswählen kannst.
  Mit Zitat antworten Zitat
Jim Carrey
(Gast)

n/a Beiträge
 
#39

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 14:49
Ein VirtualStringTree hat doch einen Support für Checkboxen, wusstest du das nicht?

Edit: verdammt, die CheckBoxen sind auch mit der alten Version von VST nicht mehr da. Muss wahrscheinlich an was anderem liegen

Edit 2: ein bisschen Nachdenken hätte nicht geschadet!
Die Knoten werden ja jetzt erst bie der Anzeige initialisiert wenn ich das richtig verstanden habe.
Demnach musste Folgendes zusätzlich in InitNode
Delphi-Quellcode:
procedure TForm2.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
 Data: PMyDataClass;
begin
 Data := VST.GetNodeData(Node);

 // .... dem VST natürlich auch sagen, dass er die verflicksten Dinger anzeigen soll!
 Node.CheckType := ctCheckBox;
 Node.CheckState := csCheckedNormal;

 Data^ := FMyDataClasses[Node^.Index];
end;

Geändert von Jim Carrey ( 6. Okt 2016 um 15:01 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#40

AW: Nodes einer VirtualStringTree hinzufügen - aber schneller!

  Alt 6. Okt 2016, 15:09
Ein VirtualStringTree hat doch einen Support für Checkboxen, wusstest du das nicht?

Edit: verdammt, die CheckBoxen sind auch mit der alten Version von VST nicht mehr da. Muss wahrscheinlich an was anderem liegen

Edit 2: ein bisschen Nachdenken hätte nicht geschadet!
Die Knoten werden ja jetzt erst bie der Anzeige initialisiert wenn ich das richtig verstanden habe.
Demnach musste Folgendes zusätzlich in InitNode
Delphi-Quellcode:
procedure TForm2.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
 Data: PMyDataClass;
begin
 Data := VST.GetNodeData(Node);

 // .... dem VST natürlich auch sagen, dass er die verflicksten Dinger anzeigen soll!
 Node.CheckType := ctCheckBox;
 Node.CheckState := csCheckedNormal;

 Data^ := FMyDataClasses[Node^.Index];
end;
Doch klar wusste ich das.
Ohne mich jetzt größer darzustellen als ich bin, aber ich glaube es gibt keine Funktion des VST die ich nicht kenne. Ich arbeite mittlerweile schon seit einigen Jahren mit der Komponente und habe schon sehr viele Werke damit vollbracht.

Und ja: Mit dem setzen des CheckTypes und des CheckStates liegst du richtig. Das musst du jetzt (wie vorher auch) jeder Node einzeln zuordnen. Ich dachte nur (siehe meinen letzten Beitrag), dass du eventuell den CheckSupport in den TreeOptions nicht eingeschaltet hattest oder sogar eine neue Einstellung hinzugekommen ist seit deiner letzten Version. Weil dann wird nämlich auch nix angezeigt.

Aber du hast es ja jetzt gefunden.

Happy
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 6   « Erste     234 56      


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 03:12 Uhr.
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