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 Problem mit Pointer beim VirtualStringTree (https://www.delphipraxis.net/144292-problem-mit-pointer-beim-virtualstringtree.html)

Jens Hartmann 4. Dez 2009 10:37


Problem mit Pointer beim VirtualStringTree
 
Hallo zusammen,

ich habe ein Problem mit einem VST. Ich möchte Daten aus einer Datenbank in folgendem Aufbau anzeigen.

Code:
-Kunde
  -Zentrale
    -Port
    -IP
Jetzt habe ich das über folgende Weg versucht, bekomme allerdings eine Fehlermeldung beim beenden von meinem Programm, das der Zeiger ungültig ist. Der Fehler muss irgendwo bei FreeNode auftreten.

Hier mal der Code...

Delphi-Quellcode:
  //Einfügen der Daten

  DM_PS.ConPSConfig.Connect;
  DM_PS.Qry_VSTSystemCreate.Open;

  DataSys := TOSYSTEM.Create;
  VSTSystem.BeginUpdate;
  with DataSys do
  begin
  DataSys.Objekt := DM_PS.Qry_VSTSystemCreate.FieldByName('KUNDE').AsString;
  case DM_PS.Qry_VSTSystemCreate.FieldByName('ZENTRALENTYP').AsInteger of
        0: DataSys.Zentrale := 'NOVAR HB/MB 24';
        1: DataSys.Zentrale := 'NOVAR HB/MB 48';
        2: DataSys.Zentrale := 'NOVAR MB100';
        3: DataSys.Zentrale := 'NOVAR MB256';
        4: DataSys.Zentrale := 'BOSCH UEZ2000';
        5: DataSys.Zentrale := 'NOVAR BMC 1024';
        6: DataSys.Zentrale := 'ESSER IQ8 Control';
        7: DataSys.Zentrale := 'SONSTIGE';
      end;
  DataSys.COM := 'COM 1, 9600,8,1';
  DataSys.IP := '192.168.100.101';
  end;

  pNode := VSTSystem.AddChild(nil,DataSys);
  pNode := VSTSystem.AddChild(pNode,DataSys);
  pNode := VSTSystem.AddChild(pNode,DataSys);
  VSTSystem.AddChild(pNode,DataSys);

  VSTSystem.EndUpdate;
  VSTSystem.Refresh;

//FreeNode
var
  DataSys : TOSYSTEM;
begin
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  DataSys.Free;
:gruebel:

Danke schon mal

und Gruß

Jens

sirius 4. Dez 2009 10:41

Re: Problem mit Pointer beim VirtualStringTree
 
Naja, du weist 4mal dem VST dasselbe Objekt zu. dadurch (wenn es initialisiert ist) wird es auch viermal gelöscht, was quasi dreimal zu viel ist.

himitsu 4. Dez 2009 10:48

Re: Problem mit Pointer beim VirtualStringTree
 
laß mal das ^ weg
Delphi-Quellcode:
DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node));
du hat ja die Instanz gespeichert und nicht einen Zeiger auf die Instanz, also brauchst/darfst du auch nicht dereferenzieren :zwinker:


Und dann natürlich das von sirius schon Gesagte.


PS: wozu das With, wenn du dann eh die Variable wieder verwendest?
Delphi-Quellcode:
with DataSys do
  begin
  DataSys.

Jens Hartmann 4. Dez 2009 10:51

Re: Problem mit Pointer beim VirtualStringTree
 
Ja das habe ich mir auch schon gedacht, allerdings weiß ich nicht so recht, wie ich den Aufbau des VST hinbekomme.

Code:
-Level1
  -Level2
    -Level3
    -Level3

himitsu 4. Dez 2009 10:57

Re: Problem mit Pointer beim VirtualStringTree
 
Edit mißt, daß dereferenzieren war hier ja nötig :wall:
also nur sirius's vorschlag.


Entweder du gibts beim Fregeiben nur das Objekt vom Elternnode (Level1) frei und nicht bei den SubNodes,
dann wird es auch nur einmal Freigegeben

oder du gibst nur dem Elternnode das Objekt
Delphi-Quellcode:
pNode := VSTSystem.AddChild(nil, DataSys);
pNode := VSTSystem.AddChild(pNode);
pNode := VSTSystem.AddChild(pNode);
VSTSystem.AddChild(pNode);
und wenn du jetzt auf das Objekt zugreifen willst, dann prüfst du dort.

- ist TOSYSTEM(VSTSystem.GetNodeData(Node)^) = nil dann nimm das vom ParentNode (ist es da auch auch NIL geht es so weiter, bis das Objekt gefunden wurde)

Jens Hartmann 4. Dez 2009 11:01

Re: Problem mit Pointer beim VirtualStringTree
 
Ja, das hatte ich so auch schon mal versucht...
Delphi-Quellcode:
  pNode := VSTSystem.AddChild(nil,DataSys);
  pNode := VSTSystem.AddChild(pNode);
  pNode := VSTSystem.AddChild(pNode);
  VSTSystem.AddChild(pNode);
allerdings, stimmt dan irgendwo was bei meiner GetText Anweisung nicht.

Delphi-Quellcode:
var
  DataSys : TOSYSTEM;  // ein Zeiger auf die Datenstruktur
begin
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  case VSTSystem.GetNodeLevel(Node) of
  0: case Column of
        0: Celltext := DataSys.Objekt;
      end;
  1: case Column of
        0: Celltext := DataSys.Zentrale;
      end;
  2: case Column of
        0: Celltext := DataSys.IP;
      end;
  3: case Column of
        0: Celltext := DataSys.COM;
      end;
  end;
end;

himitsu 4. Dez 2009 11:19

Re: Problem mit Pointer beim VirtualStringTree
 
müßte dann wohl irgendwie so aussehn ... in diesem Fall müßtest du ja erstmal den Node suchen.
Delphi-Quellcode:
var
  Node: PVirtualNode;
  Level: Integer;
  DataSys : TOSYSTEM;  // ein Zeiger auf die Datenstruktur
begin
  Level := VSTSystem.GetNodeLevel(Node);
  while TOSYSTEM(VSTSystem.GetNodeData(Node)^) = nil do
    Node := Node.ParentNode;
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  case Level of
  0: case Column of
        0: Celltext := DataSys.Objekt;
      end;
  1: case Column of
        0: Celltext := DataSys.Zentrale;
      end;
  2: case Column of
        0: Celltext := DataSys.IP;
      end;
  3: case Column of
        0: Celltext := DataSys.COM;
      end;
  end;
end;

Jens Hartmann 4. Dez 2009 11:44

Re: Problem mit Pointer beim VirtualStringTree
 
Der Ansatz könnte stimmen. jedoch kennt Delphi

Delphi-Quellcode:
  while TOSYSTEM(VSTSystem.GetNodeData(Node)^) = nil do
    pNode := pNode.ParentNode;
ParentNode nicht.

himitsu 4. Dez 2009 12:01

Re: Problem mit Pointer beim VirtualStringTree
 
Zitat:

Zitat von Jens Hartmann
jedoch kennt Delphi ParentNode nicht.

ich hab jetzt leider nicht den Aufbau des VST im Kopf ... aber irgendwie muß es ja möglich sein, den Parent eines Nodes abzufragen :stupid:

Jens Hartmann 4. Dez 2009 12:07

Re: Problem mit Pointer beim VirtualStringTree
 
Ja, die wird es geben. Ich denke auch das es so funktonieren müsste

Delphi-Quellcode:
    pNode := pNode.Parent;
Allerdings, kommt es dann immer genau an der Stelle zu einem Zugriffsfehler, wenn ich den Knoten über Mausklick Erweitern will.

sirius 4. Dez 2009 12:20

Re: Problem mit Pointer beim VirtualStringTree
 
Das ganze Konzept ist falsch.

Du kannst nicht mehreren Knoten dasselbe Objekt zuweisen.
Baue für jeden Knotentype eine eigene Klasse, welche du von einer abstrakten Klasse ableitest. Die Abstrakte Klasse stellt die einheitliche Schnittstelle für bspw. den NodeText dar.
Speicher die Objekte in einer eigenen Liste und gib diese separat frei, dann brauchst du auch bei OnFreeNode nix zu machen (onFreeNode wird nämlich nicht für jeden Konten immer aufgerufen (siehe MAN))


Edit:
Hier ist ein Besipiel (Beitrag #4).

himitsu 4. Dez 2009 12:28

Re: Problem mit Pointer beim VirtualStringTree
 
Delphi-Quellcode:
pNode := VSTSystem.AddChild(nil,DataSys);
pNode := VSTSystem.AddChild(pNode);
pNode := VSTSystem.AddChild(pNode);
VSTSystem.AddChild(pNode);
Hier wäre nur einem Knoten das Objekt zugewiesen und die untergeordneten Objekte holen sich die Daten dann von dort.


Nocheine Alternative wäre:
man hält die Objekte in einer weiteren Liste, welche diese Objekte verwaltet und später auch freigibt
und er VST bekommt die Objekte in jedem Node zugeordnet, wo er sie braucht, aber der VST sorgt nicht für deren Freigabe.


Zitat:

Zitat von Jens Hartmann
Allerdings, kommt es dann immer genau an der Stelle zu einem Zugriffsfehler, wenn ich den Knoten über Mausklick Erweitern will.

stimmt das mit dem Node auch?
Code:
while TOSYSTEM(VSTSystem.GetNodeData([color=#ff0000][b]p[/b][/color]Node)^) = nil do
    [color=#ff0000][b]p[/b][/color]Node := [color=#ff0000][b]p[/b][/color]Node.ParentNode;

Jens Hartmann 4. Dez 2009 12:42

Re: Problem mit Pointer beim VirtualStringTree
 
Ja, das stimmt. ich habe pNode deklariert.

Delphi-Quellcode:
var
  pNode : PVirtualNode;
  Level: Integer;
  DataSys : TOSYSTEM;  // ein Zeiger auf die Datenstruktur
begin
  Level := VSTSystem.GetNodeLevel(Node);
  while TOSYSTEM(VSTSystem.GetNodeData(pNode)^) = nil do
    pNode := pNode.Parent;
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  case Level of
  0: case Column of
        0: Celltext := DataSys.Objekt;
      end;
  1: case Column of
        0: Celltext := DataSys.Zentrale;
      end;
  2: case Column of
        0: Celltext := DataSys.IP;
      end;
  3: case Column of
        0: Celltext := DataSys.COM;
      end;
  end;
end;
Ein weiteres Problem, wäre ja auch die Zuordnung von Level 2, ich möchte dem Level mehrer verschieden Einträge zuordnen, die aber im selben Objekt stehen.

siehe DataSys.IP und DataSys.COM

Irgendwie stehe ich momentan total auf der Leitung.
:gruebel:
Gruß Jens

himitsu 4. Dez 2009 12:47

Re: Problem mit Pointer beim VirtualStringTree
 
Code:
v = der tatsächliche Level

0 -Level1
1   -Level2
2     -Level3
[color=#ff0000]2     -Level3[/color]
Code:
var
  Level: Integer;
  DataSys : TOSYSTEM;
begin
  Level := VSTSystem.GetNodeLevel(Node);
  while TOSYSTEM(VSTSystem.GetNodeData(Node)^) = nil do
    Node := Node.Parent;
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  case Level of
  0: case Column of
        0: Celltext := DataSys.Objekt;
      end;
  1: case Column of
        0: Celltext := DataSys.Zentrale;
      end;
  2: case Column of
        0: Celltext := DataSys.IP;
      end;
  [color=#ff0000]3: case Column of
        0: Celltext := DataSys.COM;
      end;[/color]
  end;
end;
oder
Code:
var
  [color=#0000ff][b]p[/b][/color]Node: PVirtualNode;
  Level: Integer;
  DataSys : TOSYSTEM;
begin
  [color=#0000ff][b]p[/b][/color]Node := Node;
  Level := VSTSystem.GetNodeLevel([color=#0000ff][b]p[/b][/color]Node);
  while TOSYSTEM(VSTSystem.GetNodeData([color=#0000ff][b]p[/b][/color]Node)^) = nil do
    [color=#0000ff][b]p[/b][/color]Node := [color=#0000ff][b]p[/b][/color]Node.Parent;
  DataSys := TOSYSTEM(VSTSystem.GetNodeData([color=#0000ff][b]p[/b][/color]Node)^);
  case Level of
  0: case Column of
        0: Celltext := DataSys.Objekt;
      end;
  1: case Column of
        0: Celltext := DataSys.Zentrale;
      end;
  2: case Column of
        0: Celltext := DataSys.IP;
      end;
  [color=#ff0000]3: case Column of
        0: Celltext := DataSys.COM;
      end;[/color]
  end;
end;

Jens Hartmann 4. Dez 2009 13:01

Re: Problem mit Pointer beim VirtualStringTree
 
Das mit dem Level3 ist mir klar.

Delphi-Quellcode:
  2: case Column of
        0: Celltext := DataSys.IP;
      end;
  3: case Column of
        0: Celltext := DataSys.COM;
      end;
  end;
Allerdings, wie füge ich die dann direkt hintereinander ein. Weil ich kann ja schlecht schreiben

Delphi-Quellcode:
  3: case Column of
        0: Celltext := DataSys.COM;
        0: Celltext := DataSys.IP;
      end;
  end;

himitsu 4. Dez 2009 13:40

Re: Problem mit Pointer beim VirtualStringTree
 
tja, das ist halt ein Problem in deiner Implementierung.

Wenn alles in einer Struktur stehen soll, dann brauchst du eine zuverlässige Methode die Nodes zu unterscheiden.

Kann man eigentlich einen Index erhalten? (also der wievielte SubNode es innerhalb des Eltern-Knotens ist?)

Delphi-Quellcode:
var
  Level, Index: Integer;
  DataSys : TOSYSTEM;
begin
  Level := VSTSystem.GetNodeLevel(Node);
  Index := VSTSystem.GetNodeIndex(Node); // oder irgendwie so, aber
  // nicht der globale Index, sondern nur der im Verhältnis zum Parent-Node
  while TOSYSTEM(VSTSystem.GetNodeData(Node)^) = nil do
    Node := Node.Parent;
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  case Level of
  0: case Column of
        0: Celltext := DataSys.Objekt;
      end;
  1: case Column of
        0: Celltext := DataSys.Zentrale;
      end;
  2: case Index of
        0: case Column of
             0: Celltext := DataSys.IP;
           end;
        1: case Column of
             0: Celltext := DataSys.COM;
           end;
      end;
  end;
end;
Aber so ist es schwer mal etwas einzufügen oder zu ändern, da diese Indize ganz genau mit der Erstellung abhängen.
Wenn man da was einfügt, dann muß man es auch überll ändern, sonst gibt es Probleme.

Also einfacher wäre es, wenn du

- entweder für jeden Node ein eigenes Objekt erstellt, so nur die zugehörige Info drinsteht

- oder du nutzt ein Trägerobjekt
also ein Objekt, wo du dein TOSYSTEM drin ablegst und welches entweder ein Feld "Text" hat, welches für die Anzeige genutzt wird
oder wo zumindestens gespeichert wird, welche Wert des TOSYSTEM nun in genau diesem Node angezeigt werden soll.

Jens Hartmann 4. Dez 2009 14:24

Re: Problem mit Pointer beim VirtualStringTree
 
Das wäre möglich.

Den Anfang dafür hatte ich auch schon mal..

Delphi-Quellcode:
  TOOBJEKT = class
    private
      Objekt    : String;
      ImageIndex : Integer;
  end;

  TOSYSTEM = class
    private
      Zentrale    : String;
      ImageIndex : Integer;
  end;

  TODATASYS = class
    private
      COM, IP    : String;
      ImageIndex : Integer;
  end;
Aber wie kann ich dann die Größe von NodeDataSize festlegen...

Delphi-Quellcode:
  VSTSystem.NodeDataSize := SizeOf(TOSYSTEM);
Gruß Jens

Jens Hartmann 4. Dez 2009 14:48

Re: Problem mit Pointer beim VirtualStringTree
 
Es kann ja auch eigendlich nicht so schwer sein, es ist ja vom Prinzip her nichts anderes als ein Explorer.

Da gibt es ja auch solche Herachien...

Code:
Level 1
  - Level 2
  - Level 2
    - Level3
  - Level 2
    - Level 3
    - Level 3

etc....
Das Problem, was ich sehe, ich habe schon viele Tutorials gelesen, in dennen man diese Struktur erstellen kann. Aber noch nicht herausgefunden, wie man dann die Daten zuweisen tut.

Gruß Jens

Jens Hartmann 4. Dez 2009 15:12

Re: Problem mit Pointer beim VirtualStringTree
 
Ich habe jetzt hier mal noch den gesamten aktuelle Code der das VST Betrifft.

Vieleicht hilt das ja weiter. Irgendwie glaube ich, ist da noch ein Gedankenfehler von mir drin...

Delphi-Quellcode:
//Die OBJEKTE
  TOOBJEKT = class
    private
      Objekt    : String;
      ImageIndex : Integer;
  end;

  type TOSYSTEM = class
    private
      Zentrale    : String;
      ImageIndex : Integer;
    end;


  TODATASYS = class
    private
      COM, IP    : String;
      ImageIndex : Integer;
  end;
//im FormCreate
VSTSystem.NodeDataSize := SizeOf(TOSYSTEM); //Aber ja Vermutlich nicht ganz richtig, da ich ja mehrere Objekte zur Zeit nutze.
VSTSystemCreate;

//Durch FormCreate aufgerufen
procedure TForm1.VSTSystemCreate;
var
  DataObj : TOOBJEKT;
  DataSys : TOSYSTEM;
  Data    : TODATASYS;
  pNode :pVirtualNode; // ein Pointer auf Knoten
  i : integer;
begin
  DM_PS.ConPSConfig.Connect;
  DM_PS.Qry_VSTSystemCreate.Open;

  DataObj := TOOBJEKT.Create;
  DataSys := TOSYSTEM.Create;
  Data   := TODATASYS.Create;

  VSTSystem.BeginUpdate;

  DataObj.Objekt := DM_PS.Qry_VSTSystemCreate.FieldByName('KUNDE').AsString;

  case DM_PS.Qry_VSTSystemCreate.FieldByName('ZENTRALENTYP').AsInteger of
        0: DataSys.Zentrale := 'NOVAR HB/MB 24';
        1: DataSys.Zentrale := 'NOVAR HB/MB 48';
        2: DataSys.Zentrale := 'NOVAR MB100';
        3: DataSys.Zentrale := 'NOVAR MB256';
        4: DataSys.Zentrale := 'BOSCH UEZ2000';
        5: DataSys.Zentrale := 'NOVAR BMC 1024';
        6: DataSys.Zentrale := 'ESSER IQ8 Control';
        7: DataSys.Zentrale := 'SONSTIGE';
      end;

  Data.COM := 'COM 1, 9600,8,1';
  Data.IP := '192.168.100.101';

  pNode := VSTSystem.AddChild(nil,DataObj);
  pNode := VSTSystem.AddChild(pNode,DataSys);
  pNode := VSTSystem.AddChild(pNode,Data);

  VSTSystem.EndUpdate;
  VSTSystem.Refresh;
end;

//Ereignisse vom VST
procedure TForm1.VSTSystemFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  DataObj : TOOBJEKT;
  DataSys : TOSYSTEM;
  Data   : TODATASYS;
begin
  DataObj := TOOBJEKT(VSTSystem.GetNodeData(Node)^);
  DataObj.Free;
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  DataSys.Free;
  Data := TODATASYS(VSTSystem.GetNodeData(Node)^);
  Data.Free;
end;


procedure TForm1.VSTSystemGetImageIndex(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
  var Ghosted: Boolean; var ImageIndex: Integer);
begin
  case Sender.GetNodeLevel(Node) of
    0: ImageIndex := 0;
    else ImageIndex := -1;
  end;
end;

procedure TForm1.VSTSystemGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  pNode: PVirtualNode;
  Level, Index: Integer;
  DataObj : TOOBJEKT;
  DataSys : TOSYSTEM;
  Data   : TODATASYS;
begin
  DataObj := TOOBJEKT(VSTSystem.GetNodeData(Node)^);
  DataSys := TOSYSTEM(VSTSystem.GetNodeData(Node)^);
  Data   := TODATASYS(VSTSystem.GetNodeData(Node)^);

  Level := VSTSystem.GetNodeLevel(Node);

  case Level of
    0: Celltext := DataObj.Objekt;
    1: Celltext := DataSys.Zentrale;
    2: Celltext := Data.COM;
  end;
end;
Ich hoffe das hilft weiter.

Danke schon mal

Gruß Jens

Jens Hartmann 5. Dez 2009 18:00

Re: Problem mit Pointer beim VirtualStringTree
 
Hallo zusammen,

hat den keiner irgendeinen Tip. Vieleicht noch als Hinweis.

Ich habe eine Datenbank, in der mehrere Tabellen existieren. Ich möchte diese im VST anzeigen. Und zwar in folgender Darstellung...

Code:
-Tabelle 1
  -Inhalt Spalte 1
  -Inhalt Spalte 2
  -Inhalt Spalte 3
  -Inhalt Spalte 4
-Tabelle 2
  -Inhalt Spalte 1
    -Wert 1
    -Wert 2
    -Wert 3
  -Inhalt Spalte 2
    -Wert 1
    -Wert 2
    -Wert 3
  -Inhalt Spalte 3
    -Wert 1
    -Wert 2
    -Wert 3
Bin leider noch kein Stück weiter gekommen.

Danke schon mal

Gruß Jens

Jens Hartmann 5. Dez 2009 23:55

Re: Problem mit Pointer beim VirtualStringTree
 
Liste der Anhänge anzeigen (Anzahl: 2)
Schönen guten Abend nochmal zusammen,

Ich bin jetzt ein Stück weiter, allerdings denke ich das es der falsche Weg ist, und außerdem ist auch noch eine Fehler drin.

Ich habe jetzt einfach mal so zum Test 4 GLOBALE Variablen angelegt, die ich beim CREATE initialisiere und in die GetText Methode einbinde.
Funktioniert auch jetzt genau so wie ich mir das vorstelle (siehe ScreenShot1), bis auf wenn ich eine Ebene über das - Zeichen Expandiere, kann ich diese Ebene nie wieder FullExpanded setzen(siehe Anhang 2).

Außerdem, gefällt mir das mit den GLOBALEN Var. nicht.

hier mal der aktuelle Code...
Delphi-Quellcode:
procedure TForm1.VSTSystemCreate;
var
  pNode :pVirtualNode;
begin
  DM_PS.ConPSConfig.Connect;
  DM_PS.Qry_VSTSystemCreate.Open;
  Objekt := DM_PS.Qry_VSTSystemCreate.FieldByName('KUNDE').AsString;
  case DM_PS.Qry_VSTSystemCreate.FieldByName('ZENTRALENTYP').AsInteger of
        0: Zentrale := 'NOVAR HB/MB 24';
        1: Zentrale := 'NOVAR HB/MB 48';
        2: Zentrale := 'NOVAR MB100';
        3: Zentrale := 'NOVAR MB256';
        4: Zentrale := 'BOSCH UEZ2000';
        5: Zentrale := 'NOVAR BMC 1024';
        6: Zentrale := 'ESSER IQ8 Control';
        7: Zentrale := 'SONSTIGE';
      end;
  COMPort := 'COM 1, 9600,8,1';
  IPPort := '192.168.100.101';
  DM_PS.Qry_VSTSystemCreate.Close;
 
  VSTSystem.BeginUpdate;
  pNode := VSTSystem.AddChild(nil);
  pNode := VSTSystem.AddChild(pNode);
  VSTSystem.AddChild(pNode);
  VSTSystem.AddChild(pNode);
  VSTSystem.EndUpdate;
end;

procedure TForm1.VSTSystemGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Level : Integer;
begin
Level := VSTSystem.GetNodeLevel(Node);
if Column = 0 then
  begin
    if Level = 0 then
      CellText := Objekt;
    if Level = 1 then
      CellText := Zentrale;
    if Level = 2 then
      begin
        if Node.Index = 0 then
          CellText := IPPort
        else
          CellText := COMPort
      end;
  end;
end;
Gruß Jens

Jens Hartmann 6. Dez 2009 11:24

Re: Problem mit Pointer beim VirtualStringTree
 
Einen wunderschönen guten Morgen zusammen,

so nach einer langen Nacht und viel Geduld, habe ich meine Problem jetzt gelößt. Die Lösung habe ich jetzt über ein Record gemacht und die Daten über folgende Ausführung zugewiesen. Ich bin mir allerdings nicht sicher, ob es so gut gelößt ist,das ich nicht irgendwo Probleme bekomme.

Die Lösung funktioniert zwar, aber vieleicht kann ja mal jemand von Euch sich den Weg dazu ansehen.

Hier meine Lösung...

Delphi-Quellcode:
type pNodeData = ^rNodeData;
     rNodeData = record
        Objekt : String;
        Zentrale : String;
        IPPort : String;
        COMPort : String;
end;

...

implementation

....

function GetLocalIPs(const Lines:TStrings):Boolean;
type
  PPInAddr= ^PInAddr;
var
  wsaData: TWSAData;
  HostInfo: PHostEnt;
  HostName: Array[0..255] of Char;
  Addr: PPInAddr;
begin
  Result:=False;
  Lines.Clear;
  if WSAStartup($0102, wsaData)=0 then
  try
    if gethostname(HostName, SizeOf(HostName)) = 0 then Begin
       HostInfo:= gethostbyname(HostName);
       if HostInfo<>nil then Begin
          Addr:=Pointer(HostInfo^.h_addr_list);
          if (Addr<>nil) AND (Addr^<>nil) then
             Repeat
                    Lines.Add(StrPas(inet_ntoa(Addr^^)));
                    inc(Addr);
             Until Addr^=nil;
       end;
    end;
    Result:=True;
  finally
    WSACleanup;
  end;
end;

...

procedure TForm1.Create;
begin
...
VSTSystemCreate;
...
end;

procedure TForm1.VSTSystemCreate;
var
  pNode :pVirtualNode;
begin
  VST.Clear;
  VSTSystem.BeginUpdate;
  pNode := VSTSystem.AddChild(nil);
  pNode := VSTSystem.AddChild(pNode);
  VSTSystem.AddChild(pNode);
  VSTSystem.AddChild(pNode);
  VSTSystem.EndUpdate;
end;

procedure TForm1.VSTSystemFreeNode(Sender: TBaseVirtualTree;
  Node: PVirtualNode);
var
  pdata : pNodeData;
begin
  pdata := Sender.GetNodeData(Node);
    if Assigned(pdata) then
      begin
        pdata.Objekt := '';
        pdata.Zentrale := '';
        pdata.COMPort := '';
        pdata.IPPort := '';
      end;
end;

procedure TForm1.VSTSystemGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
var
  Level : Integer;
  pdata : pNodeData;
begin
  pdata := Sender.GetNodeData(Node);
  Level := VSTSystem.GetNodeLevel(Node);
    if Level = 0 then
      CellText := pdata.Objekt;
    if Level = 1 then
      CellText := pdata.Zentrale;
    if Level = 2 then
      begin
        if Node.Index = 0 then
          CellText := pdata.IPPort
        else
          CellText := pdata.COMPort;
      end;
end;

procedure TForm1.VSTSystemInitNode(Sender: TBaseVirtualTree; ParentNode,
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
var
  pdata : pNodeData;
  BaudRate : String;
  Stopbit : String;
  Databit : String;
  IPLokal : TStringList;
begin
  DM_PS.ConPSConfig.Connect;
  DM_PS.Qry_VSTSystemCreate.Open;

  pdata := Sender.GetNodeData(Node);

  pdata.Objekt := DM_PS.Qry_VSTSystemCreate.FieldByName('KUNDE').AsString;
  case DM_PS.Qry_VSTSystemCreate.FieldByName('ZENTRALENTYP').AsInteger of
        0: pdata.Zentrale := 'NOVAR HB/MB 24';
        1: pdata.Zentrale := 'NOVAR HB/MB 48';
        2: pdata.Zentrale := 'NOVAR MB100';
        3: pdata.Zentrale := 'NOVAR MB256';
        4: pdata.Zentrale := 'BOSCH UEZ2000';
        5: pdata.Zentrale := 'NOVAR BMC 1024';
        6: pdata.Zentrale := 'ESSER IQ8 Control';
        7: pdata.Zentrale := 'SONSTIGE';
      end;

  BaudRate := IntToStr(ComPort1.CustomBaudRate);
  Stopbit := StopBitsToStr(ComPort1.StopBits);
  Databit := DataBitsToStr(ComPort1.DataBits);
  pdata.COMPort := ComPort1.Port+', '+BaudRate+', '+Stopbit+', '+Databit;

  IPLokal := TStringList.Create;
  GetLocalIPs(IPLokal);
  pdata.IPPort := IPLokal.Text;
  IPLokal.Free;

  DM_PS.Qry_VSTSystemCreate.Close;
end;
Danke schon mal,

Gruß

Jens


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