Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy 10 - TTreeview von Server zu Client (https://www.delphipraxis.net/143617-indy-10-ttreeview-von-server-zu-client.html)

schwa226 19. Nov 2009 13:15


Indy 10 - TTreeview von Server zu Client
 
Hi,

ich übertrage per
Delphi-Quellcode:
MyIdTCPClient.IOHandler.Write(fileStream);
Datein zum Server.

Das geht auch. Nun habe ich die Frage ob es auch geht vom Server eine TTreeview zu dem Client zu übertragen!?

Der Client kann ja nur durch ständiges Abfragen des InputBuffers schauen ob Daten da sind:
Delphi-Quellcode:
if not MyIdTCPClient.IOHandler.InputBufferIsEmpty then
Jedoch habe ich keine Idee wie ich den Inhalt der TreeView vom Server zum Client übertrage.
In was umwandeln und dann senden damit der Client die Daten dann wieder in ein seine eigene TreeView eintragen kann?

Angel4585 19. Nov 2009 13:46

Re: Indy 10 - TTreeview von Server zu Client
 
Ich würds in ne XML-Struktur umwandeln und das dann schicken

uoeb7gp 19. Nov 2009 15:45

Re: Indy 10 - TTreeview von Server zu Client
 
Hallo zusammen, kommt drauf an was in dem Treeview sonst noch alles drinnen steckt.
Objekt Referenzen, Daten hinter den Nodes etc.

Da das Teil sowiso Streamingfähig ist --> TreeView1.SaveToStream();
Brauchst nur noch die Referenzen (Memory, Variablen etc. Marshallen und auch im gleichen Stream übertragen)

Sollte ja kein Problem sein.!

lg.

schwa226 20. Nov 2009 07:02

Re: Indy 10 - TTreeview von Server zu Client
 
Habe jetzt versuchsweise ein kopieren eine Treeviews probiert:
Delphi-Quellcode:
procedure TForm2.Button1Click(Sender: TObject);
var
  TreeViewStream : TMemoryStream;
begin

  TreeViewStream := TMemoryStream.Create;
  TreeView1.SaveToStream(TreeViewStream);
  TreeViewStream.Seek(0, soFromBeginning);
  TreeView2.LoadFromStream(TreeViewStream);

  FreeAndNil(TreeViewStream);

end;
Jedoch wird nur der erste Buchstabe des ersten Eintrages von TreeView1 in TreeView2 angezeigt.

Habe auch noch das getestet:
http://www.swissdelphicenter.ch/torr...de.php?id=2124

Da wird dann im INIFile nur das abgespeichert:
Zitat:

[test]
Node0=a
Also auch nur der erste Buchstabe... :wall:

uoeb7gp 20. Nov 2009 11:04

Re: Indy 10 - TTreeview von Server zu Client
 
  • Schwa226 hat geschrieben
    ...jedoch wird nur der Erste Buchstabe angezeigt..

Also Source ist korrekt, bei mir unter D6, D7, D2007 und FPC funktioniert es.
Womöglich streaming Problem von D2009 ???

schwa226 21. Jan 2010 09:34

Re: Indy 10 - TTreeview von Server zu Client
 
Hirzu habe ich noch eine Frage!

Bin nun auf Delphi 2010 umgestiegen. Da geht es eine TreeView in einem Stream abzuspeichern.

Nun habe ich aber noch das Problem, dass beim Stream des TreeView anscheinend die Werte von:

TTreeNode.HasChildren
TTreeNode.ImageIndex
TTreeNode.SelectedIndex

fehlen!

Wie könnte man das nun mit in den Stream einbauen?
Oder mache ich hier etwas falsch?

Der TreeView wird einfach per:
TreeView.SaveToStream(meinStream);
in meinen TMemoryStream übergeben.

ATSV 21. Jan 2010 09:45

Re: Indy 10 - TTreeview von Server zu Client
 
Hallo,
in unserem aktuellen Projekt hatten wir exakt das selbe Problem letzendlich haben wir uns dann dazu entschlossen den gesamten Treeview mit allen wichtigen Attributen etc. in ein XML zu packen, dieses ganz normal an den Client zu schicken und dort wieder in einen Treeview einzulesen.

Läuft bei uns ohne Probleme und alle relevanten Informationen sind da. Wurde ja auch hier im Thread angesprochen :wink:

DataCool 21. Jan 2010 09:57

Re: Indy 10 - TTreeview von Server zu Client
 
@schwa226:

Sehe ich genauso, Treeview als XML Struktur speichern und diese dann in einem Stream und diesen dann verschicken,
sollte das unabhängiste und sicherste sein.

Greetz Data

schwa226 21. Jan 2010 11:57

Re: Indy 10 - TTreeview von Server zu Client
 
Danke für die Hilfe!

Habe es erst einmal so Versucht:
Delphi-Quellcode:
function GetNodeByText
(ATree : TsTreeView; AValue:String;
 AVisible: Boolean): TTreeNode;
var
    Node: TTreeNode;
begin
  Result := nil;
  if ATree.Items.Count = 0 then Exit;
  Node := ATree.Items[0];
  while Node <> nil do
  begin
    if UpperCase(Node.Text) = UpperCase(AValue) then
    begin
      Result := Node;
      if AVisible then
        Result.MakeVisible;
      Break;
    end;
    Node := Node.GetNext;
  end;
end;


procedure StreamToTreeNode(var Tree : TsTreeView; TreeStream : TMemoryStream);

  procedure ProcessTreeItem(var Node : TTreeNode; TreeStream : TMemoryStream);
  var
    ChildNode : TTreeNode;
    TextLength, HasChildren, ImageIndex, SelectedIndex : Integer;
    NodeName : String;
  begin
    while TreeStream.Position < TreeStream.Size do
    begin
      TreeStream.Read(TextLength, SizeOf(Integer));
      TreeStream.Read(NodeName, TextLength);
      TreeStream.Read(ImageIndex, SizeOf(Integer));
      TreeStream.Read(SelectedIndex, SizeOf(Integer));
      TreeStream.Read(HasChildren, SizeOf(Integer));

      //make new child node
      ChildNode:= Tree.Items.AddChild(Node,NodeName);
      ChildNode.ImageIndex := ImageIndex;
      ChildNode.SelectedIndex := SelectedIndex;
      ChildNode.HasChildren := Bool(HasChildren);
    end;
  end; (*ProcessTreeItem*)


var
  Node : TTreeNode;
  TextLength, HasChildren, ImageIndex, SelectedIndex : Integer;
  NodeName : String;
begin

    //get first node from stream:
    TreeStream.Read(TextLength, SizeOf(Integer));
    TreeStream.Read(NodeName, TextLength);
    TreeStream.Read(ImageIndex, SizeOf(Integer));
    TreeStream.Read(SelectedIndex, SizeOf(Integer));
    TreeStream.Read(HasChildren, SizeOf(Integer));

    //check if node exists in treeview:
    Node := GetNodeByText(Tree, NodeName, True);

    //node found:
    if Node <> nil then
    begin
      //clear childs:
      Node.DeleteChildren;
      //add new childs:
      ProcessTreeItem(Node, TreeStream)
    end
    else begin
      //node doesn't exist:
      Node:= Tree.Items.Add(nil,NodeName); //Root node
      Node.ImageIndex := ImageIndex;
      Node.SelectedIndex := SelectedIndex;
      Node.HasChildren := Bool(HasChildren);

      //if stream have more data:
      if TreeStream.Position < TreeStream.Size then
        ProcessTreeItem(Node, TreeStream);
    end;
end;



procedure TreeNodeToStream(TreeNode : TTreeNode; var TreeStream : TMemoryStream);

  procedure ProcessTreeItem(Node : TTreeNode; var TreeStream : TMemoryStream);
  var
    TextLength, HasChildren : Integer;
  begin
    if (Node = nil) then Exit;
    TextLength := Length(Node.Text);
    TreeStream.Write(TextLength, SizeOf(Integer));
    TreeStream.Write(Node.Text, TextLength);
    TreeStream.Write(Node.ImageIndex, SizeOf(Integer));
    TreeStream.Write(Node.SelectedIndex, SizeOf(Integer));
    HasChildren := Integer(Node.HasChildren);
    TreeStream.Write(HasChildren, SizeOf(Integer));
  end; (*ProcessTreeItem*)

var
  i : Integer;
begin

  if TreeNode <> NIL then
  begin
    //Handle Node itself
    ProcessTreeItem(TreeNode, TreeStream);

    //Handle Childs of the Node
    for i := 0 to TreeNode.Count - 1 do
      ProcessTreeItem (TreeNode.Item[i], TreeStream);
  end;
end;
Damit wird der Umweg zu XML umgangen.
Es werden auch nur einzelne ausgewählte Nodes übertragen. Nicht die ganze Treeview.
Von dem einzelnen Node wird auch nur die erste Ebene genommen.

Möchte sozusagen eine Explorerview zum Client übertragen. Normal sind alle Ordner zusammen geklappt. Wenn nun ein Ordner (Node) beim Client expandiert wird holt er sich für diesen Node die nächste Ebene.
Ansonsten müsste ja immer die ganze Ordnerstruktur vom Server übertragen werden.
Auch der Server fügt erst beim erweitern des Ordners die nächste Ebene ein. Somit kann man so schnell wie mit dem Explorer herumsuchen.


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