AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TTreeView alles dopelt, warum ?

Ein Thema von mimi · begonnen am 13. Aug 2006 · letzter Beitrag vom 15. Aug 2006
Antwort Antwort
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#1

TTreeView alles dopelt, warum ?

  Alt 13. Aug 2006, 12:33
Hallo,
ich lese die verzeichnis strucktur ein und zwar so:
damit es nicht ewig dauert wollte ich es stückweise machen.
also habe ich folgenden
D:\Daten
D:\Spiele
D:\Programme
diese verzeichnis werden eingelesen und auch deren unterverzeichnise:
D:\Daten\unterverz.\
D:\Spiele\unterverz.\
D:\Programme\unterverz.\
und das sieht dann auch so ungefähr aus.
ich arbeite mit zwei proceduren:
Delphi-Quellcode:
procedure DirsToTreeView(Dir:String; TV:TTreeview;Item:TTreeNode; addFiles:Boolean; ChildCount:Integer);
var
  Sr: TSearchRec;
  parent:TTreeNode;
begin
  // Damit nicht ständig neugezeichnet wird
  dir:=GetDir(dir);
  // Suche nur starten wenn es ein erfolgt wahr also es keine fehler geben hat
  if findFirst(Dir + '*.*', faDirectory,sr) = 0 then begin
    repeat
      // Wenn es sich um verzeichnis handelt
      if sr.name[1] <> '.then begin
        if ((sr.Attr and faDirectory > 0)) then begin
          item:=tv.Items.AddChild(Item,sr.name);

          Parent:=item.Parent;

          if ChildCount = 0 then begin
            ChildCount:=1;
            DirsToTreeView(dir+sr.name,tv,item,addfiles,ChildCount);
            ChildCount:=0;
          end;
          item:=parent;
        end;
      end; // if sr.name

    until FindNext(SR) <> 0;
  end;
end;
die installsiert die TreeView bzw. befüllt sie mit Verzeichnise aber halt nicht komplet:
die zweite procedure soll jetzt sobalt ich auf ein + zeichen drücke die unterverzeichnis durchsuchen und es dort emebfalls so machen also:
das dort die unterverzeichnise eingelesen werden wie oben gezeigt...
aber halt nicht alle.

Delphi-Quellcode:
procedure DirsToTV(dir:String; tv:TTreeview; item:TTreeNode;count:Integer);
var
  i:Integer;
  pfad:String;
  sr:TSearchRec;
begin
//ShowMEssage(IntToStr(count));
  for i:=0 to Item.Count-1 do begin
    pfad:= getItemPfad(tv,item.Item[i]); ;
    if findFirst(pfad + '\*.*',faDirectory,sr) = 0 then begin
      repeat
        if sr.name[1] <> '.then begin
          if (sr.Attr and faDirectory > 0) then begin
            if item.item[i] <> NIL then begin
               tv.Items.AddChild(item.item[i],sr.name);
            end;
          end;
        end;
      until FindNext(sr) <> 0;
      FindClose(sr);
    end;
  end;
end;
und genau hier ist auch das problem bei AddChild sobalt ich das aufrufe habe ich den stamm zweimal und ich weiß nicht warum auch wenn ich oben die ShowMessage habe die sag es sein 19 einträge obwohl es nur 9 sind ich weiß einfach nicht mehr weiter.

im anahng ist die exe datei.
achaj: ich arbeitet unter "Delphi 2005 PE"
Angehängte Dateien
Dateityp: exe systembackup1_129.exe (669,5 KB, 12x aufgerufen)
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
raiguen
(Gast)

n/a Beiträge
 
#2

Re: TTreeView alles dopelt, warum ?

  Alt 13. Aug 2006, 20:11
Moin
Ich vermute mal (anhand Deines Beispiels), dass Du eine Verzeichnis-Explorer nachbauen möchtest...
Das ist doch relativ einfach zu machen und geht auch superflink(siehe mein Code weiter unten)

Zunächst: die doppelten Einträge sind einfach zu erklären-> im ersten Step ziehst Du dir schon die [b]gesamte[/] Verszeichnisstruktur des ausgewählten Laufwerks rein:
Code:
procedure DirsToTreeView(Dir:String; TV:TTreeview;Item:TTreeNode; addFiles:Boolean; ChildCount:Integer);
var
  Sr: TSearchRec;
  parent:TTreeNode;
begin
   ...
   item:=tv.Items.AddChild(Item,sr.name); //--Knoten zuweisen
...
   //--für den soeben erstellten Knoten gleich die Unterverzeichnisse suchen und eintragen
   DirsToTreeView(dir+sr.name,tv,item,addfiles,ChildCount);
...
end;
Ist ja prinzipiell nicht verkehrt, nur bei einer umfangreichen Struktur dauert es halt ein bischen, bis der Baum aufgebaut ist...
Im zweiten Step klickst Du auf irgendeinen Knoten, um diesen aufzumachen und die darumnterliegende Struktur anzuzeigen bzw. die Struktur einzulesen -> genau hier erscheinen dann die doppelten Einträge -> Du liest mit der zweiten Procedure nochmals die Struktur des angewählten Knotens aus, obwohl diese schon vom ersten Step vorhanden ist...

So, nun zu meinem Lösungsvorschlag:
Delphi-Quellcode:
{Hinweis: AutoExpand beim TreeView ist FALSE!!}
//--Editfeld zur Laufwerksauswahl
procedure TfrmMain.Edit2KeyPress(Sender: TObject; var Key: Char);
var Node: TTreeNode;
begin
if key=#13 then
  begin
    //--RootKnoten erstellen
    Node := TreeView1.Items.Add(nil,Edit2.Text);
    //--erste Verzeichnisebene auslesen
    VerzBaum(Edit2.Text, TreeView1, Node, false);
  end;
end;

procedure TfrmMain.VerzBaum(Dir: String; aTV:TTreeView; aItem: TTreeNode);
var
  SR: TSearchRec;
  NeuerNode: TTreeNode;
begin
  aTV.Items.BeginUpdate; //--Aufbau schneller, da nicht ständig neu gezeichnet werden muss
  if findFirst(Dir+'\*.*', faAnyFile,SR) = 0 then
    repeat
      if (SR.Name <> '.') and (SR.Name <> '..') and (sr.Attr and faDirectory > 0) then begin
          NeuerNode := aTV.Items.AddChild(aItem,SR.Name);
          NeuerNode.HasChildren := True; //erstmal setzen
      end;
    until FindNext(SR) <> 0;
  FindClose(SR);
  aTV.Items.EndUpdate; //--neue Knoten anzeigen

  //--Markierung entsprechend setzen
  aItem.HAsChildren := (aItem.Count>0);
end;

//--Knoten expandieren bzw Struktur einlesen und Baum aufbauen
procedure TfrmMain.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);

var ElternKnoten: TTreeNode;
    Pfad: String;
begin
  //--wenn noch keine Unterknoten(Kinder) existieren
  if Node.GetFirstChild = nil then
     begin
      //--alle Parents auslesen bis zur Root und somit den Pfadnamen zusammensetzen
      Pfad := Node.Text;
      ElternKnoten := Node.Parent;
      while ElternKnoten <> nil do begin
        Pfad := ElternKnoten.Text+ '\' + Pfad ;
        ElternKnoten := ElternKnoten.Parent;
      end;
      VerzBaum(Pfad, TreeView1, Node, false);
      //AllowExpansion := True;
  end;
end;

procedure TfrmMain.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
      { Dateien aus Verzeichnis mit entsprechender MAske auslesen }
      procedure DateiListe(sPfad, sMaske: String; aList: TListBox);
        var SR: TSearchRec;
            Pfad: String;
      begin
        Pfad := IncludeTrailingBackSlash(sPfad);
        if FindFirst (PChar(Pfad+ sMaske), faAnyFile, SR) = 0 Then
          repeat
            if (SR.Name <> '.') and (SR.Name <> '..') Then
            aList.Items.Add(SR.Name);
          until FindNext (SR ) <> 0;
        FindClose(SR);
      end;


  var aNode, ElternKnoten: TTreeNode;
    Pfad: String;
begin
  ListBox1.Clear;
  aNode := TreeView1.Selected;
  //--feststellen, ob MausKlick auf einem Knoten erfolgte
  if (htOnItem in TreeView1.GetHitTestInfoAt(X,Y)) then
    begin
      Pfad := aNode.Text;
      ElternKnoten := aNode.Parent;
      while ElternKnoten <> nil do begin
        Pfad := ElternKnoten.Text+ '\' + Pfad ;
        ElternKnoten := ElternKnoten.Parent;
      end;
      DateiListe(Pfad, '*.*', ListBox1);
  end;
end;
Das Beispiel habe ich bewusst einfach gestrickt (mit den guten D5 *grins*) um das Ganze nachvollziehbar zu machen (hoff ich doch, dass es mir gelungen ist...)
Wünsche viel Erfolg beim 'studieren' und probieren...
an meine alte Heimat (sofern es OL ist)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#3

Re: TTreeView alles dopelt, warum ?

  Alt 13. Aug 2006, 23:25
vielen dank für deinen code habe ihn gerade ausbrobiert *G* solltes du als tip in die code lib einfügen ....

scheint bis jetzt alles zu klappen.
den teil den ich raußkopiert habe...

deine beschreibung für mein problem jedoch kann ich nicht ganz nachvollziehn:
die forschleife sollte doch alle unterkonten durchgehen aber nicht alle doppelt dastellen...
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#4

Re: TTreeView alles dopelt, warum ?

  Alt 13. Aug 2006, 23:41
was noch schön währe, wenn nur ein + gezeichnit wird wenn auch unterverzeichnise hatte:
weiß du wie ich meine ?
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#5

Re: TTreeView alles dopelt, warum ?

  Alt 14. Aug 2006, 17:28
habe das problem mit hilfe diese änderungen selbst behäben können *G*

Delphi-Quellcode:
function TForm2.GetAnderDir(dir:String):boolean;
var
  sr:TSearchRec;
  ok:Boolean;
begin
  ok:=False;
  if findFirst(Dir+'\*.*', faAnyFile,SR) = 0 then begin
    repeat
      if (sr.Name[1] <> '.') and (sr.Attr and faDirectory > 0) then begin
       // ShowMessage(sr.name);
        ok:=True;

        break;
      end;
    until FindNext(Sr) <> 0;
  end;
  FindClose(sr);
  result:=ok;
end;

procedure TForm2.VerzBaum(Dir: String; aTV:TTreeView; aItem: TTreeNode);
var
  SR: TSearchRec;
  NeuerNode: TTreeNode;
begin
  aTV.Items.BeginUpdate;
  if findFirst(Dir+'\*.*', faAnyFile,SR) = 0 then
    repeat
      if (sr.Name[1] <> '.') and (sr.Attr and faDirectory > 0) then begin
          NeuerNode := aTV.Items.AddChild(aItem,SR.Name);

          NeuerNode.HasChildren := GetAnderDir(dir + '\' +NeuerNode.text);
      end;
    until FindNext(SR) <> 0;
  FindClose(SR);
  aTV.Items.EndUpdate;
// aItem.HAsChildren := aItem.count > 0;
end;
Diese code durch sucht einmal das hauptverzeichnis dann schaut die procedur GetAnderDir in das nächte verzeichnis rein um so diese + zu setzten wenn es unterverzeichnise gibt.. ich hoffe ihr könnte mir folgen.....

vielen dank für die hilfe !

Edit: noch was vergeesen:
du schreibst immer: if (SR.Name <> '.') and (SR.Name <> '..') Then
aber es würde reichen if sr.name[1] <> '.' then
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
raiguen
(Gast)

n/a Beiträge
 
#6

Re: TTreeView alles dopelt, warum ?

  Alt 15. Aug 2006, 10:43
Schön, dass Du meine Änderungen übernommen hast und sogar daraufhin noch eine Schritt weiter gegangen bist
Nun, es stellt sich due Frage, wie schnell der Verzeichnisbaum aufgebaut werden soll: scheibchen weise, also immer nur die benötigte Struktur oder gleich vollständig mit allen Strukturen!
Im ersten Fall hat man natürlich das '+' auch an den Knoten, die evtl. keine weiteren Kinder haben - gut, ein Klick vergeblich, aber das '+' verschwindet dann ja...
Der zweite Fall prüft, ob evtl mindest ein Unterverzeichnis vorhanden ist...nimmt also etwas Zeit in Anspruch (bei einem Verzeichnis, was tonnenweise nur Dateien und kein UVZ hat, dauert das natürlich...), um evtl das '+' anzuzeigen.. Nun, dann kann ich ja auch gleich die komplette Struktur einlesen Nichts für ungut, wollte halt nur meine Gedanken diesbezüglich kundtun.

Das hier kannst Du noch etwas verbessern:
Delphi-Quellcode:
function TForm2.GetAnderDir(dir:String):boolean;
var
  sr:TSearchRec;
begin
  RESULT := False; //<<--vorbelegen
  if FindFirst(Dir+'\*.*', faAnyFile,SR) = 0 then
    repeat
      RESULT := (sr.Name[1] <> '.') and (sr.Attr and faDirectory > 0)
    until RESULT or (FindNext(sr) <> 0); //<--Abbruch bei RESULT=True oder wenn Verzeichnis komplett durch
  FindClose(sr);
end;
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#7

Re: TTreeView alles dopelt, warum ?

  Alt 15. Aug 2006, 17:12
vielen dank für dein tip mit der verbesserung an der funktion mein ziel ist eine schneller einlesen der verzeichnis strucktur so wie im Explorer selbst dort sind auch nur + zeichen wenn es mind. ein unterverzeichnis gibt... mehr möchte ich garnicht erreichen....

ich habe von einer methode gehört verzeichnise schneller einzulesen über
irgenwelch IDs oder so.... evlt. weißt ja einer mehr darüber...

evlt. kann ich ja auch die gleichen funktionen nutzen wie der explorer....

nuzte ja schon die systemiconlist vom explorer *G*

edit:
kennst du ihr seiten die sich mit sowas befassen(auf deutsch) so mit dem system Dateisystem *G*
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

Re: TTreeView alles dopelt, warum ?

  Alt 15. Aug 2006, 17:24
Hallo raigun, hallo mimi,

also das mit dem '+' ist so ne Sache, dass stimmt. Aber wenn man in der Methode GetAnderDir mit FindFirst gleich nur nach Verzeichnissen suchen läßt, sollte es schneller gehen. Das sieht dann so aus:
Delphi-Quellcode:
function TForm2.GetAnderDir(dir:String):boolean;
var
  sr:TSearchRec;
begin
  RESULT := False; //<<--vorbelegen
  if FindFirst(Dir+'\*.*', faDirectory,SR) = 0 then //<<--faDirectory sollte hier die Lösung sein
    repeat
      RESULT := (sr.Name[1] <> '.');
    until RESULT or (FindNext(sr) <> 0); //<--Abbruch bei RESULT=True oder wenn Verzeichnis komplett durch
  FindClose(sr);
end;
Ich denke das dürfte beide Seiten zufrieden stellen. Ich bin mir aber nicht 100% sicher, ob das dann wirklich schneller ist. Hängt davon ab, wie FindFirst/FindNext arbeiten. Sollte man mal testen

Gruß, Chris

//Edit: Irgendwie werden die '<' und '>' im Quelltext-Tag durch das Zitat in das HTML-Äquivalent geändert -> &lt; oder &gt; Das verbessert
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#9

Re: TTreeView alles dopelt, warum ?

  Alt 15. Aug 2006, 17:29
danke für die verbesserung. habe sie eingebaut... mein ziel ist es daraus eine funktion zu schreiben evlt. auch eine komponenten die die Explorers änlichsieht aber mehr kann als die komponenten die unter beispiele zu finden sind z.b. das mit den checkboxen und den 3 zuständen *G*
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
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