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 VST und Gruppenbildung (https://www.delphipraxis.net/139790-vst-und-gruppenbildung.html)

RWarnecke 5. Sep 2009 12:23


VST und Gruppenbildung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

ich arbeite mich gerade in den VirtualStringTree ein. Aber er macht mir noch ein bisschen Kopfzerbrechen. Hier erstmal der Code :
Delphi-Quellcode:
type
  TOParentPos = class
  public
    Reiter : string;
    TextSnip : string;
  end;

  TOSearchResult = class(TOParentPos)
  public
    Number : Integer;
    Kategorie : string;
    Ueberschrift : string;
  end;

{...}

procedure TSearchResultForm.FormCreate(Sender: TObject);
var
  tmpCaption : string;
  daten     : TOSearchResult;
  parentpos : TOParentPos;
  counter   : Integer;
  node      : PVirtualNode;
begin
  counter := 0;
  VST_SearchResult.NodeDataSize := SizeOf(TOParentPos);
  with MainForm.IBQuery do
  begin
    SQL.Clear;
    SQL.Text := SQLCommand;
    Open;
    Active := True;
    while not EOF do
    begin
      counter := counter + 1;
      MainForm.GetCategoryPath(tmpCaption, Fields[1].AsInteger, '');
      daten := TOSearchResult.Create;
      with daten do
      begin
        Number      := counter;
        Kategorie   := tmpCaption;
        Ueberschrift := Fields[2].AsString;
      end;
      node := VST_SearchResult.AddChild(nil, daten);

      parentpos := TOParentPos.Create;
      parentpos.Reiter := 'Sourcecode ' + IntToStr(PosEx(SearchKeywords, Fields[3].AsString));
      parentpos.TextSnip := 'Test';
      VST_SearchResult.AddChild(node, parentpos);
      Next;
    end;
    Active := False;
  end; // END-With IBQuery
  SearchResultCount := counter;
end;

procedure TSearchResultForm.VST_SearchResultDblClick(Sender: TObject);
var
  tmpSelectedText: string;
  I: Integer;
  Node: PVirtualNode;
  Daten: TOSearchResult;
begin
  with MainForm do
  begin
    M_Description.SelAttributes.Style := [];
    M_Description.SelAttributes.Color := clWindowText;
    Node := VST_SearchResult.FocusedNode;
    Daten := TOSearchResult(VST_SearchResult.GetNodeData(Node)^);
    tmpSelectedText := Daten.Ueberschrift;
    for I := 0 to TV_Category.Items.Count - 1 do
      if tmpSelectedText = TV_Category.Items.Item[i].Text then
        with TV_Category do
        begin
          Selected := Items.Item[i];
          Selected.SelectedIndex := 2;
          Selected.ImageIndex := 2;
          TV_CategoryChange(Sender,Selected);
        end;
  end;
end;

procedure TSearchResultForm.VST_SearchResultFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  daten: TOParentPos;
begin
  daten := TOParentPos(VST_SearchResult.GetNodeData(Node)^);
  daten.free;
end;

procedure TSearchResultForm.VST_SearchResultGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
  daten: TOSearchResult;
begin
  daten := TOSearchResult(VST_SearchResult.GetNodeData(Node)^);
  case Column of
    0: CellText := IntToStr(daten.Number);
    1: if daten is TOSearchResult then
         CellText := daten.Kategorie
       else
         CellText := TOParentPos(daten).Reiter;
    2: if daten is TOSearchResult then
         CellText := daten.Ueberschrift
       else
         CellText := TOParentPos(daten).TextSnip;
  end;
end;
Der VST wird passend mit den Daten aus der Klasse TOSearchResult gefüllt, wie im Bild in Level 0. Nur wenn ich jetzt die Node aufklappen will, kommt eine EAccessViloation. In dem Feld "Reiter" soll zum Beispiel "Sourcecode (2:40)" stehen und im Textsnip dann ein Ausschnitt rund um das Suchwort.

Was habe ich falsch gemacht ?

mirage228 5. Sep 2009 13:12

Re: VST und Gruppenbildung
 
Müssen die Node-Daten nicht als Record gespeichert werden?

Delphi-Quellcode:
PNodeData = ^TNodeData;
TNodeData = record
  Daten: TOParentPos;
end;

// FormCreate
VST.NodeDataSize := SizeOf(TNodeData);

// Hinzufügen
var
  Node: PVirtualNode;
  Data: PNodeData;
begin
  Node := VST.AddChild(nil);
  VST.ValidateNode(Node, False);
  Data := VST.GetNodeData(Node);
  Data.Daten := ...
end;

RWarnecke 5. Sep 2009 13:18

Re: VST und Gruppenbildung
 
Nee, kannste auch über Objekte machen. Denn wenn ich Zeile 46-49 aus meinem Sourcecode aus Beitrag #1 entnehme habe ich keinerlei Probleme.

generic 5. Sep 2009 14:32

Re: VST und Gruppenbildung
 
Zitat:

Zitat von mirage228
Müssen die Node-Daten nicht als Record gespeichert werden?

Nein, der VST nutzt nur aus Geschwindigkeitsgründen Records, da diese direkt als Block allociert werden können.
Eigentlich werden Zeiger gespeichert, wo diese hin Zeigen ist egal.


Das Problem ist (wie du schon festgestellt hast) in der onGetText Methode.
Deine Typprüfungen und die Casts sehen etwas kompliziert aus.

daten würde ich als ParentPos deklarieren und dann nur zu dem SeachResult casten.
Ich denke dort liegt irgendwo der Fehler.

RWarnecke 5. Sep 2009 15:31

Re: VST und Gruppenbildung
 
Zitat:

Zitat von generic
Das Problem ist (wie du schon festgestellt hast) in der onGetText Methode.
Deine Typprüfungen und die Casts sehen etwas kompliziert aus.

daten würde ich als ParentPos deklarieren und dann nur zu dem SeachResult casten.
Ich denke dort liegt irgendwo der Fehler.

Erstmal danke für Deinen Hinweis. Ich habe jetzt das OnGetText-Ereignis so abgeändert :
Delphi-Quellcode:
procedure TSearchResultForm.VST_SearchResultGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
  daten: TOParentPos;
begin
  daten := TOParentPos(VST_SearchResult.GetNodeData(Node)^);
  case Column of
    0: CellText := IntToStr(TOSearchResult(daten).Number);
    1 : begin
          if daten is TOParentPos then
            CellText := daten.Position;
          if daten is TOSearchResult then
            CellText := TOSearchResult(daten).Kategorie;
        end;
    2 : begin
          if daten is TOParentPos then
            CellText := daten.TextSnip;
          if daten is TOSearchResult then
            CellText := TOSearchResult(daten).Ueberschrift;
        end;
  end;
end;
So funktioniert es jetzt, ich habe aber noch ein Verständnisproblem dabei, wieso meine andere IF-Abfrage aus Beitrag #1 nicht funktioniert und warum ich das ganze umdrehen muss ?

generic 5. Sep 2009 16:17

Re: VST und Gruppenbildung
 
Vermutung:
Du greifst auf ein Such Objekt zu, obwohl es ein Pos Element ist.
Durch den Typcast gaukelst also ein Objekt mit Eigenschaften vor, welche nicht vorhanden sind.
Daher dann die AV.

Ich würde da hier noch ändern:
Delphi-Quellcode:
          if daten is TOParentPos then
            CellText := daten.Position;
          if daten is TOSearchResult then
            CellText := TOSearchResult(daten).Kategorie;
in

Delphi-Quellcode:
          if daten is TOSearchResult then
            CellText := TOSearchResult(daten).Kategorie
          else
            CellText := daten.Position;

RWarnecke 5. Sep 2009 17:42

Re: VST und Gruppenbildung
 
Das sind nur ganz einfache Namen. Die Namen habe ich nur deshalb gewählt, weil es in meinem Suchformular ist. Ich könnte auch TOMeineDaten für TOSearchResult schreiben und TOPositionen für TOParentPos.

Edit: Jetzt habe ich nur noch ein kleines Problem, wenn ich jetzt die Node öffne, werden mir die SubNodes richtig angezeigt, nur durch häufiges auf und zu, bekomme ich wieder eine Exception. Habe ich da noch etwas vergessen ?

omata 5. Sep 2009 18:05

Re: VST und Gruppenbildung
 
Delphi-Quellcode:
procedure TSearchResultForm.VST_SearchResultGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: WideString);
var
  daten: TObject;
begin
  daten := VST_SearchResult.GetNodeData(Node)^;
  case Column of
    0: if daten is TOSearchResult then
         CellText := IntToStr(TOSearchResult(daten).Number);
    1: begin
         if daten is TOParentPos then
           CellText := TOParentPos(daten).Position
         else if daten is TOSearchResult then
           CellText := TOSearchResult(daten).Kategorie;
       end;
    2: begin
         if daten is TOParentPos then
           CellText := TOParentPos(daten).TextSnip
         else if daten is TOSearchResult then
           CellText := TOSearchResult(daten).Ueberschrift;
       end;
  end;
end;

RWarnecke 5. Sep 2009 18:20

Re: VST und Gruppenbildung
 
Hallo omata,

wenn ich Dein Beispiel ausprobiere, bekomme ich den folgenden Fehler in Zeile 7 :
Zitat:

Incompatible types: 'Tobject' and 'procedure, untyped pointer or untyped parameter'
Zumal ich auch nicht ganz den Hintergrund von Deinem Beispiel verstehe.

omata 5. Sep 2009 18:24

Re: VST und Gruppenbildung
 
Dann ignoriere einfach meinen Beitrag, sorry, dass ich was gesagt habe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02: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 by Thomas Breitkreuz