Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Große Probleme mit VirtualStringTree (https://www.delphipraxis.net/193070-grosse-probleme-mit-virtualstringtree.html)

SneakyBagels 17. Jun 2017 09:40

Große Probleme mit VirtualStringTree
 
Ich teste mich heute an einem VirtualStringTree denn mein Ziel ist es ein VST zu haben was aussieht wie ein TListView (mit Mouse-Hover-Effekt).

Das hier habe ich schon. Ok, es kommt von einem Tutorial. Aber es funktioniert trotzdem nicht.
Statt dass die in Col1 und Col2 zugewiesenen Strings im VST landen, landet das im Form.Caption.

Delphi-Quellcode:
type
 PTreeData = ^TTreeData;

 TTreeData = packed record
  Col1: string;
  Col2: string;
 end;

implementation

{$R *.dfm}

function AddVSTStructure(AVST: TCustomVirtualStringTree; ANode: PVirtualNode; ARecord: TTreeData): PVirtualNode;
var
 Data: PTreeData;
begin
 Result := AVST.AddChild(ANode);
 Data := AVST.GetNodeData(Result);
 AVST.ValidateNode(Result, False);
 Data^.Col1 := ARecord.Col1;
 Data^.Col2 := ARecord.Col2;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
 i: Integer;
 TreeData: TTreeData;
begin
 VST.NodeDataSize := SizeOf(TTreeData);
 VST.BeginUpdate;
 for i := 0 to 9 do
  begin
   TreeData.Col1 := 'Node-Nummer: ' + IntToStr(i);
   TreeData.Col2 := 'Nummer: ' + IntToStr(i * i);
   AddVSTStructure(VST, nil, TreeData);
  end;
 VST.EndUpdate;
end;

procedure TForm2.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
 Data: PTreeData;
begin
 Data := VST.GetNodeData(Node);
 case Column of
  0:
   Text := Data.Col1;
  1:
   Text := Data.Col2;
 end;
end;
Text habe ich mal durch CellText geändert das funktioniert jetzt.
Was aber nicht funktioniert das Einstellen der Höhe eines Nodes. Und allgemein kann man mit dem VST irgendwie wenig machen oder es ist halt alles versteckt.
Wieso gibt es denn nicht mal einen Fokus-Rahmen wenn man mit er Maus drüber fährt wie beim ListView?

jaenicke 17. Jun 2017 10:07

AW: Große Probleme mit VirtualStringTree
 
Delphi-Quellcode:
procedure TForm2.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string); // CellText !!!
var
 Data: PTreeData;
begin
 Data := VST.GetNodeData(Node);
 case Column of
  0:
   Text := Data.Col1; // nicht Text !!
  1:
   Text := Data.Col2;
 end;
end;
// EDIT:
Ok, hast du selbst parallel gesehen.

jaenicke 17. Jun 2017 10:27

AW: Große Probleme mit VirtualStringTree
 
Ich schreibe das mal separat, damit du eine Benachrichtigung siehst:
Höhe ändern geht einfach, aber man muss es aktivieren (aus Performancegründen):
Unter TreeOptions --> MiscOptions den Wert toVariableNodeHeight auf True setzen.
Dann funktioniert OnMeasureItem.

SneakyBagels 17. Jun 2017 10:32

AW: Große Probleme mit VirtualStringTree
 
Zitat:

Ich schreibe das mal separat, damit du eine Benachrichtigung siehst:
Weiß nicht, welche Benachrichtigung.

Ich bin mittlerweile so weit:

Items zur besseren Übersicht farblich gestalten (jedes zweite):
Delphi-Quellcode:
procedure TForm2.VSTAfterItemErase(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect);
begin
 if Odd(Node.Index) then
  TargetCanvas.Brush.Color := $00E1F3FF;

 TargetCanvas.FillRect(ItemRect);
end;
Im OnGetText u.a.:
Delphi-Quellcode:
procedure TForm2.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
 Data: PVSTData;
begin
 Data := VST.GetNodeData(Node);

 if Node.Index = 2 then
  Node.NodeHeight := 35; // <= funktioniert sogar ohne toVariableNodeHeight
....
end;
Text selber zeichnen:
Delphi-Quellcode:
procedure TForm2.VSTDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect;
 var DefaultDraw: Boolean);
begin
 DefaultDraw := False;
 TargetCanvas.TextOut(CellRect.Left, CellRect.Top + 2, Text);

 if Node.Index = 2 then
  begin
   TargetCanvas.TextOut(CellRect.Left, CellRect.Top + 16, '123'); // Funktioniert. Wird aber erst sichtbar, wenn ich mit der Maus über das VST fahre
  end;
end;
Ist das bisher eine absolute 0815-Lösung oder ist das OK so?

SneakyBagels 17. Jun 2017 10:58

AW: Große Probleme mit VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 1)
Im Anhang mal mein aktueller Versuch.
Das Ganze ist eine Zusammenstellung aus Forum, Google, Tutorial und meinem Kram.

Es funktioniert soweit bis auf, dass
- ein Node mit einer Höhe > Default den zweiten TextOut nicht anzeigt.
- ein Node der vorher selektiert war und wo nun der Fokus woanders hin verlegt wird (Button), eine andere Hintergrundfarbe hat

jaenicke 17. Jun 2017 11:00

AW: Große Probleme mit VirtualStringTree
 
Ich würde das ganze mit den Pointern und Records lassen und lieber Klassen dranhängen. In den aktuellen Versionen des VST geht es auch generisch:
Delphi-Quellcode:
type
  TTest = class
  private
    FValue: Integer;
    procedure SetValue(const Value: Integer);
  public
    constructor Create(const AValue: Integer);
    property Value: Integer read FValue write SetValue;
  end;

// hinzufügen
  VirtualStringTree1.AddChild(nil, TTest.Create(15));

// OnGetText
  CellText := IntToStr(Node.GetData<TTest>.Value);

SneakyBagels 17. Jun 2017 11:02

AW: Große Probleme mit VirtualStringTree
 
Ich brauche die ObjectList leider, um später auf die Daten zugreifen zu können OHNE ins VST gehen zu müssen. Sonst würde ich sie auch weglassen.

jaenicke 17. Jun 2017 11:08

AW: Große Probleme mit VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von SneakyBagels (Beitrag 1374741)
Es funktioniert soweit bis auf, dass
- ein Node mit einer Höhe > Default den zweiten TextOut nicht anzeigt.

Weil du den Wert einfach hineinschreibst statt es zu machen wie ich geschrieben habe. ;-)

Im Anhang funktioniert es und die Pointerspielerei ist auch raus.

Zitat:

Zitat von SneakyBagels (Beitrag 1374743)
Ich brauche die ObjectList leider, um später auf die Daten zugreifen zu können OHNE ins VST gehen zu müssen. Sonst würde ich sie auch weglassen.

Die soll auch nicht raus, die Daten sollen schon extern liegen. Aber siehe Anhang.

Aviator 17. Jun 2017 11:11

AW: Große Probleme mit VirtualStringTree
 
Tag!

Also vorab: Mit dem VST kannst du eigentlich alles machen was du willst. Die Komponente ist extrem flexibel und lässt sehr viele Dinge zu, die mit anderen Komponenten nur schwer bis gar nicht erreicht werden können. Und das noch auf extrem einfache Art und Weise.

Das farbliche Markieren von Zeilen macht man besser im OnBeforeCellPaint. Das Event ist dafür besser geeignet bzw. wird in der Regel eher dafür genutzt. Anbei mal die Reihenfolge der Zeichen-Events, die nacheinander ausgelöst werden. Das OnBeforeCellPaint Event kommt zwar direkt nach dem OnAfterItemErase, aber StateOfTheArt ist eigentlich OnBeforeCellPaint.

Zitat:

Zitat von VirtualTreeView Help File
Usually the following paint stages are executed during a paint cycle:
• before paint (OnBeforePaint)
• before item paint (OnBeforeItemPaint)
• before item erase (OnBeforeItemErase)
• after item erase (OnAfterItemErase)
• before cell draw (OnBeforeCellPaint)
• on paint text (string trees only, OnPaintText)
• after cell draw (OnAfterCellPaint)
• after item paint (OnAfterItemPaint) after paint (OnAfterPaint)

Die Messung der Texthöhe solltest du nicht im OnGetText Event machen. Dafür gibt es spezielle Events wie z.B. OnMeasureItem.

Zitat:

Zitat von VirtualTreeView Help File
10.1.2.126 TBaseVirtualTree.OnMeasureItem Event

Miscellaneous event.

Delphi-Quellcode:
property OnMeasureItem: TVTMeasureItemEvent;
Description

Virtual Treeview supports individual node heights. However it might sometimes unpractical to set this height in advance (e.g. during OnInitNode( see TBaseVirtualTree.OnInitNode Event, page 147)). Another scenario might be that multi line nodes must size themselves to accomodate the entire node text without clipping. For such and similar cases the event OnMeasureItem is for. It is queried once for each node and allows to specify the node's future height. If you later want to have a new height applied (e.g. because the node's text changed) then call InvalidateNode( see TBaseVirtualTree.InvalidateNode Method , page 221) for it and its vsHeightMeasured state is reset causing so the tree to trigger the OnMeasureItem event again when the node is painted the next time.

Die Grund Initialisierung kannst du im OnInit Event durchführen. In den neueren Versionen gibt es auch noch die Events OnMeasureTextHeight und OnMeasureTextWidth die du dafür nutzen solltest.


Bei Änderungen der Formatierung deiner Texte die im VST angezeigt werden solltest du OnPaintText benutzen. Im OnDrawText musst du alles selbst machen. Die Positionierung, die Ausgabe des Textes, usw.

Im OnPaintText übernimmt der Tree das alles für dich. Aber nur, wenn es um Formatierungen geht. Wenn du weitere Texte dazumalen willst, dann solltest du OnDrawText.


Die eigentliche Erstellung der Nodes solltest du mit der RootNodeCount Eigenschaft des Trees machen. Die Children bzw. den ChildCount dann im OnInit und OnInitChildren Event zuweisen.

Um Nodes beim Drüberfahren mit der Maus markieren zu lassen, kannst du auch die TreeOption toHotTrack in den PaintOptions setzen. Wenn dir das Design nicht zusagt, dann setze evtl. zum Testen mal toUseExplorerTheme auf True. Wenn es dann noch nicht passt, dann kannst du das im OnBeforeCellPaint selbst machen. Hatte ich auch mal für ein paar Programme gemacht. Sieht eigentlich ziemlich gut aus.

SneakyBagels 17. Jun 2017 11:19

AW: Große Probleme mit VirtualStringTree
 
Hallo Aviator, deinen Beitrag lese ich mir gleich mal in Ruhe durch.

Jaenike:
Danke für deine Änderung.
SetData und GetData können leider nicht gefunden werden und ich weiß auch leider nicht wie ich das in diesen von mir fabrizierten Salat einbinde :(
VST in Verbindung mit Klassen und ObjectList ist komplett neu für mich.

jaenicke 17. Jun 2017 11:27

AW: Große Probleme mit VirtualStringTree
 
Was hast du denn für eine Delphiversion und woher hast du den VST heruntergeladen?
Richtig wäre hier ausgecheckt:
https://github.com/Virtual-TreeView/Virtual-TreeView

SneakyBagels 17. Jun 2017 11:32

AW: Große Probleme mit VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 1)
Tokyo und VST Version 7, die neueste.
Fehlt in Unit2 nicht SetData und GetData?

SneakyBagels 17. Jun 2017 11:35

AW: Große Probleme mit VirtualStringTree
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374749)
Tokyo und VST Version 7, die neueste.

Fehlt in Unit2 nicht SetData und GetData?

EDIT es funktioniert jetzt... ich musste nur meinen alten VST-Ordner mit den Units drin löschen.
Ich bastel dann später mal weiter. Danke bisher! Und Aviator, deinen Beitrag lese ich mir noch in Ruhe durch.

SneakyBagels 17. Jun 2017 15:27

AW: Große Probleme mit VirtualStringTree
 
So da bin ich wieder.
Ich habe noch ein bisschen rumgespielt und herausgefunden, dass wenn ich das VST mit Clear leere, wohl auch die Datenklassen in den Nodes automatisch freigegeben werden.
Ein im ..ObjectList..Free im FormDestroy führt aber zu einem "Ungültige Zeigeroperation".
Im VSTOnFree habe ich
Delphi-Quellcode:
VST.GetNodeData<TVSTData>(Node).Free;
hinzugefügt.
Ist es nicht normaler so, wie man Instanzen von etwas freigibt? Im OnDestroy meine ich?

DeddyH 17. Jun 2017 17:35

AW: Große Probleme mit VirtualStringTree
 
Das klingt so, als hättest Du Mehrfach-Referenzen auf Deine Objekte. Wenn man da nicht aufpasst, schafft man sich ganz schnell wilde Zeiger, was zu den geschilderten Problemen führt. Also entweder dafür sorgen, dass beim Zerstören der Objekte alle Referenzen genilt werden oder einfach Interfaces verwenden.

SneakyBagels 17. Jun 2017 17:48

AW: Große Probleme mit VirtualStringTree
 
Wollte gerade antworten :P

1. TObjectList habe ich durch TList ausgetauscht. Denn TObjectList UND die VST haben die Objekte.... "ge-owned" :?: gehabt... glaube ich jedenfalls.

2. Folgende Änderung im OnFreeNode
Delphi-Quellcode:
procedure TForm2.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
 VST.GetNodeData<TVSTData>(Node).Free;
 aVSTDataClasses.Delete(Node.Index); // <== das hier habe ich hinzugefügt
end;
Das funktioniert jetzt soweit.

- VST.Clear
VST leeren, Nodes löschen und TList-Objekte freigeben

- aVSTDataClasses.Free
Am Ende des Programms Liste freigeben

NUR ich kann mir gut vorstellen, dass meine Änderung oben mit Delete(Nodex.Index) richtig in die Hose geht, wenn man das VST um-sortiert (von Z nach A statt A nach Z).
Bzw. wenn man im VST nur ein paar Nodes und nicht alle angezeigt (Stichwort "Suche") dann ginge das auch echt in die Hose.
Oder sehe ich das falsch?

Und habe dabei gerade noch ein anderes Problem gefunden... ein VST.Clear räumt mir leider auch die TList leer, was ich nicht möchte.

DeddyH 17. Jun 2017 17:57

AW: Große Probleme mit VirtualStringTree
 
Das siehst Du schon richtig, machst es Dir aber auch unnötig schwer. Ich an Deiner Stelle würde die Objekte speichertechnisch weiterhin von der Objektliste verwalten lassen und eine Referenz in den Knoten ablegen, wie Du es ja vorher hattest. Wird nun ein Knoten gelöscht, merkst Du Dir die Referenz, holst Dir deren Index aus der Objektliste und löschst dann diesen Index aus der Liste. Steht dort OwnsObjects auf true, wird das Objekt automatisch freigegeben. Im OnFreeNode darfst Du das Objekt dann natürlich nicht freigeben, das ist ja schon weg.

SneakyBagels 17. Jun 2017 18:00

AW: Große Probleme mit VirtualStringTree
 
Das ich das Projekt nochmal als Anhang schicken? Verstehe sonst nur Bahnhof, ob ich das jetzt richtig habe oder nicht.

Aviator 17. Jun 2017 18:12

AW: Große Probleme mit VirtualStringTree
 
Du könntest einfach das OnFreeNode Event weglassen. Dann gibt dir der Tree auch nichts frei was du nicht freigeben willst. Und dann eben eine TObjectList nutzen (wie von DeddyH vorgeschlagen). Bei mir funktioniert das so schon seit Jahren.

Der Tree bekommt immer nur eine Referenz zu dem Objekt, wird aber niemals der Besitzer.

EDIT: Häng dein Projekt einfach mal an. Dann können wir mal drüberschauen.

DeddyH 17. Jun 2017 18:12

AW: Große Probleme mit VirtualStringTree
 
Das müssen sich dann aber andere anschauen, ich sitze gerade am Tablet. Aber eine andere Frage: wird die Liste noch anderweitig benutzt, oder dient sie lediglich der Speicherverwaltung? Im letzteren Fall könntest Du doch komplett darauf verzichten.

SneakyBagels 17. Jun 2017 18:25

AW: Große Probleme mit VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 1)
Aktuell verwende ich ein TListView welches ich eigentlich bearbeiten wollte, um Data mit hinterlegter Liste zu verwenden.
Das hätte für mich den Vorteil, dass ich an verschiedenen Stellen nicht mehr extra in meine Ini-Datei gehen muss oder noch blöder die SubItems auslesen muss.

Und wenn-schon-denn-schon dachte ich mir, baue ich alles komplett auf VST um.
Also ja, die Daten werden noch woanders verwendet (nur lesend).

Hier meine aktuelle Demo. Sortieren funktioniert, aber löschen danach nicht mehr.
Folgendes lößt das Problem vorzeitig, aber ist es auch -richtig-?
Delphi-Quellcode:
 // Zu TVSTData hinzufügen
 Index: Integer;

 // Index beim Erstellen der Nodes setzen
 aVSTData := TVSTData.Create;
 aVSTData.Index := i;
 // ....

 // Einen Node und dessen Daten löschen
 ShowMessage('VST-Index: ' + IntToStr(VST.FocusedNode.Index) + sLineBreak + 'List-Index: ' + IntToStr(Data.Index));
 aVSTDataClasses.Delete(Data.Index); // Daten des Nodes aus ObjectList löschen
 VST.DeleteNode(VST.FocusedNode); // Node "visuell" löschen

DeddyH 17. Jun 2017 18:38

AW: Große Probleme mit VirtualStringTree
 
Nimm doch beim Löschen einfach den Index innerhalb der Objektliste, dann kann doch nichts schiefgehen. Pseudo-Code:
Delphi-Quellcode:
idx := Liste.IndexOf(VST.NodeData);
if idx > -1 then
  Liste.Delete(idx);

Aviator 17. Jun 2017 23:10

AW: Große Probleme mit VirtualStringTree
 
Ich habe mir dein Testprojekt jetzt mal angeschaut. Es ist natürlich wenig programmfluss drin der sich selbst erklärt. Also wann soll man welchen Button drücken damit nichts kaputt geht. Aber das ist ja bei einem Testprojekt normal.

Prinzipiell sieht es schonmal nicht falsch aus. Auch wenn da noch einige Dinge drin sind die man verbessern könnte. Nur will ich hier jetzt kein großes Fass aufmachen da ich nicht weiß, wie ausführlich du dein Testprojekt jetzt programmiert hast.

Ich denke es wäre sinnvoller, wenn du schon ein etwas fortgeschritteneres Programm zum "Probelesen" anbieten würdest, in dem du auch schon ein gewisses Errorhandling drin hast. Fehler im Keim zu ersticken ist zwar immer besser, aber bei reinen Testanwendung schreibt man ja auch schnell mal was hin ohne großartig Wert darauf zu legen wie es aussieht. Hauptsache der Test funktioniert.

Das Problem mit dem Löschen deiner Nodes haben wir ja in dem anderen Thread geklärt. :wink:

SneakyBagels 17. Jun 2017 23:13

AW: Große Probleme mit VirtualStringTree
 
Ich kann dir später gerne mal mein aktuelles Testprojekt hier anbieten.
Es wird aber noch über Wochen ein Testprojekt bleiben.
Fehlerbehandlung kommt erst, wenn ich den Testcode in mein eigentliches Projekt einbaue, da mir im Testprojekt dafür gewisse Units fehlen.

Mit diesem Testprojekt ohne Fehlerbehandlung komme ich vollkommen klar. Ich setze es demnächst aber nochmal neu hier rein mit einer kurzen Erklärung.

Aviator 17. Jun 2017 23:28

AW: Große Probleme mit VirtualStringTree
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374781)
Ich kann dir später gerne mal mein aktuelles Testprojekt hier anbieten.
Es wird aber noch über Wochen ein Testprojekt bleiben.
Fehlerbehandlung kommt erst, wenn ich den Testcode in mein eigentliches Projekt einbaue, da mir im Testprojekt dafür gewisse Units fehlen.

Mit diesem Testprojekt ohne Fehlerbehandlung komme ich vollkommen klar. Ich setze es demnächst aber nochmal neu hier rein mit einer kurzen Erklärung.

Ist ja auch in Ordnung so. Ich habe jetzt einfach mal nur die Art deiner Programmierung, also der Zuweisung der Daten zum Tree und die Verarbeitung der Daten, beachtet. Ausgeführt habe ich das Programm nur kurz und mal nacheinander verschiedene Dinge probiert.

Mir ist jetzt nicht direkt irgendetwas aufgefallen was du evtl. falsch machst bis auf eine Kleinigkeit:

Delphi-Quellcode:
procedure TForm2.VSTCompareNodes(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
var
 Data1: TVSTData;
 Data2: TVSTData;
begin
 Data1 := Node1.GetData<TVSTData>;
 Data2 := Node2.GetData<TVSTData>;

 Result := CompareText(Data1.Col1, Data2.Col2);
end;

Hier vergleichst du Col1 immer mit Col2 von unterschiedlichen Nodes. Ich denke, dass das richtigerweise beide Male Col1 sein sollte. Aber dazu kann ich nicht mehr sagen.

Ein Hinweis vielleicht noch zu dem DrawText. Hier geht es dir scheinbar darum, dass du einen bestimmten Text hinter eine Node setzen willst, wenn eine Beschreibung vorliegt. Das könntest du evtl. auch mit dem StaticText umsetzen was du wiederum über das GetText lösen könntest. Dafür benötigst du dann kein extra DrawText Event.

SneakyBagels 17. Jun 2017 23:36

AW: Große Probleme mit VirtualStringTree
 
Zitat:

Das könntest du evtl. auch mit dem StaticText umsetzen was du wiederum über das GetText lösen könntest. Dafür benötigst du dann kein extra DrawText Event.
Ich nehme jegliche Verbesserungsvorschläge an.

Ich führe jaenike's Beitrag hier mal fort wenn ich darf: #4: http://www.delphipraxis.net/1374783-post4.html
Das hieße, ich bräuchte keine extra TObjectList zum Halten der Daten.

Daher eine generelle Frage:
ObjectList ja oder nein. Das Projekt hat rund 120.000 Zeilen und das VST wird das Control sein, welches zu 99% verwendet wird.

jaenicke 18. Jun 2017 06:38

AW: Große Probleme mit VirtualStringTree
 
Es ist immer besser die Daten außerhalb der GUI zu halten und dort nur zu referenzieren.

SneakyBagels 18. Jun 2017 11:03

AW: Große Probleme mit VirtualStringTree
 
Ich habe eben mal ein bisschen mit toShowStaticText rumprobiert, bekomme das aber leider nicht hin, dass ich zwei Zeilen Text pro Node habe.
Aktuell verwende ich ja TargetCanvas.TextOut im OnDrawText zweimal, da klappt es. Winapi.Windows.DrawTextW wäre mir eigentlich lieber.

Aktuell ist es so
Delphi-Quellcode:
procedure TForm2.VSTDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect;
 var DefaultDraw: Boolean);
var
 Data: TVSTData;
 DrawFormat: Cardinal;
 R: TRect;
 s: string;
begin
 DefaultDraw := False;
 R := CellRect;
 R.Left := R.Left + VST.Indent;

 Data := Node.GetData<TVSTData>;

 // TargetCanvas.TextOut(CellRect.Left, CellRect.Top + 2, Text);

 DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE;
 if Data.bHasDescription then
  R.Top := R.Top - 14;

 Winapi.Windows.DrawTextW(TargetCanvas.Handle, PWideChar(Text), Length(Text), R, DrawFormat);

 if Data.bHasDescription and (Column = 0) then
  begin
   // TargetCanvas.TextOut(CellRect.Left, CellRect.Top + 18, '123');
   s:='123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 '; // wird leider nicht komplett gezeichnet - nur "123 "
   R.Top := R.Top + 28;
   Winapi.Windows.DrawTextW(TargetCanvas.Handle, PWideChar(s), Length(s), R, DrawFormat);
  end;
end;

jaenicke 18. Jun 2017 18:41

AW: Große Probleme mit VirtualStringTree
 
Warum benutzt du denn DT_SINGLELINE? Es können doch direkt mehrere Zeilen ausgegeben werden.

SneakyBagels 18. Jun 2017 18:56

AW: Große Probleme mit VirtualStringTree
 
Im Prinzip möchte ich folgendes weiß aber nicht ob das möglich ist
.,.. keine Ahnung wie man eine Tabelle macht daher so

Header | Header | Header | Header
---------------------------------
-Col1--|--Col2--|--Col3--|--Col4 <== Node: Default Höhe

-Col1--|--Col2--|--Col3--|--Col4 <== Node: doppelte Höhe
-hier ein string von Col1 bis Col4

Ich dachte erst AutoSpan der Cols könnte helfen aber leider nicht.

Aviator 18. Jun 2017 19:06

AW: Große Probleme mit VirtualStringTree
 
Für den Fall könntest du mal den Automatismus vom VST ausprobieren. Aktiviere hierzu
Delphi-Quellcode:
toAutoSpanColumns
(glaube so heißt es) in den TreeOptions und füge dann nur in Col1 (bzw. in der Column, ab der der Text angezeigt werden soll) den Text ein. Bei den nachfolgenden Columns lässt du den CellText leer.

Der VST verlängert dann automatisch den Text über die anderen Spalten hinweg. Ob das mit Multiline funktioniert weiß ich nicht. Die Node Höhe sollte da aber keine Rolle spielen.

SneakyBagels 18. Jun 2017 20:10

AW: Große Probleme mit VirtualStringTree
 
Funktioniert alles leider nicht.
Ich brauche leider ja auch die anderen Columns.

Chaotisch aber so sieht es aus
Delphi-Quellcode:
procedure TForm2.VSTDrawText(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; const Text: string; const CellRect: TRect;
 var DefaultDraw: Boolean);
var
 Data: TVSTData;
 DrawFormat: Cardinal;
 R: TRect;
 s: string;
begin
 DefaultDraw := False;
 R := CellRect;

 if Column = 0 then
  R.Left := R.Left + VST.Indent;

 Data := Node.GetData<TVSTData>;

 // TargetCanvas.TextOut(CellRect.Left, CellRect.Top + 2, Text);

 DrawFormat := DT_NOPREFIX or DT_VCENTER; // or DT_SINGLELINE;
 // if Data.bHasDescription then
 // R.Top := R.Top - 14;

 // Winapi.Windows.DrawTextW(TargetCanvas.Handle, PWideChar(Text), Length(Text), R, DrawFormat);

 if Data.bHasDescription and (Column = 0) then
  begin
   s := '123 123 123 123 123 ' + sLineBreak + '123 123 123 123 123 123 123 123 123 123 ';
   // R.Top := R.Top + 28;
   // TargetCanvas.TextOut(CellRect.Left, CellRect.Top + 18, s);
   Winapi.Windows.DrawTextW(TargetCanvas.Handle, PWideChar(s), Length(s), R, DrawFormat);
  end
 else if (Column = 0) then
  Winapi.Windows.DrawTextW(TargetCanvas.Handle, PWideChar(Text), Length(Text), R, DrawFormat);
end;

Towmuz 19. Jun 2017 07:46

AW: Große Probleme mit VirtualStringTree
 
Moin,

habe jetzt nicht so ganz genau den Thread komplett gelesen, aber ich glaub du könntest
in diesem Fall auch einfach im
Delphi-Quellcode:
OnInitNode
festlegen:

Delphi-Quellcode:
procedure TForm2.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
  if Length(VST.GetNodeData<TDeinObject>(Node).Col1) > 10 then
  begin
     VST.MultiLine[Node] := True;
     VST.NodeHeight[Node] := 40; // oder sonstwas wie´s dir passt
  end
end;
Dann kann das händische Pinseln im
Delphi-Quellcode:
OnDrawText
raus und mit
Delphi-Quellcode:
OnGetText
dann:

Delphi-Quellcode:
procedure TForm2.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
  s: string;
begin
  case Column of
    0: begin
      if Length(VST.GetNodeData<TDeinObject>(Node).Col1) > 10 then
      begin
        s := 'blablalblabla' + #13#10 + 'blablabla';
      end else begin
        s := 'blabla';
      end;
      CellText := s;
    end;
  end;    
end;

SneakyBagels 19. Jun 2017 08:03

AW: Große Probleme mit VirtualStringTree
 
Zitat:

habe jetzt nicht so ganz genau den Thread komplett gelesen,
Ist kein Problem und ich bedanke mich für die Hilfe aber das ist nicht das was ich suche. Ich suche eine Lösung die mir die zweite Zeile der ersten Spalte über alle Spalten hinweg durchgehend anzeigt.

Aviator 19. Jun 2017 08:39

AW: Große Probleme mit VirtualStringTree
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374834)
Zitat:

habe jetzt nicht so ganz genau den Thread komplett gelesen,
Ist kein Problem und ich bedanke mich für die Hilfe aber das ist nicht das was ich suche. Ich suche eine Lösung die mir die zweite Zeile der ersten Spalte über alle Spalten hinweg durchgehend anzeigt.

Ich bin immer noch der Meinung, dass dir an der Stelle
Delphi-Quellcode:
toAutoSpanColumns
helfen müsste. Das hat nämlich genau den Effekt den du suchst.

Alternativ kannst du auch das Zeichnen des Textes selbst übernehmen mit dem DrawText Event und einfach dann an den Zellen in denen nichts gezeichnet wird
Delphi-Quellcode:
DefaultDraw
auf
Delphi-Quellcode:
False
setzen und auch selbst dort nichts zeichnen. Nur
Delphi-Quellcode:
toAutoSpanColumns
nimmt dir die Arbeit schon ab. :cyclops:

SneakyBagels 19. Jun 2017 08:43

AW: Große Probleme mit VirtualStringTree
 
Wie bereits erwähnt habe ich das schon getestet.
Die Texte zeichne ich bereits selber.

Towmuz 19. Jun 2017 09:17

AW: Große Probleme mit VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ah na denn, siehe Grafik ob ich´s nun richtig verstanden hab :D
ansonsten Bsp.Projekt im Anhang.

Für sowas gibt´s das AfterItemPaint, wenn du das im OnDrawText benutzt kannst du das Rectangle zwar definieren wie du willst, es wird trotzdem jedesmal die Column (also auch die NachbarColumns) neu gezeichnet, und somit deine übermalte Column kurz gezeichnet und dann gleich wieder überpinselt.

Edit: TreeView Version 6.4.1. aber das sollte wohl kaum einen Unterschied machen

SneakyBagels 19. Jun 2017 10:20

AW: Große Probleme mit VirtualStringTree
 
Bild sieht gut aus. Ich teste das gleich mal!
Ich antworte gleich auch im Detail nur habe gerade keine zeit.

Also: ich teste das gleich und melde mich :thumb:


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