![]() |
TTreeView alles dopelt, warum ?
Liste der Anhänge anzeigen (Anzahl: 1)
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:
die installsiert die TreeView bzw. befüllt sie mit Verzeichnise aber halt nicht komplet:
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 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:
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.
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; im anahng ist die exe datei. achaj: ich arbeitet unter "Delphi 2005 PE" |
Re: TTreeView alles dopelt, warum ?
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:
Ist ja prinzipiell nicht verkehrt, nur bei einer umfangreichen Struktur dauert es halt ein bischen, bis der Baum aufgebaut ist...
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; 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:
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...)
{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; Wünsche viel Erfolg beim 'studieren' und probieren... :hi: an meine alte Heimat (sofern es OL ist) |
Re: TTreeView alles dopelt, warum ?
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... |
Re: TTreeView alles dopelt, warum ?
was noch schön währe, wenn nur ein + gezeichnit wird wenn auch unterverzeichnise hatte:
weiß du wie ich meine ? |
Re: TTreeView alles dopelt, warum ?
habe das problem mit hilfe diese änderungen selbst behäben können *G*
Delphi-Quellcode:
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.....
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; 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 |
Re: TTreeView alles dopelt, warum ?
:thumb: 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; |
Re: TTreeView alles dopelt, warum ?
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* |
Re: TTreeView alles dopelt, warum ?
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:
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 :-)
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; Gruß, Chris //Edit: Irgendwie werden die '<' und '>' im Quelltext-Tag durch das Zitat in das HTML-Äquivalent geändert -> < oder > Das verbessert :-) |
Re: TTreeView alles dopelt, warum ?
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*
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:17 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