Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Funktion erweitern (https://www.delphipraxis.net/152309-funktion-erweitern.html)

Muellermilchtrinker 17. Jun 2010 18:49

Delphi-Version: 2009

Funktion erweitern
 
Hallo DP,

ich hab folgende Funktion:
Delphi-Quellcode:
Procedure FülleOrdnerInTreeView(Pfad:String;TreeView:TTreeView;Node:TTreeNode;
                                Dateimaske:String;DateiendungAnzeigen:Boolean);
var Files:TSearchRec; erg:Integer; DateiName:String;
begin
if (Pfad <> '') then //wenn kein Pfad angegeben dann abbrechen
begin
  if Pfad[length(Pfad)] <> '\' then Pfad := Pfad + '\'; //wenn kein '\' dann hinzufügen
  erg := FindFirst(Pfad + Dateimaske, faAnyFile, Files); //erste Datei holen (Ergebnis <> 0 = nix gefunden)
  while erg = 0 do //wenn Datei gefunden weitersuchen
  begin
    Dateiname := Files.Name;
    if DateiendungAnzeigen=False then
    begin
      Delete(Dateiname,Pos('.',Dateiname),Length(Dateimaske));
    end;
    TreeView.Items.AddChild(Node,Dateiname);
    erg := FindNext(Files); //nächste Datei suchen
  while ((Files.Name = '.') or (Files.Name = '..')) and (erg <> 0) do erg := FindNext(Files); //Filtert "." und ".." raus.
  end;
    FindClose(Files); //SearchRec freigeben
    TreeView.Items.Item[0].Expand(True);
end;
end;
ich möchte gerne jetzt, dass die auch die unterordner einfüllt.
Wäre nett, wenn ihr mir helfen könnt.

Matze 17. Jun 2010 19:43

AW: Funktion erweitern
 
Baue dir eine der Funktionen aus der Code-Library um. Das ist nicht schwer: FindAllFilesFindAllFiles.

Edit: Irgendwie gehen die [cl]-Tags noch nicht richtig.

Muellermilchtrinker 20. Jun 2010 20:18

AW: Funktion erweitern
 
Ich steh grad echt aufm Schlauch. :D

Wie bekomm ich folgendes in mein TreeView:

Code:
--Dateien <--Hauptordner
 +liste
 +zitate
 +-testdateien <--unterordner
  +test
  +test1
 +datei <-- unterordner beendet weiter mit hauptordner
und so weiter.
Jemand ne Idee??

himitsu 20. Jun 2010 20:27

AW: Funktion erweitern
 
Zitat:

Delphi-Quellcode:
if DateiendungAnzeigen=False then
begin
  Delete(Dateiname,Pos('.',Dateiname),Length(Dateimaske));
end;

=False und vorallem =True sollte man nicht zum Vergleichen verwenden.

Und dann hast du z.B. ein Probleme mit Dateien, welche einen Punkt im Namen haben. (der letzte Punkt zählt als Trennung und nicht er erste, welchen Pos finden würde)
Delphi-Quellcode:
if not DateiendungAnzeigen then
  Dateiname := ChangeFileExt(Dateiname, '');
zu deiner Frage:
- rufe deine Funktion rekursiv auf, bei Unterverzeichnissen
- und gib den Node des übergeordneten TreeNodes mit, welcher dann als Parent für die neuen Nodes verwendet wird.
- beim ersten Aufruf übergibst du den RootNode des TreeView

Teekeks 20. Jun 2010 20:28

AW: Funktion erweitern
 
vl. Hilft dir ja das hier:
Das teil durchsucht einen Ordner -Unterordner und legt dementsprechend Nodes an...

EDIT: Das war das falsche...
Hier also das richtige...

Delphi-Quellcode:
procedure TDirectorySearch.scan(path: string; tiefe:integer);
var SR:TSearchRec;
    tmparray:array of string;
    i:integer;
    tn:TTreeNode;
begin
  SetLength(tmparray,0);
  if FindFirst(path+'*', faAnyFile, SR) = 0 then
    begin
       repeat
          if (SR.Attr and faDirectory = faDirectory) and
          not ((SR.Name=',') or (SR.Name='.') or (SR.Name='..')) then
          begin
            with fTreeView.Items.AddChild(fTreeView.Selected,sr.Name+'/') do
            begin
              tn:=fTreeView.Selected;
              Selected:=true;
              scan(path+sr.Name+'/',tiefe+1);
              fTreeView.Selected:=tn;
            end;
          end else
              if not ((SR.Name=',') or (SR.Name='.') or (SR.Name='..') or (SR.Name='.directory')) and
                ((AnsiLowerCase(extractfileext(sr.Name))='.mp3') or
                (AnsiLowerCase(extractfileext(sr.Name))='.ogg') or
                (AnsiLowerCase(extractfileext(sr.Name))='.aac') or
                (AnsiLowerCase(extractfileext(sr.Name))='.wav')) then
              begin
                SetLength(tmparray,Length(tmparray)+1);
                tmparray[High(tmparray)]:=sr.Name;
              end;
        until FindNext(SR) <> 0;
  end;
  if High(tmparray)>=0 then
    for i:=0 to High(tmparray) do
    begin
      fTreeView.Items.AddChild(fTreeView.Selected,tmparray[i]).MakeVisible;
    end;
end;

himitsu 20. Jun 2010 20:56

AW: Funktion erweitern
 
@Teekeks:
* nicht das Delphi-Referenz durchsuchenFindClose vergessen :!:
* die For-Schleife brauchst du nicht mit diesem IF absichern (ist da schon eingebaut)
* und mal sehn was du zum Rest sagst :)
Delphi-Quellcode:
uses StrUtils;

procedure TForm1.scan(path: string);
var SR: TSearchRec;
    tmparray: array of string;
    i: integer;
    s: string;
begin
    SetLength(tmparray,0);
    if FindFirst(path+'*', faAnyFile, SR) = 0 then
    begin
        repeat
            if not AnsiMatchStr(SR.Name, [',', '.', '..']) then
                if SR.Attr and faDirectory = 0 then
                begin
                    if AnsiMatchText(ExtractFileExt(SR.Name), ['.mp3', '.ogg', '.aac', '.wav']) then
                    begin
                        SetLength(tmparray, Length(tmparray) + 1);
                        tmparray[High(tmparray)] := SR.Name;
                    end;
                end
                else
                    scan(path + SR.Name + '/');
         until FindNext(SR) <> 0;
         FindClose(SR);
    end;
    for i := 0 to High(tmparray) do
    begin
      //die Titel in diesem Ordner...
    end;
end;
@Muellermilchtrinker:
Delphi-Quellcode:
procedure TForm1.scan(path: string; parent: TTreeNode = nil);
var SR: TSearchRec;
  s: String;
begin
  SetLength(tmparray,0);
  if FindFirst(path + '*', faAnyFile, SR) = 0 then
    try
      repeat
        if (SR.Name <> '.') and (SR.Name <> '..') then
          if SR.Attr and faDirectory = 0 then
          begin
            TreeView1.Items.AddChild(parent, SR.Name);
            //s := SR.Name;
            //if not DateiendungAnzeigen then
            //  s := ChangeFileExt(s, '');
            //TreeView1.Items.AddChild(parent, S);
          end
          else
            scan(path + SR.Name + '/', TreeView1.Items.AddChild(parent, SR.Name));
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
end;

scan('C:\');

Teekeks 20. Jun 2010 21:22

AW: Funktion erweitern
 
Zitat:

Zitat von himitsu (Beitrag 1030462)
@Teekeks:
* nicht das Delphi-Referenz durchsuchenFindClose vergessen :!:
* die For-Schleife brauchst du nicht mit diesem IF absichern (ist da schon eingebaut)

Ok, FindClose fehlt tatsächlich, aber nehmen wir mal an es gibt einen Ordner der keine Dateien enthält, schon benötigt man das if wieder :)

Das ganze ist auch aus einem Projekt das ich schon seit gut einem Jahr nicht mehr bearbeite und nutze...

xZise 20. Jun 2010 21:39

AW: Funktion erweitern
 
Zitat:

Zitat von Teekeks (Beitrag 1030468)
Zitat:

Zitat von himitsu (Beitrag 1030462)
@Teekeks:
* nicht das Delphi-Referenz durchsuchenFindClose vergessen :!:
* die For-Schleife brauchst du nicht mit diesem IF absichern (ist da schon eingebaut)

Ok, FindClose fehlt tatsächlich, aber nehmen wir mal an es gibt einen Ordner der keine Dateien enthält, schon benötigt man das if wieder :)[…]

Nein Himitsu hat recht. Wenn wir die folgende For-Schleife haben:
Delphi-Quellcode:
for i := a to b do
  c();
Dann wird der Befehl c genau Max(b - a + 1, 0)× ausgeführt :mrgreen: Wenn also keine Dateien existieren, dann ist High(<empty array>) = -1 und damit ist -1 - 1 + 1 = -1 < 0 → es wird 0× ausgeführt.

Man könnte es auch so ausdrücken:
Delphi-Quellcode:
i := a;
while i &#8804; b do
begin
  c();
  Inc(i);
end;
Du siehst also, wenn a > b, dann wird die Schleife nie durchlaufen.

MfG
Fabian

PS: @Himi: Wozu zwei Proceduren?

Muellermilchtrinker 21. Jun 2010 11:31

AW: Funktion erweitern
 
Die letzte Procedur von Himitsu funktioniert. Aber ich hab folgendes Problem. Hab die jetzt so abgeändert, aber bei den Unterordnern funktioniert der Filter nicht :(:
Delphi-Quellcode:
procedure TForm1.scan(path: string; parent: TTreeNode = nil;Maske:String='*.*';DateiendungAnzeigen:Boolean=true);
var SR: TSearchRec;
  s:string;
  tmparray: array of string;
begin
  SetLength(tmparray,0);
  if FindFirst(path + '*', faAnyFile, SR) = 0 then
    try
      repeat
        if (SR.Name <> '.') and (SR.Name <> '..') then
          if SR.Attr and faDirectory = 0 then
          begin
            //TreeView1.Items.AddChild(parent, SR.Name);
            s := SR.Name;
            if not DateiendungAnzeigen then
            s := ChangeFileExt(s, '');
            TreeView1.Items.AddChild(parent, S);
          end
          else
            scan(path + SR.Name + '/', TreeView1.Items.AddChild(parent, SR.Name),Maske,DateiendungAnzeigen);
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
end;

DeddyH 21. Jun 2010 12:13

AW: Funktion erweitern
 
Wenn path sowieso nicht als konstanter Parameter deklariert ist, kannst Du ihn ja innerhalb der Routine ändern, also ggf. den Backslash anhängen. Nimm also als erste Zeile mal
Delphi-Quellcode:
path := IncludeTrailingPathDelimiter(path);
rein und mach vor allem den Slash beim rekursiven Aufruf raus.

Muellermilchtrinker 21. Jun 2010 18:12

AW: Funktion erweitern
 
Funktioniert leider immer noch nicht.
Die Maske funktioniert immer noch nicht bei den Unterordnern.
Und wenn wir grad dabei sind: Hat jemand eine Idee wie ich den Pfad rausbekomm, wenn ich auf eine Datei vom Unterordner klick??? Hab das immer so gemacht:
Delphi-Quellcode:
Dateipfad := Hauptpfad + TreeView1.Selected.Text
Weiß jemand wie ich das dann hier bekomm mit den Unterordnern???

DeddyH 21. Jun 2010 18:27

AW: Funktion erweitern
 
Dann zeig uns doch einmal die aktuelle Routine sowie den Aufruf, vielleicht sieht man da etwas.

Muellermilchtrinker 21. Jun 2010 18:33

AW: Funktion erweitern
 
Also meine aktuelle Routine sieht so aus:
Delphi-Quellcode:
procedure TForm1.scan(path: string; parent: TTreeNode = nil;Maske:String='*.*';DateiendungAnzeigen:Boolean=true);
var SR: TSearchRec;
  s:string;
  tmparray: array of string;
begin
  path := IncludeTrailingPathDelimiter(path);
  SetLength(tmparray,0);
  if FindFirst(path + '*', faAnyFile, SR) = 0 then
    try
      repeat
        if (SR.Name <> '.') and (SR.Name <> '..') then
          if SR.Attr and faDirectory = 0 then
          begin
            //TreeView1.Items.AddChild(parent, SR.Name);
            s := SR.Name;
            if not DateiendungAnzeigen then
            s := ChangeFileExt(s, '');
            TreeView1.Items.AddChild(parent, S);
          end
          else
            scan(path + SR.Name, TreeView1.Items.AddChild(parent, SR.Name),Maske,DateiendungAnzeigen);
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
end;
Und so rufe ich auf:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
scan(Edit1.Text,TreeView1.Items.Item[0],'*.txt',false);
end;
Ich hab einfach mal ein Testprojekt gemacht, indem ich ein Editfeld (für den Pfad), ein Button und das TreeView hab. Ich klick auf den Button und dann liest der den Ordner vom Editfeld in das TreeView ein.

DeddyH 21. Jun 2010 18:44

AW: Funktion erweitern
 
Und dabei wird die Maske ignoriert, sobald die erste Rekursion ins Spiel kommt? Passiert das auch, wenn Du den Defaultwert einmal entfernst?

Muellermilchtrinker 21. Jun 2010 18:46

AW: Funktion erweitern
 
Sobald die Rekursion kommt, wird die Maske entfernt.
Eigentlich wollt ich es zuerst ohne Defaultwert machen, aber da bekamm ich die Errormeldung, dass ein Defaultwert fehlt und dasselbe bei DateiendungAnzeigen.

DeddyH 21. Jun 2010 18:50

AW: Funktion erweitern
 
Das kann ja eigentlich nur bedeuten, dass Du beim ursprünglichen Aufruf nicht alle Parameter belegt hattest.

Muellermilchtrinker 21. Jun 2010 18:54

AW: Funktion erweitern
 
Ich hab aber alle Paramenter belegt und trotzdem kommt der Error.

DeddyH 21. Jun 2010 18:56

AW: Funktion erweitern
 
Delphi-Quellcode:
procedure TForm1.scan(path: string; parent: TTreeNode;Maske:String;DateiendungAnzeigen:Boolean=true);
So sollte es aber auch funktionieren, es sei denn, Du hast woanders noch eine gleichnamige Routine und beim Aufruf lässt sich nicht eindeutig zuordnen, welche gemeint ist.

Muellermilchtrinker 21. Jun 2010 18:59

AW: Funktion erweitern
 
Hier mal die komplette Unit:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    TreeView1: TTreeView;
    procedure Button1Click(Sender: TObject);
    procedure scan(path: string; parent: TTreeNode = nil;Maske:String;DateiendungAnzeigen:Boolean=true); //hier kommt der Error
//[DCC Fehler] Unit1.pas(15): E2238 Für 'Maske' ist ein Vorgabewert erforderlich
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.scan(path: string; parent: TTreeNode = nil;Maske:String;DateiendungAnzeigen:Boolean=true); //hier kommt auch der Error
//[DCC Fehler] Unit1.pas(53): E2238 Für 'Maske' ist ein Vorgabewert erforderlich
var SR: TSearchRec;
  s:string;
  tmparray: array of string;
begin
  path := IncludeTrailingPathDelimiter(path);
  SetLength(tmparray,0);
  if FindFirst(path + '*', faAnyFile, SR) = 0 then
    try
      repeat
        if (SR.Name <> '.') and (SR.Name <> '..') then
          if SR.Attr and faDirectory = 0 then
          begin
            //TreeView1.Items.AddChild(parent, SR.Name);
            s := SR.Name;
            if not DateiendungAnzeigen then
            s := ChangeFileExt(s, '');
            TreeView1.Items.AddChild(parent, S);
          end
          else
            scan(path + SR.Name, TreeView1.Items.AddChild(parent, SR.Name),Maske,DateiendungAnzeigen);
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
scan(Edit1.Text,TreeView1.Items.Item[0],'*.txt',false);
end;

end.

DeddyH 21. Jun 2010 19:01

AW: Funktion erweitern
 
Lass die "nil"-Zuweisung davor weg. Sobald ein Default-Parameter definiert ist, müssen alle folgenden auch Default-Werte aufweisen.

himitsu 21. Jun 2010 19:05

AW: Funktion erweitern
 
Oder einfach diesen Parameter nach hinten verlagern.

Bei Verwendung einer Maske wird es schwieriger,
denn die Verzeichnisse dürfen ja nicht über die Maskte gesucht werden.
Also muß man entweder selber den Dateinamen mit der Maske vergleichen oder man sucht in zwei Schritten.
Delphi-Quellcode:
procedure TForm1.scan(path: string; Maske:String;DateiendungAnzeigen:Boolean=true;parent:TTreeNode=nil);
var SR: TSearchRec;
  s:string;
begin
  path := IncludeTrailingPathDelimiter(path);
  if FindFirst(path + '*', faAnyFile, SR) = 0 then
    try
      repeat
        if (SR.Name <> '.') and (SR.Name <> '..')
            and (SR.Attr and faDirectory <> 0) then
          scan(path + SR.Name, Maske, DateiendungAnzeigen,
            TreeView1.Items.AddChild(parent, SR.Name));
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  if FindFirst(path + Maske, faAnyFile, SR) = 0 then
    try
      repeat
        if SR.Attr and faDirectory = 0 then
        begin
          s := SR.Name;
          if not DateiendungAnzeigen then
            s := ChangeFileExt(s, '');
          TreeView1.Items.AddChild(parent, S);
        end;
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
end;

Muellermilchtrinker 21. Jun 2010 19:06

AW: Funktion erweitern
 
Hab das nil weggelassen und hat geklappt. Aber leider klappt der Filter immer noch nicht. Bei den Unterordnern klappt die Maske nicht mehr.

himitsu 21. Jun 2010 19:08

AW: Funktion erweitern
 
Maske: siehe meine letzer editierter Beitrag.

Muellermilchtrinker 21. Jun 2010 19:13

AW: Funktion erweitern
 
Hat funktioniert. Hat aber jemand noch ne Idee wie ich den Pfad wieder bekomme???
Hab des so gemacht:
Delphi-Quellcode:
Dateipfad := Hauptpfad + TreeView1.Selected.Text
Aber das klappt ja bei den Unterordnern nicht mehr. Jemand ne Idee???

himitsu 21. Jun 2010 19:19

AW: Funktion erweitern
 
Entweder su speicherst dir den kompletten Pfad in den Node.Data

oder du setzt dir den Pfad zusammen.
in etwa so:
Delphi-Quellcode:
Dateipfad := '';
Node := TreeView1.Selected;
while Assigned(Node) do
begin
  Dateipfad := Node.Text + '\' + Dateipfad;
  Node := Node.Parent;
end;
Dateipfad := IncludeTrailingPathDelimiter(Hauptpfad)
  + ExcludeTrailingPathDelimiter(Dateipfad);

Muellermilchtrinker 21. Jun 2010 19:35

AW: Funktion erweitern
 
hat jemand ne Idee wie ich dort den Hauptnode ignorieren kann???

Teekeks 21. Jun 2010 19:57

AW: Funktion erweitern
 
Ungefähr so:
Delphi-Quellcode:
Dateipfad := '';
Node := TreeView1.Selected;
while Assigned(Node) do
begin
  if Node.Parent<>nil then
  begin
    Dateipfad := Node.Text + '\' + Dateipfad;
    Node := Node.Parent;
  end;
end;
Dateipfad := IncludeTrailingPathDelimiter(Hauptpfad)
  + ExcludeTrailingPathDelimiter(Dateipfad);

Muellermilchtrinker 21. Jun 2010 20:02

AW: Funktion erweitern
 
das funktioniert leider nicht. das programm hängt sich dort auf :(

Teekeks 21. Jun 2010 20:06

AW: Funktion erweitern
 
Ahh, Tatsache, mach es ohne das begin end;
Also so:
Delphi-Quellcode:
Dateipfad := '';
Node := TreeView1.Selected;
while Assigned(Node) do
begin
  if Node.Parent<>nil then
    Dateipfad := Node.Text + '\' + Dateipfad;
  Node := Node.Parent;
end;
Dateipfad := IncludeTrailingPathDelimiter(Hauptpfad)
  + ExcludeTrailingPathDelimiter(Dateipfad);

Muellermilchtrinker 21. Jun 2010 20:10

AW: Funktion erweitern
 
Jetzt funktioniert alles. Nun kann ich mein Programm erweitern. :stupid:

himitsu 21. Jun 2010 20:12

AW: Funktion erweitern
 
oder die IF-Abfrage direkt in das While integriert:
Delphi-Quellcode:
Dateipfad := '';
Node := TreeView1.Selected;
while Assigned(Node) and Assigned(Node.Parent) do
begin
  Dateipfad := Node.Text + '\' + Dateipfad;
  Node := Node.Parent;
end;
Dateipfad := IncludeTrailingPathDelimiter(Hauptpfad)
  + ExcludeTrailingPathDelimiter(Dateipfad);


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