Delphi-PRAXiS

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 VirtualTreeView bearbeiten (https://www.delphipraxis.net/160883-virtualtreeview-bearbeiten.html)

mdx 6. Jun 2011 11:57

VirtualTreeView bearbeiten
 
Hallo,
ich habe folgendes Problem:

Ich habe ein Programm geschrieben, welches eine URL aus einer Stringlist und den Dateinamen aus einer weiteren Stringlist ausliest (wobei der Dateiname auch in dem VirtualTreeView steht) und diese Dateien in einem Thread herunterlädt. Das funktioniert auch alles ohne Probleme.
Jetzt würde ich gerne in der VirtualTreeView Komponente in derselben Zeile wie der jeweilige Eintrag steht eine Progressbar, sowie die aktuelle Geschwindigkeit, Verbleibende Zeit und Größe der Datei bzw. der bereits heruntergeladenen Datei anzeigen lassen. Die Werte an sich hab ich alle schon, ich muss sie nur irgendwie in diese Komponente schreiben können.
Momentan hab ich es so probiert:
Delphi-Quellcode:
[...]
daten := TEntry.Create;
VST.NodeDataSize:=SizeOf(daten);
daten := TEntries(VST.GetNodeData(Node)^);

with daten do
  begin
    daten.DownloadStatus:=inttostr(Progress)+ ' %';
  end;

[...]
Jedoch erhalte ich hier in der 3. Zeile eine Zugriffsverletzung.
Wobei wenn ich recht überlege dass so auch gar nicht funktionieren könnte, da man in dieser Routine ja wissen müsste welche Zeile jz was ist... :nixweiss:

Hat jemand eine Idee wie sich dieses Problem lösen lässt? Wie bereits in einem anderen Thema über die Komponente gesagt, gibt es eigentlich keinen vernünftigen Tutorials oder ähnliches...

Meine erste Idee war
Delphi-Quellcode:
 node := VST.GetNodeAt(x,y);
jedoch weiß ich nicht wie ich an die x / y Werte kommen soll :|

Wäre nett wenn mir jemand helfen kann :)

(Crosspost DF: http://xe.lv/5fe)

Aurelius 6. Jun 2011 13:24

AW: VirtualTreeView bearbeiten
 
Wenn ich dich richtig verstanden habe hast du einen bereits initialisierten Tree und möchtest nun beliebige Einträge durch ein Programm ändern lassen.

Ich hab zwar lange nicht mehr mit VST gearbeitet, aber theoretisch sollte es möglich sein, diesen von oben bis unten per Schleife durchzugehen und, beispielsweise über die URL, den passenden Eintrag zu finden. Laut der Doku unter http://www.soft-gems.net/index.php?o...d=12&Itemid=33 existieren hier verschiedene Funktionen zum Ermitteln des nächsten Knoten ( 10.1.2.329 TBaseVirtualTree.GetNext ).

Mir hat damals http://www.delphi-treff.de/tutorials...rtualtreeview/ als Einstieg sehr geholfen, aber evtl. kennst du das schon :)

chaosben 6. Jun 2011 15:53

AW: VirtualTreeView bearbeiten
 
"Normalerweise" geht das so:
Der Thread stellt eine Änderung im Fortschritt fest. Also will er den Daten des dazugehörigen Knoten das sagen (entweder kennt der Thread den Knoten oder der Knoten den Thread).

Dann holt man sich die Daten des Knotens und ändert darin die Variable, die den Fortschritt speichert.

Wenn dann irgendwann (vielleicht durch ein Tree.Repaint) das OnGetText-Event aufgerufen wird, gibt man den Fortschritt zurück und der User sieht ihn.

mdx 6. Jun 2011 16:33

AW: VirtualTreeView bearbeiten
 
Zitat:

Zitat von chaosben (Beitrag 1104856)
Dann holt man sich die Daten des Knotens und ändert darin die Variable, die den Fortschritt speichert.

Genau das ist mein Problem :wink:

How can I do this? :D

chaosben 6. Jun 2011 16:50

AW: VirtualTreeView bearbeiten
 
TV.GetNodeData(Node) :-)

Ich denke dein Problem ist die Verknüpfung zwischen Thread und Knoten. Oder?

Stevie 6. Jun 2011 17:50

AW: VirtualTreeView bearbeiten
 
Zitat:

Zitat von chaosben (Beitrag 1104856)
"Normalerweise" geht das so:
Der Thread stellt eine Änderung im Fortschritt fest. Also will er den Daten des dazugehörigen Knoten das sagen (entweder kennt der Thread den Knoten oder der Knoten den Thread).

"Idealerweise" benutzt man dann ein Datenobjekt und/oder ein Callback. Ansonsten hat der Thread ne Abhängigkeit auf ne visuelle Komponente oder umgekehrt -> beides nicht wünschenswert. Beispielweise, wenn du mal den Fortschritt des Threads in eine Datei schreiben willst oder in der Konsole ausgeben willst.

mdx 6. Jun 2011 18:30

AW: VirtualTreeView bearbeiten
 
Zitat:

Zitat von chaosben (Beitrag 1104866)
TV.GetNodeData(Node) :-)

Ich denke dein Problem ist die Verknüpfung zwischen Thread und Knoten. Oder?

Genau ;)
Zum Beispiel müsste ich aus der Zeile eine Spalte die Unique ist auslesen und anhand dessen Rückgabe die aktuelle Zeile verändern lassen ;)
Ich dachte dabei einfach daran z.B den aktuellen Timestamp mit in die Tabelle zu schreiben und dann im Thread auszulesen (anhand der ID in der Stringlist und dessen vergleich) und dann sozusagen machen node := 3; oder so ähnlich, wobei das eigentlich das Problem ist, wie ich node zuweisen kann auf eine bestimmte Zeile :)

chaosben 6. Jun 2011 20:19

AW: VirtualTreeView bearbeiten
 
Grundsätzlich hat Stevie Recht. Aber bis wir auf dem Niveau sind, "krauten" wir einfach mal so weiter. :-)

Wenn ich dich richtig verstanden habe, hast du doch eine Klasse TEntry.
Nun gibt es 2 Varianten:
  1. Du erweiterst die Klasse TEntry um ein Feld, in dem du den Thread referenzierst. So kannst du z.B. alle Knoten durchgehen, die Daten holen und kommst auf diese Weise an den Thread.
  2. Du "merkst" dir im Thread, welchen Knoten du in ihm abarbeitest. Dann kannst du bei einer Fortschrittsänderung die Daten des Knotens ändern.

Ich finde Variante 2 kommt deinen Bedürfnissen ziemlich nahe.

Stevie 6. Jun 2011 20:39

AW: VirtualTreeView bearbeiten
 
Zitat:

Zitat von chaosben (Beitrag 1104920)
Grundsätzlich hat Stevie Recht. Aber bis wir auf dem Niveau sind, "krauten" wir einfach mal so weiter. :-)

Nen Datenobjekt zu bauen und das an Node.Data zu hängen ist nu echt keine Raketenwissenschaft ;)

chaosben 6. Jun 2011 20:53

AW: VirtualTreeView bearbeiten
 
Zitat:

Zitat von Stevie (Beitrag 1104929)
Nen Datenobjekt zu bauen und das an Node.Data zu hängen ist nu echt keine Raketenwissenschaft ;)

Ach so ... das haben wir ja schon ... wenn ich es richtig verstehe, hat er schon ne Klasse TEntry, die genau das macht.

mdx 6. Jun 2011 23:00

AW: VirtualTreeView bearbeiten
 
Okay, nehmen wir an ich habe zum Beispiel in meinem Thread die ID 3, also die vierte Zeile von oben (beginnt ja immer beo 0), wie sag ich dem TreeView Ding dann dass er die Werte in Zeile 4 schreiben soll?
Darum gehts, nicht um das herausfinden der Zeile, das dürfte ich eigentlich hinbekommen irgendwie ;)

chaosben 7. Jun 2011 07:38

AW: VirtualTreeView bearbeiten
 
Steht den in deinem TEntry die ID drin? Wenn ja, dann musst du alle Knoten durchgehen und gucken in welchem die gesuchte ID vorkommt. Dann kannst du die Daten in diesem Knoten ändern.

Alternativ zur ID könntest du dem Thread aber auch sagen, welchen Knoten/welches TEntry-Objekt er updaten soll.

(Mir fällt grad noch was ein: Falls die ID der Index des Knotens ist, kannst du auch die ID auch damit abgleichen (Node^.Index). Das ist aber in meine Augen sehr schmutzig)

mdx 7. Jun 2011 13:24

AW: VirtualTreeView bearbeiten
 
Zitat:

Zitat von chaosben (Beitrag 1104975)
Wenn ja, dann musst du alle Knoten durchgehen und gucken in welchem die gesuchte ID vorkommt. Dann kannst du die Daten in diesem Knoten ändern.)

Hättest du vielleicht auch einen Befehl oder so dafür? Die Komponente mag mich nämlich irgendwie überhaupt nicht :stupid:

Aurelius 7. Jun 2011 14:42

AW: VirtualTreeView bearbeiten
 
So oder so ähnlich sollte es, hoffe ich, funktionieren. Ich nehme an in deinem Thread arbeitest du ebenfalls mit einer TEntry-Instanz, aber es würde genau so mit mehreren String, Int etc. Parametern funktionieren. Folgende Funktion einfach aus dem Snychronize des Threads heraus ausrufen:

Delphi-Quellcode:
function TForm.SynchronizeTreeWithThreadData( ThreadData: TEntry);
var
  Node: PVirtualNode;
  TreeData: TEntry;
  //...
begin;
//...
  TreeData := TEntry.Create;
  Node := VST.GetFirst;

  while Assigned(Node)do
  begin
    // Daten aus aktuellem Knoten holen (hier nehme ich einfach mal an dass dein geposteter Code funktioniert)
    TreeData := TEntries(VST.GetNodeData(Node)^);
    // Daten vergleichen
    If ( ThreadData.ID = TreeData.ID )
    begin
      TreeData.Progress = ThreadData.Progress;
      // ...
    end;
    // Nächsten Knoten ermitteln
    Node := VST.GetNext(Node);
  end;
// ...
end;
Nur aus dem Kopf getippt, ich hoffe ich hab nicht zu viele Fehler reingeschlumpert :stupid:

mdx 7. Jun 2011 15:36

AW: VirtualTreeView bearbeiten
 
Wow danke du bist mein Held Aurelius :wink:
Leicht abgewandelt klappts jz endlich ^^

Delphi-Quellcode:
  daten := TEntries(VST.GetNodeData(Node)^);

  while assigned(daten) do
  begin
  daten := TEntries(VST.GetNodeData(Node)^);
   with daten do
   begin
    If ( '3' = Daten.ID ) then // Zum Test ^^
    begin
[...]
    break; // Schleife Abbrechen wenn gefunden
    end;
     Node := VST.GetNext(Node);
   end;
  end;
Also vielen Dank nochmal, ich hoffe ich muss nicht nochmal eine Frage zu dem dummen Tree-Ding stellen :stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:27 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