Delphi-PRAXiS
Seite 1 von 3  1 23      

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: Es klappt nicht ganz (https://www.delphipraxis.net/70508-virtualtreeview-es-klappt-nicht-ganz.html)

JPSelter 31. Mai 2006 11:06


VirtualTreeView: Es klappt nicht ganz
 
So, jetzt stosse ich an erste Probleme. Ich habe ein Objekt erzeugt und möchte es an den Baum anhängen. Da läuft er auch durch, aber am Ende (scheinbar bevor er den VTV anzeigen will) kommt eine EAccessViolation. Ich kann den Fehler leider nicht ganz zurückverfolgen, ich weiss nur, dass er aus der VTV Klasse kommt. Delphi bleibt in der Funktion TCustomVirtualStringTree.DoGetText stehen, aber auch nach 2-maligem Durchlauf von TBaseVirtualTree.WndProc. Hier erstmal mein bisheriger Code:

Objekt-Definition:
Delphi-Quellcode:
// Ebene 0: Sitzungsdaten
  TSessionObject = class
    private
      fdatum: integer;
      fsessiontyp: string;
      fprotokollant: string;
      fteilnehmer: string;
      fverteiler: string;
      fndatum: integer;
    published
      property datum: integer read fdatum write fdatum;
      property sessiontyp: string read fsessiontyp write fsessiontyp;
      property protokollant: string read fprotokollant write fprotokollant;
      property teilnehmer: string read fteilnehmer write fteilnehmer;
      property verteiler: string read fverteiler write fverteiler;
      property ndatum: integer read fndatum write fndatum;
  end;
Neues Objekt wird mit Daten versehen und an den Baum gehangen:
Delphi-Quellcode:
// insert new session
procedure insertSession();
var SessionObject: TSessionObject;
    datum, ndatum: integer;
begin
  Form1.VST1.NodeDataSize:=SizeOf(TTreeData);
  SessionObject:=TSessionObject.Create;
  try
    datum:=DateTimeToUnix(Form1.DateTimePicker1.Date);
    ndatum:=DateTimeToUnix(Form1.DateTimePicker2.Date);
    SessionObject.datum:=datum;
    SessionObject.sessiontyp:=Form1.ComboBox1.Text;
    SessionObject.protokollant:=Form1.Edit1.text;
    SessionObject.teilnehmer:=Form1.Edit2.Text;
    SessionObject.verteiler:=Form1.Edit3.Text;
    SessionObject.ndatum:=ndatum;
    AddVSTObject(Form1.VST1,nil,SessionObject);
  except
    SessionObject.Free;
  end;
end;
Die eigentliche Anhänge-Funktion:
Delphi-Quellcode:
// add new structure into VST
function AddVSTObject(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
  AObject: TObject): PVirtualNode;
var
  Data: PTreeData;
begin
  Result:=AVST.AddChild(ANode);
  AVST.ValidateNode(Result,False);
  Data:=AVST.GetNodeData(Result);
  Data^.FObject:=AObject;
end;
Er läuft da überall ohne Probleme durch, keine Fehlermeldungen, nur am Ende dieses EAccessViolation... vielleicht kennt sich da jemand genauer aus. Danke!

generic 31. Mai 2006 11:24

Re: VirtualTreeView: Es klappt nicht ganz
 
probier mal

Delphi-Quellcode:
vst.addchild(nil, meinobj);
später drauf zugreifen mit:

Delphi-Quellcode:
myobj:=TSessionObject(vst.getnodedate(node)^);

jbg 31. Mai 2006 11:30

Re: VirtualTreeView: Es klappt nicht ganz
 
Die NodeDataSize Eigenschaft hast du aber schon auf die richtige Größe (SizeOf(TTreeData)) gesetzt?

chaosben 31. Mai 2006 11:31

Re: VirtualTreeView: Es klappt nicht ganz
 
Zitat:

Zitat von JPSelter
Delphi-Quellcode:
// add new structure into VST
function AddVSTObject(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
  AObject: TObject): PVirtualNode;

Ich denke es liegt an der Übergabe des Objektes. Probier doch mal das Ganze mit einem "const" vor "AObject". Dann sollte er das Objekt selbst bzw. eine Referenz darauf übergeben. (ich hoffe, ich verwechsel nicht schon wieder alles)

JPSelter 31. Mai 2006 11:34

Re: VirtualTreeView: Es klappt nicht ganz
 
Argh, hab den Fehler gefunden... hatte im Projekt noch Überbleibsel aus dem Tutorial drin, also so Sachen wie vstFreeNode und VSTGetText, die alle ohne Objekte arbeiteten... ach menno :D Exception ist nun weg. Dann bis zur nächsten Frage ;)

JPSelter 31. Mai 2006 12:26

Re: VirtualTreeView: Es klappt nicht ganz
 
Weiter gehts ;)

Ich habe noch nicht viel mit Pointern und Objekten programmiert. Ich will nun die Spalte korrekt beschriften und das Tutorial hat dazu diesen Code:

Delphi-Quellcode:
procedure TForm1.VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: Integer; TextType: TVSTTextType; var Text: WideString);
var
  Data: PTreeData;
begin
  Data:=VST.GetNodeData(Node);

  case Column of
    0: Text := Data.FCaption;
    1: Text := Data.FColumn1;
  end;
end;
Leider ist das noch die Geschichte ohne Objekte und ich frage mich nun, wie ich die Eigenschaften meines Objektes ansprechen soll. Irgendwas mit

Data^.FObject...

oder so?

himitsu 31. Mai 2006 12:42

Re: VirtualTreeView: Es klappt nicht ganz
 
jupp, du mußt halt nur den DatenTyp ändern Data: PTreeData; ist ja ein Pointer auf 'nen Record und du brauchst Data: TSessionObject; ... eine ObjektVariable ist ja schon ein Pointer auf ein Objekt, also kannst du auch gleich dieses nutzen und mußt es nicht nochmal über 'nen Pointer ansprechen ^^

Und dann halt nur noch Data.FObject...

JPSelter 31. Mai 2006 12:46

Re: VirtualTreeView: Es klappt nicht ganz
 
Jepp, das klappt :) Danke!

JPSelter 31. Mai 2006 13:16

Re: VirtualTreeView: Es klappt nicht ganz
 
So, diesmal finde ich aber gar nichts zu diesem Thema: Ich will meinen Baum nun speichern. Das Tutorial behandelt aber nur das Speichern von Strings und Integer, nicht das Speichern von ganzen Objekten. Wie speichere ich da?
Ein Node kann bei mir 3 verschiedene Objekte beinhalten, die ich aber leicht über die Spalten-Nummer identifizieren kann. Ein Node hat also ein FObject, ich kann doch nicht das ganze Objekt speichern oder? Ich muss doch sicher noch IN das Objekt rein und alle Paramter einzeln speichern, oder gehts doch einfacher?

himitsu 31. Mai 2006 13:32

Re: VirtualTreeView: Es klappt nicht ganz
 
Im Grunde muß immer nur der DatenTyp angepasst werden. (abgesehn von den CompilerMagicSachen)
Delphi-Quellcode:
var Data: PString;
var Data: PInteger;
...

Wobei der String nicht dem Pointer übergeben wird (Strings und dynamische Arrays sind halt 'ne CompilerMagicSache), sondern der Pointer zum String gemacht wird und diesem dann erst der String gegeben wird (also andersrum).
Ein AnsiRING) hat ja eine Interne referenzzähling und wenn nur der Pöinter übergeben wird, dann wird der Referenzzähler nicht erhöht und somit kann der String eventuell vorzeigt freigegeben werden.

Wenn dem String z.B. erst in der Prozedur der Inhalt erzeugt/zugewiesen wurde und dann der String auch noch eine Lokale Variable ist, dann wird er ja am Prozedurende freigegeben.

Zitat:

String zuweisen >> Referenzzähler = 1
Pointer übergeben >> Referenzzähler immernoch 1
Prozedurende >> Referenzzähler = Referenzzähler - 1
wenn Referenzzähler = 0 >> string wird freigegeben
Code:
function AddVSTObject(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
  [b]AString: String[/b]): PVirtualNode;
begin
  Result:=AVST.AddChild(ANode);
  AVST.ValidateNode(Result,False);
  Data:=AVST.GetNodeData(Result);
  [b]PString(Data^.FObject)^ := AString;[/b]
end;
Und der Integer ... für den brauchste nichtma Speicher reservieren, da dieser ja genausogroß wie der Pointer ist:
Code:
function AddVSTObject(AVST: TCustomVirtualStringTree; ANode: PVirtualNode;
  [b]AInteger: Integer[/b]): PVirtualNode;
begin
  Result:=AVST.AddChild(ANode);
  AVST.ValidateNode(Result,False);
  Data:=AVST.GetNodeData(Result);
  [b]Data^.FObject := Pointer(AInteger);[/b]
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:20 Uhr.
Seite 1 von 3  1 23      

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