![]() |
TreeView und ListView
Hallo zusammen,
Ich arbeite noch nicht sehr lange mit Delphi und habe nun folgendes Problem Ich lasse mir in einem TreeView die Ordner aus einem ausgewählten Laufwerk anzeigen und möchte jetzt in einer ListView die Dateien anzeigen lassen die sich in den Ordnern befinden. Es sollen jedoch nur die Dateien angezeigt werden die auch in dem markierten Ordner sind. Bitte um schnelle Hilfe MFG Malte |
Re: TreeView und ListView
Hallo, herzlich Willkommen!
Mit ![]() |
Re: TreeView und ListView
Hallo,
ich weiss nicht, welche Version von Delphi Du verwendest, aber in Delphi 7 gab es noch die Komponenten 'ShellTreeView' und 'ShellListView'. Zu finden waren sie m.M. nach unter der Rubrik 'Beispiele'. Seit BDS2006 (oder früher?!) müssen diese manuell nachinstalliert werden. Die Packages liegen unter (bspw.) C:\Programme\Borland\BDS\4.0\Demos\DelphiWin32\VCL Win32\ShellControls Edit: Wieder zu langsam |
Re: TreeView und ListView
Ich benutze CodeGear RAD Studio 2007 Professionell
Ich weis nicht so genau wie ich die FindAllFiles funktion einbinden soll. Wenn ihr mir da helfen könntet? |
Re: TreeView und ListView
Installiere Dir die ShellControls. Wo diese liegen, habe ich bereits erwähnt. Dann benötigst Du FindAllFIles nicht.
Ansonsten: Zu 'FindAllFiles' findest Du eine Demo von Luckie, wenn Du auf den von Matze geposteten Link klickst. |
Re: TreeView und ListView
Danke für die Antworten aber das ist alles nicht so wie ich mir das vorstelle. Vielleicht muss ich mich nochmal anders ausdrücken.
1. Ich habe eine Prozedur die für jedes Laufwerk des Rechners einen Button erzeugt. 2. Beim Click auf einen der Button werden die Ordner ausgelesen, die auf diesem Laufwerk vorhanden sind, und in einem TreeView dargestellt. 3. Wenn ich jetzt im TreeView einen Ordner anklicke(markiere) soll er mir in einem ListView (rechts neben dem TreeView) die einzelnen Dateien, die in dem ausgewählten Ordner sind) anzeigen. Die ShellControls habe ich nicht bei meinem Delphi. |
Re: TreeView und ListView
Da gibts doch vorgefertigte Componenten, die mit Delphi mitgeliefert werden, die das alles per Click/Properties erledigen. (Bei Interesse nochmal nachfragen, dann schau ich mal). Wenn du es aus irgendeinem Grund aber per Hand machen MUSST, dann geht das auf jeden Fall mit dem auslesen der Files und dem Platzieren in einem Listview. Willst du denn alle unterordner in dem Listview mit anzeigen oder nur (ausschließlich) solche Items, die auch Dateien sind (=keine Ordner)?
|
Re: TreeView und ListView
Die vorgefertigten Komponenten gefallen mir nicht. Beim TreeView gibt es kein "+" und "-" vor den Knoten.
Im List View sollen hinterher NUR Dateien stehen. aber halt auch nur die zum angewählten Ordner. Ich hatte es schon soweit das er mir alle anzeigt, was natürlich nicht Sinn der Sache ist. |
Re: TreeView und ListView
was bedeutet denn "alle" dateien? Ich kann mir gar nicht vorstellen, dass es anders geht, als nur die im ordner enthaltenen dateien anzuzeigen. Moment ich bastel ma rum ...
|
Re: TreeView und ListView
Die ShellControls findest du hier:
...\Borland\BDS\4.0\Demos\DelphiWin32\VCLWin32\She llControls Einfach beide Packages compilieren und dann installieren. Du bekommst dann in der Komponentenpalette eine neue Kategorie "Samples". Das + und - beim Knoten kannst du mit einer Eigenschaft, dir mir gerade nicht einfällt, an bzw. ausschalten. |
Re: TreeView und ListView
Wie Andreas schon sagt ist der eleganteste Weg einfach das Design (+/-, etc.) der schon vorhandenen Komponenten zu ändern.
Wenn es mit ShellCtrl nicht klappt kannst du mit FindFirst, FindNext, etc. arbeiten. Dort kannst du nämlich auch gleich angeben, ob du Ordner includen willst oder nicht. Bsp.-Quellcode zum Selbststudium:
Delphi-Quellcode:
Wenn du in der Hilfe mal nach "Dateien" suchst und den Filter auf DevStudio für Win32 setzt, danna auf "Methoden zur Ein-/Ausgabe" klickst und noch ein bissl rumsuchst, findest du eine ganze Anleitung dazu.
var
SearchRec: TSearchRec; procedure TForm1.SearchClick(Sender: TObject); begin FindFirst('c:\Program Files\MyProgram\bin\ *.*', faAnyFile, SearchRec); Label1.Caption := SearchRec.Name + ' is ' + IntToStr(SearchRec.Size) + " bytes in size'; end; procedure TForm1.AgainClick(Sender: TObject); begin if FindNext(SearchRec) = 0 then Label1.Caption := SearchRec.Name + ' is ' + IntToStr(SearchRec.Size) + ' bytes in size' else FindClose(SearchRec); end; Ansonsten wie gesagt die schon vorhandenen Komponenten anpassen. Und bei Fragen nochmal posten :) |
Re: TreeView und ListView
Hier ist die Prozedur die die Verzeichnisse ausliest. Jetzt ist die Frage, ob ich hier auch die Dateien schon suche oder ob ich dafür ne eigene Prozedur schreibe, die nur beim Klick auf den ausgegebenen Ordner ausgeführt wird.
Delphi-Quellcode:
procedure TForm2.HoleVerzeichnisse(const Pfad: String; var Tree: TTreeView;var ListView: TListView; Start: TTreeNode);
var SR: TSearchRec; begin if FindFirst(Pfad + '\*.*', faAnyFile, SR) = 0 then repeat Application.ProcessMessages; if (SR.Attr AND faDirectory = faDirectory) AND (SR.Name[1] <> '.') AND (SR.Name[1] <> '_') then begin baum := Tree.Items.Addchild(Start, SR.Name); baum.ImageIndex := 1; baum.StateIndex := 2; HoleVerzeichnisse(Pfad + '\' + SR.Name, Tree, ListView, Baum); end; until (FindNext(SR) <> 0); SysUtils.FindClose(SR); end; |
Re: TreeView und ListView
Du machst beim OnClik des treeviews eine Art "HoleDateien" mit den gleichen Parametern. Die schreibt dann die Elemente von "Pfad" (also dem aus dem Item und den Überitems zusammengesetzten String des TreeViews) wo (SR.Attr AND NOT faDirectory = faAnyFile) und schreibt die in den ListView.
|
Re: TreeView und ListView
1. Muss ich OnClick oder OnChange nehmen?
2. Wie komm ich in der Funktion an den Pfad dran? Also wie kann ich auslesen was ich angeklickt habe? |
Re: TreeView und ListView
So sieht meine Prozedur bis jetzt aus. Jedoch weis ich nicht genau wie ich denn jetzt den Namen in das Item packe.
Ihr wisst was ich meine??
Delphi-Quellcode:
procedure TForm2.HoleDateien(const Pfad: String);
var SR: TSearchRec; begin if FindFirst(Pfad + '\*.*', faAnyFile, SR) = 0 then repeat Application.ProcessMessages; if (SR.Attr OR faAnyfile = faAnyFile) AND (SR.Name[1] <> '.') AND (SR.Name[1] <> '_') then begin ListView1.Items.Add ; ListItem.Caption := (SR.Name); baum.ImageIndex := 1; baum.StateIndex := 2; HoleDateien(Pfad); end; until (FindNext(SR) <> 0); SysUtils.FindClose(SR); end; |
Re: TreeView und ListView
Hier hab ich dir mal ein uraltes Beispiel das dir auch deine +/- Anzeigt vor den Eintraegen im Treeview!
Delphi-Quellcode:
procedure Verzeichnisse_Einlesen(Tree : TTreeView; Verzeichnis : String; Eintrag : TTreeNode; Mit_Dateien : Boolean);
Var SearchRec : TSearchRec; EintragTemp : TTreeNode; List : TStringList; Buf : String; I : Integer; Begin Tree.Items.BeginUpdate; List:= TStringList.Create; If Verzeichnis[Length(Verzeichnis)] <> '\' Then Begin Verzeichnis:= Verzeichnis + '\'; End; If FindFirst(Verzeichnis + '*.*', faDirectory, SearchRec) = 0 Then Begin Repeat If (SearchRec.Attr And faDirectory = faDirectory) And (SearchRec.Name[1] <> '.') Then Begin //Eintrag ist ein Verzeichnis If (SearchRec.Attr And faDirectory > 0) Then Begin //zum aktuellen Eintrag hinzufügen Eintrag:= Tree.Items.AddChild(Eintrag, SearchRec.Name); EintragTemp:= Tree.Items.Add(Nil, Buf); EintragTemp.ImageIndex := 0; //Ummarkiert EintragTemp.SelectedIndex := 0; //Markiert EintragTemp.StateIndex := -1; //Eintrag merken EintragTemp:= Eintrag.Parent; //auf Untereinträge prüfen Verzeichnisse_Einlesen(Tree, Verzeichnis + SearchRec.Name, Eintrag, Mit_Dateien); //Eintrag wiederholen Eintrag:= EintragTemp; End Else //Eintrag ist eine Datei If Mit_Dateien Then Begin If (SearchRec.Name[1] <> '.') And (SearchRec.Name[1] <> '..') Then Begin Tree.Items.AddChild(Eintrag, SearchRec.Name); Eintrag:= Tree.Items.Add(Nil, SearchRec.Name); EintragTemp:= Tree.Items.Add(Nil, List.Strings[I]); EintragTemp.ImageIndex := 2; //Ummarkiert EintragTemp.SelectedIndex := 2; //Markiert EintragTemp.StateIndex := -1; End; End; End; Until FindNext(SearchRec) <> 0; FindClose(SearchRec); End; Tree.Items.EndUpdate; End; procedure TForm1.Button2Click(Sender: TObject); begin TreeView1.Items.Clear; Verzeichnisse_Einlesen(TreeView1, Edit2.Text, Nil, False); end; |
Re: TreeView und ListView
Ich hab es ja jetzt auch schon so, dass er mir das + und - anzeigt. Ich habe halt nur nen problem, dass er mir die Dateien aus den Ordnern in einem ListView anzeigt.
|
Re: TreeView und ListView
Ich mache das immer so:
Delphi-Quellcode:
var MyItem: TListItem;
MyItem := ListView.Items.Add; MyItem.ImageIndex := EinIndex; MyItem.Caption := 'Inhalt der 1. Spalte'; MyItem.SubItems.Add('Inhalt der 2. Spalte'); MyItem.SubItems.Add('Inhalt der 3. Spalte'); |
Re: TreeView und ListView
Ich habe das jetzt hinbekommen.
Leider kann ich im moment nur die Dateien anzeigen die sich hinter dem ersten knoten verbergen. Was muss ich denn ändern, damit der komplette Pfad mitübergeben wird? |
Re: TreeView und ListView
Zitat:
|
Re: TreeView und ListView
Liest die Ordner aus:
Delphi-Quellcode:
Zeigt die entsprechenden Dateien an:
procedure TForm2.HoleVerzeichnisse(const Pfad: String; var Tree: TTreeView;
Start: TTreeNode); var SR: TSearchRec; begin if FindFirst(Pfad + '\*.*', faAnyFile, SR) = 0 then repeat Application.ProcessMessages; if (SR.Attr AND faDirectory = faDirectory) AND (SR.Name[1] <> '.') AND (SR.Name[1] <> '_') then begin baum := Tree.Items.Addchild(Start, SR.Name); baum.SelectedIndex := 1; baum.ImageIndex := 1; baum.StateIndex := -1; HoleVerzeichnisse(Pfad+'\'+ SR.Name, Tree, baum); end; until (FindNext(SR) <> 0); SysUtils.FindClose(SR); end;
Delphi-Quellcode:
procedure TForm2.HoleDateien(const Pfad: String; ListV: TListView; Filter: String);
var SR: TSearchRec; anItem:TListItem; begin if FindFirst(Pfad + '\' + Filter, faAnyFile, SR) = 0 then repeat Application.ProcessMessages; if (SR.Attr AND faDirectory <> 16) AND (SR.Name[1] <> '.') AND (SR.Name[1] <> '_') then begin anItem:=ListV.Items.Add; anItem.Caption:=SR.Name; anItem.SubItems.Add( IntToStr(GetFileSizeEx(Pfad+'\'+SR.Name)div 1024)); anItem.SubItems.Add( GetFileTypename(Pfad+'\'+SR.Name)); anItem.SubItems.Add( DateToStr(GetFileLastAccessTime(Pfad+'\'+SR.name))); anItem.SubItems.Add( DateToStr(GetCreationTimeOfFile(Pfad+'\'+SR.Name))); end; until (FindNext(SR) <> 0); SysUtils.FindClose(SR); end; |
Re: TreeView und ListView
Hm,
du musst auch noch auf
Delphi-Quellcode:
ueberpruefen!
( SR.Name[1] <> '..')
Und was soll das sein?
Delphi-Quellcode:
Du weist schon dass du das ganze einfacher in einer einzigen Funktion mit Rekursion schreiben kannst?
(SR.Name[1] <> '_')
|
Re: TreeView und ListView
Das
Delphi-Quellcode:
habe ich gemacht, weil der mir sonst auch _history Ordner anzeigt was ich aber nich haben möchte.
(SR.Name[1] <> '_')
Und
Delphi-Quellcode:
hab ich nicht gemacht da ich es ja schon mit einem Punkt habe. Wenn das erste Zeichen ungleich '.' ist schliesst es '..' ja logischerweise auch aus, da dies ja schon 2 Zeichen sind.
(SR.Name[1] <> '..')
Wie kann ich das denn in einer Funktion machen? Ich habe Stunden lang rumprobiert und es nicht hinbekommen. Danach habe ich mich dann für 2 Funktionen entschieden. Für eine Lösung in einer Funktion wäre ich sehr dankbar. Vorallem das mit der Rekursion wäre interessant, da ich somit dann auch Dateien aus SubOrdnern auslesen könnte. |
Re: TreeView und ListView
Siehe dir doch den Link in meinen ersten Beitrag (Beitrag #2) an. Da sind rekursive Funktionen zu finden, die du wenn, dann nur leicht anpassen musst.
|
Re: TreeView und ListView
Entweder hast du meinen Beitrag #16 total ignoriert oder ich sehe net wo das Problem liegt :?: Du musst einfach wenn es im Result um einen Ordner handelt in diesen Ordner reingehen und dort weitersuchen bis es keine weiteren Unterordner mehr gibt.
Hab dir hier mal ein kleines Beispiel was du mit etwas anpassen verwenden kannst (hab ich aus einem aktuellen Projekt rauskopiert) oder aber auch einfach umschreiben kannst um Delphi's TSearchRec zu nutzen!
Delphi-Quellcode:
procedure SearchFiles(aRoot: String; var Files : TStringList; Mask: String = '*.*'; Recursive : Boolean = False);
var wfd : TWin32FindData; hFile : THandle; begin aRoot := IncludeTrailingPathDelimiter(aRoot); if Recursive then begin hFile := FindFirstFile(PChar(aRoot + Mask), wfd); if ( hFile <> INVALID_HANDLE_VALUE ) then try repeat if ( wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY ) then begin if ( (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') ) then begin SearchFiles(aRoot + wfd.cFileName, Files, Mask, Recursive); // hier wird die Rekursion angewandt end; end; until FindNextFile(hFile, wfd) = False; finally Windows.FindClose(hFile); end; end; hFile := FindFirstFile(PChar(aRoot + Mask), wfd); if ( hFile <> INVALID_HANDLE_VALUE ) then try repeat if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY <> FILE_ATTRIBUTE_DIRECTORY ) then begin Files.Add(wfd.cFileName); end; until FindNextFile(hFile, wfd) = False; finally Windows.FindClose(hFile); end; end; |
Re: TreeView und ListView
Tut mir ja leid das ich das alles noch nicht sofort verstehe aber ich arbeite noch nicht so lange mit delphi.
Ich werde das morgen dann mal ausprobieren und meinen Erfolg hier posten! |
Re: TreeView und ListView
Moin Malte,
Zitat:
Delphi-Quellcode:
prüfen musst.
(SR.Name <> '.') and (SR.Name <> '..')
Eine Prüfung auf SR.Name[1] <> '.' ist schlichtweg falsch, da ein Datei-/Ordername durchaus mit einem Punkt beginnen kann. Nur weil man das im Explorer nicht so eingeben kann heisst noch lange nicht, dass es nicht geht, bzw. nicht erlaubt ist ;-) (ich weiss, dass man das oft so sieht, aber dadurch wird es nicht richtiger ;-)) |
Re: TreeView und ListView
Zitat:
Und klar sag ruhig wenn es geklappt hat oder ob du noch mehr Hilfe brauchst, dazu ist ja das Forum da! |
Re: TreeView und ListView
Entweder bin ich zu doof um die Funktion umzubauen oder die tut einfach nicht das was ich möchte.
Jetzt zeigt er mir im TreeView nichts mehr an und im ListView zeigt er mir ALLES an. also Ordner + unterordner + dateiname und dabei listet er die Ordner und Unterordner auch einzeln auf. z.B.: C:\ C:\Test C:\Test\test.txt Hat jemand ne Lösung? Hier meine umgebaute Funktion:
Delphi-Quellcode:
Ich vermute einfach mal das
procedure TForm2.FindAllFiles(FileList: TListView;
RootFolder: string; Mask: string ='*'; Recurse: Boolean = True; AddFolderNames: Boolean = False; IgnoreMaskAtFolderNames: Boolean = True); procedure LFindAllFiles(AParentFolder: String); var LSearchRec: TSearchRec; begin if FindFirst(AParentFolder + '*', faAnyFile, LSearchRec) = 0 then begin repeat if (LSearchRec.Name <> '.') and (LSearchRec.Name <> '..') then begin if LSearchRec.Attr and faDirectory = faDirectory then begin if AddFolderNames and (IgnoreMaskAtFolderNames or Like(AnsiLowerCase(LSearchRec.Name), Mask)) then FileList.AddItem(AParentFolder + LSearchRec.Name, TObject(True)); if Recurse then LFindAllFiles(AParentFolder + LSearchRec.Name + '\'); end else if Like(AnsiLowerCase(LSearchRec.Name), Mask) then FileList.AddItem(AParentFolder + LSearchRec.Name, TObject(False)); end; until FindNext(LSearchRec) <> 0; FindClose(LSearchRec); end; end; begin Mask := AnsiLowerCase(Mask); LFindAllFiles(IncludeTrailingPathDelimiter(RootFolder)); end;
Delphi-Quellcode:
auf keinen Fall so richtig ist. Aber wie komm ich an
FileList.AddItem(AParentFolder + LSearchRec.Name, TObject(True));
Delphi-Quellcode:
???
AddObject
|
Re: TreeView und ListView
Hab es endlich richtig hinbekommen. Danke für die Hilfe
|
Re: TreeView und ListView
Dann immer her mit dem funktionierenden Code damit alle was davon haben!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:55 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-2025 by Thomas Breitkreuz