Delphi-PRAXiS

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

bluescreen25 11. Nov 2007 18:39


suche Funktion FindLastDir
 
suche eine Funktion, die mir ausgehend von einem Pfad , in dem weitere Unterverzeichnisse sind, immer tiefer ins erste "erreichbare"** Unterverzeichnis geht bis keines mehr vorhanden ist und mir den "tiefsten" Pfad zurückliefert.

** der erste Ordner,alphabetisch wie im Windows-Explorer

Jemand ne Idee oder Ansatz?

Gruß, bluescreen25

Nuclear-Ping 11. Nov 2007 18:41

Re: suche Funktion FindLastDir
 
http://dsdt.info/tipps/?id=134

bluescreen25 11. Nov 2007 19:01

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von Nuclear-Ping
http://dsdt.info/tipps/?id=134

Danke, aber eigendlich wollte ich nicht alle Files oder Dirs in Stringlisten verwalten, lediglich die Rückgabe der tiefsten Ebene eines Pfades.

Dachte eher an sowas nur umgekehrt...:

Delphi-Quellcode:
function GetAudioplayerDirectory(const APath: String): String;
var
  i: Integer;
begin
  Result:=APath;
  i:=Length(APath);
  If i>3 Then
  Begin
    Repeat
      Dec(i);
    Until (APath[i] = '\') OR (i=1);
    If APath[i]='\' Then
      Result:=Copy(APath,1,i);
  End
end;

marabu 11. Nov 2007 19:15

Re: suche Funktion FindLastDir
 
Hallo,

vielleicht hilft dir das: Letzten Ordnernamen eines Pfades ermitteln

Grüße vom marabu

bluescreen25 11. Nov 2007 19:30

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von marabu
Hallo,

vielleicht hilft dir das: Letzten Ordnernamen eines Pfades ermitteln

Grüße vom marabu

das ist leider auch nicht ,was ich suche...

Ich habe C:\Ordner1 und am Ende möchte ich C:\Ordner1\UnterOrdner1\UnterOrdner1... haben, sprich den letzten und im ersten Moment unbekannten Pfad. Falls es noch UnterOrdner 2 oder mehr gibt, sind diese unberücksichtigt. Immer nur solange in den ersten verfügbaren Ordner springen bis es nicht tiefer geht und dann den vollen Pfad ausgeben.


Gruß, bluescreen25

C.Schoch 11. Nov 2007 21:01

Re: suche Funktion FindLastDir
 
Das kannst du recht einfach mit FindFirst ohne Rekursion erledigen.
Einfach FindFirst mit dem Dateinamen des letzten Aufrufs aufrufen, bis der Rückgabewert <> 0 ist.
Als Filter solltest du faDirectory setzen

Nuclear-Ping 11. Nov 2007 21:14

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von bluescreen25
Zitat:

Zitat von Nuclear-Ping
http://dsdt.info/tipps/?id=134

Danke, aber eigendlich wollte ich nicht alle Files oder Dirs in Stringlisten verwalten, lediglich die Rückgabe der tiefsten Ebene eines Pfades.

Was ist ein "Pfad" in dem Fall für dich? Ein String oder ein Verzeichnis auf der Festplatte, von dem du noch nicht weißt, was die tiefste Ebene ist?

Falls es ein String ist, kannst du dir entweder eine Funktion schreiben, die den String rückwärts nach dem ersten Vorkommen von '\' (oder '/' je nach Fall) durchsucht und einfach mit Copy den Teil von der Position ausgehend rauskopieren oder nach einer "LastPos" Funktion suchen.

Falls es das letztere ist, dann sollte der Link die Grundlage bilden, die letzte Ebene eines Verzeichnisses zu finden.

bluescreen25 11. Nov 2007 21:23

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von Nuclear-Ping
Zitat:

Zitat von bluescreen25
Zitat:

Zitat von Nuclear-Ping
http://dsdt.info/tipps/?id=134

Danke, aber eigendlich wollte ich nicht alle Files oder Dirs in Stringlisten verwalten, lediglich die Rückgabe der tiefsten Ebene eines Pfades.

Was ist ein "Pfad" in dem Fall für dich? Ein String oder ein Verzeichnis auf der Festplatte, von dem du noch nicht weißt, was die tiefste Ebene ist?

Falls es ein String ist, kannst du dir entweder eine Funktion schreiben, die den String rückwärts nach dem ersten Vorkommen von '\' (oder '/' je nach Fall) durchsucht und einfach mit Copy den Teil von der Position ausgehend rauskopieren oder nach einer "LastPos" Funktion suchen.

Falls es das letztere ist, dann sollte der Link die Grundlage bilden, die letzte Ebene eines Verzeichnisses zu finden.

Nachdem ich selber darauf gekommen bin, das es sich um ein unbekanntes Verzeichnis handelt, gebe ich dir Recht. Es geht um die von dir 2.te beschriebene Art.

Ich nutze schon FindAllFiles, doch in einer ganz anderen Weise, dachte es würde einfacher gehen....

Eigendlich wäre das nur ein Teil des Gesamten, wo in einem MP3Player von einem File ausgehend, ein Ordner abgespielt, am Ende dann aus dem Ordner in die höhere Ebene in den nächsten Ordner gehen soll und das erste File abspielen soll. Natürlich wenn keine Ordner vorhanden, das nächste File in der höheren Ebene.

Gruß, bluescreen25

Nuclear-Ping 11. Nov 2007 21:45

Re: suche Funktion FindLastDir
 
Naja, in dem Fall weißt du ja den Pfad schon fast.
Du brauchst nur den String an Hand der '\' zerlegen, kriegst daraus alle Teile des Pfades und kannst rückwärts auf die einzelnen Teile eine rekursive Verzeichnissuche machen. Wenn es keine Verzeichnisse in einem Pfad mehr gibt, hast du die letzte Ebenen unter einem jeweiligen Teilpfad.

bluescreen25 12. Nov 2007 14:37

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von Nuclear-Ping
Naja, in dem Fall weißt du ja den Pfad schon fast.
Du brauchst nur den String an Hand der '\' zerlegen, kriegst daraus alle Teile des Pfades und kannst rückwärts auf die einzelnen Teile eine rekursive Verzeichnissuche machen. Wenn es keine Verzeichnisse in einem Pfad mehr gibt, hast du die letzte Ebenen unter einem jeweiligen Teilpfad.

Nee leider nicht, denn wenn ich in einem Ordner abspiele, und es das letzte File war, möchte ich eine Ebene zurück und dort im nächsten Ordner den tiefsten Pfad haben und da kenne ich zu Beginn nur den obersten Pfad.

c:\MP3\Album1\letzterSong.mp3
c:\MP3
c:\MP3\nächstesAlbum\ggfUnterordner\ggfUnterOrdner \erstesFile.mp3 <-- hier würde ich nur c:\Mp3\nächstesAlbum wissen ,aber den letzten Ordner und sogar daraus das erste File wieder abspielen wollen...

hehe...etwas kurios wird aber noch schlimmer:

eine gesetzte oberste Grenze (Pfad) erreicht wie c:\MP3 und als letztes c:\MP3\letztesAlbum\letzterOrdner\letztesFile.mp3 soll dann wiedrum beim ersten Ordner anfangen und dort in die Tiefe gehen und da abspielen...und dann der Ablauf von oben weiter....wobei in der Tiefe abgespielt wird, immer eine Ebene höher und zuletzt auf das nächste Album in die Tiefe...bis wieder alles abgespielt wird....

Ist eine Art CD-Wechsler-Funktion , nur das es etwas komplexer ist, wegen Ordner in der Tiefe, was eine normale CD nicht hat wie C:\MP3\Album1\CD1\*.mp3 und das ggf in jedem Ordner darüber noch Restfiles liegen können sprich in ..\Album1 liegt Ordner \CD1 und ggf noch *.mp3.

Insgesamt wollte ich die Schritte in einzelne Funktionen aufteilen und dann zusammenstellen...

Gruß,bluescreen25

C.Schoch 12. Nov 2007 19:15

Re: suche Funktion FindLastDir
 
Hi,
Dafür gibts doch schon einen Funktion in der Codelib ich meine die nennt sich FindAllFilesFindAllFiles.
Die liest dir alle Dateien eines Ordners aus und schreibt sie in eine Stringlist und von da an sollte der Rest kein Problem mehr darstellen

bluescreen25 12. Nov 2007 20:44

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von C.Schoch
Hi,
Dafür gibts doch schon einen Funktion in der Codelib ich meine die nennt sich FindAllFilesFindAllFiles.
Die liest dir alle Dateien eines Ordners aus und schreibt sie in eine Stringlist und von da an sollte der Rest kein Problem mehr darstellen

Ich denke Findfirst muss dafür herhalten, muss mir mal ein paar Einzelfunktionen basteln...

Nuclear-Ping 12. Nov 2007 21:29

Re: suche Funktion FindLastDir
 
Warum nur FindFirst? Was ist wenn das Verzeichnis mehrere Unterverzeichnisse hat?

bluescreen25 12. Nov 2007 21:55

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von Nuclear-Ping
Warum nur FindFirst? Was ist wenn das Verzeichnis mehrere Unterverzeichnisse hat?

Ich meinte Findfirst & CO

Wie wäre es mit dem ersten Finden des Unterordners verschachtelt diesen wieder als Path in die Funktion zu leiten um wiedrum den ersten Unterordner zu finden, wenn kein UnterOrdner mehr zu finden, dann Rückgabe des letzen Path ? Dann hätte ich schonmal den Pfad.

Diesen kann ich dann mit FindAllFiles nach Dateien durchsuchen und abspielen...


Ich versuche morgen mal einen Ansatz anzubieten..

Gruß, bluescreen25

C.Schoch 13. Nov 2007 18:47

Re: suche Funktion FindLastDir
 
Hi,
Ich hab da mal was gebastelt, das sollte wenn wir nicht völlig aneinander vorbeireden in etwa hinkommen.
Eigentlich soll man ja keine Lösungen posten, aber trotzdem:
Delphi-Quellcode:
  function FindLastDir(sDirectory : string) : string;
  var
    SearchRec : TSearchRec;
  begin
    sDirectory := IncludeTrailingPathDelimiter(sDirectory);
    result := sDirectory;
    if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then
    begin
      try
        repeat
          if ((SearchRec.Attr and faDirectory) = faDirectory) and(SearchRec.Name <> '.') and
          (SearchRec.Name <> '..') then
          begin
            result := FindLastDir(sDirectory + SearchRec.Name);
            break;
          end;
        until FindNext(SearchRec) <> 0;
      finally
        FindClose(SearchRec);
      end;
    end;
  end;
Edit: Absichtlich nicht kommentiert versuch selbst herauszufinden wie und warum, bei Fragen her damit

bluescreen25 14. Nov 2007 15:47

Re: suche Funktion FindLastDir
 
Wow, ansatzweise hatte ich das auch noch so hinbekommen, scheiterte an Einzelheiten...zumindest bin ich jetzt in der Lage, weitere Teilfunktionen zu erstellen, ich denke, ich habs verstanden...

Vielen Dank.. :-D

Zitat:

Zitat von C.Schoch
Hi,
Ich hab da mal was gebastelt, das sollte wenn wir nicht völlig aneinander vorbeireden in etwa hinkommen.
Eigentlich soll man ja keine Lösungen posten, aber trotzdem:
Delphi-Quellcode:
  function FindLastDir(sDirectory : string) : string;
  var
    SearchRec : TSearchRec;
  begin
    sDirectory := IncludeTrailingPathDelimiter(sDirectory); //Path mit Slash versehen,falls fehlt
    result := sDirectory; //das fehlte in meinen Versuchen ??? kannste mir sagen warum ich hier eine Rückgabe liefern muss ?
    if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then// wenn ersten Eintrag gefunden
    begin
      try
        repeat                                                 //Schleife wenn Path eine Dir ist
          if ((SearchRec.Attr and faDirectory) = faDirectory) and(SearchRec.Name <> '.') and
          (SearchRec.Name <> '..') then
          begin          //erste Dir als Path zurückgeben, soweit war ich auch
                          //Verschachtelung erneuter Aufruf der Funktion, immer 1 in die Tiefe
            result := FindLastDir(sDirectory + SearchRec.Name);
            break;       //Abbruch wenn 1 gefunden
          end;
        until FindNext(SearchRec) <> 0; //bis Findnext 0 liefert
      finally
        FindClose(SearchRec);
      end;
    end;
  end;
Edit: Absichtlich nicht kommentiert versuch selbst herauszufinden wie und warum, bei Fragen her damit

Gruß, bluescreen25

C.Schoch 14. Nov 2007 23:05

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von bluescreen25
Wow, ansatzweise hatte ich das auch noch so hinbekommen, scheiterte an Einzelheiten...zumindest bin ich jetzt in der Lage, weitere Teilfunktionen zu erstellen, ich denke, ich habs verstanden...

Vielen Dank.. :-D
Delphi-Quellcode:
  function FindLastDir(sDirectory : string) : string;
  var
    SearchRec : TSearchRec;
  begin
    sDirectory := IncludeTrailingPathDelimiter(sDirectory);
    result := sDirectory; //Hier wird dem result der aufrufende String zugewiesen, da sonst immer ein leerer String zurückgegeben wird --> Siehe Erklärung unten
    if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then
    begin
       try
        repeat
          if ((SearchRec.Attr and faDirectory) = faDirectory) and(SearchRec.Name <> '.') and
          (SearchRec.Name &lt;&gt; '..') then
          begin        
            result := FindLastDir(sDirectory + SearchRec.Name);
            break;      
          end;
        until FindNext(SearchRec) &lt;&gt; 0;
      finally
        FindClose(SearchRec);
      end;
    end;
  end;
Gruß, bluescreen25

Die Funktion ist rekursiv.

Angenommen ich habe einen Verzeichnisbaum der so aussieht,
Zitat:

C:\Ebene1\Ebene2\Ebene3\Ebene4\
Ich rufe meine Funktion so auf:
Delphi-Quellcode:
FindLastDir('C:\Ebene1')
Code:
Dann sieht Result so aus:
  1. Aufruf:
    1. Zuweisung: result = 'C:\Ebene1\'
  2. Aufruf:
    1. Zuweisung: result = 'C:\Ebene1\Ebene2\'
  3. Aufruf:
    1. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\'
    2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\'
  4. Aufruf:
    1. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\' // --> 2.Zuweisung wir nicht ausgeführt!
    kehrt zurück zum
  3. Aufruf:
    2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\'
    break;
    kehrt zurück zum
  2. Aufruf:
    2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\'
    break;
    kehrt zurück zum
  1. Aufruf:
    2. Zuweisung: result = 'C:\Ebene1\Ebene2\Ebene3\Ebene4\'
    break;
    kehrt zurück zu
  Deinem Aufruf, du erhälst: 'C:\Ebene1\Ebene2\Ebene3\Ebene4\'


würde nun die 1. Zuweisung im 4. Aufruf fehlen erhälst du immer: ''
Daraus folgt der Rückgaberwert der Funktion ist immer der im letzten Aufruf ermittelt String.

Ich hoffe ich habe dir die Gedankengänge die zu dieser Zuweisung geführt haben etwas verdeutlichen können :coder2:

alzaimar 15. Nov 2007 06:58

Re: suche Funktion FindLastDir
 
Leider funktioniert die Funktion :mrgreen: nicht immer. Du willst doch den Pfad des am tiefsten verschachtelten Verzeichnisses haben, oder? Also benötigst Du eine Maximierung der Verschachtelungstiefen. Die fehlt hier.

Weiterhin verstehe ich nicht, wieso Du im FindFirst nur nach 'faDirectory' suchst, und dann trotzdem fragst, ob die gefundene Datei auch wirklich ein faDirectory ist... Also ich würde das weglassen.
Das Break nach dem rekursiven Aufruf wird dann auch überflüssig, weil wir doch ALLE Verzeichnisse durchsuchen müssen, und nicht nur das 'erste'.

Hier meine ungetestete Variante:
Delphi-Quellcode:
function FindLastDir(sDirectory : string) : string;
Var
  sDeepestPath : String;
  iMaxLevel : Integer;

  Procedure _DoFindLastDir (sDirectory : String; aLevel : Integer);
  var
    SearchRec : TSearchRec;

  begin
    sDirectory := IncludeTrailingPathDelimiter(sDirectory);
    If aLevel > iMaxLevel Then Begin // <-- wenn besuchte Tiefe > bisherige maximale Tiefe...
      iMaxLevel := aLevel;          // <-- Dann merken wir uns diese Tiefe
      sDeepestPath := sDirectory;   // <-- Sowie den Pfad, der uns bis hierhin gebracht hat
    End;
    if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then
    begin
       try
        repeat
          if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
            _DoFindLastDir(sDirectory + SearchRec.Name, aLevel + 1);
        until FindNext(SearchRec) &lt;&gt; 0;
      finally
        FindClose(SearchRec);
      end;
    end;
  end;

Begin
  iMaxLevel := -1;
  sDeepestPath := '';
  _DoFindLastDir (sDirectory, 0);
End;

marabu 15. Nov 2007 08:12

Re: suche Funktion FindLastDir
 
Moin,

vielleicht habe ich nicht aufmerksam genug gelesen, aber wenn ich die etwas abstrakten Anforderungen mal ignoriere und die durchscheinende Anwendungsidee betrachte, dann verstehe ich folgendes:

Anders als übliche Player will der thread owner ein automatisches Abspielen von Audio-Dateien nicht über einen vom Benutzer geordneten SnapShot eines Verzeichnisbaumes steuern, sondern die physische Abfolge von Titeln unabhängig von der Tiefe der Verzeichnisstruktur heranziehen.

Code:
- Audio
  - Best Of The 50's
    - Dean Martin - Memories Are Made Of This
    - Don Robertson - The Happy Whistler
  - Eagles
    - One Of These Nights
      - Lyin' Eyes
      - Take It To The Limit
    - Desperado
      - Tequila Sunrise
Nach dem Track "The Happy Whistler" soll der Track "Lyin' Eyes" gespielt werden - also ein Depth-First TreeWalk durch einen Verzeichnisbaum, bei dem die leafs die zu spielenden Tracks darstellen.

Freundliche Grüße

bluescreen25 15. Nov 2007 14:09

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von marabu
Moin,

vielleicht habe ich nicht aufmerksam genug gelesen, aber wenn ich die etwas abstrakten Anforderungen mal ignoriere und die durchscheinende Anwendungsidee betrachte, dann verstehe ich folgendes:

Anders als übliche Player will der thread owner ein automatisches Abspielen von Audio-Dateien nicht über einen vom Benutzer geordneten SnapShot eines Verzeichnisbaumes steuern, sondern die physische Abfolge von Titeln unabhängig von der Tiefe der Verzeichnisstruktur heranziehen.

Code:
- Audio
  - Best Of The 50's
    - Dean Martin - Memories Are Made Of This
    - Don Robertson - The Happy Whistler
  - Eagles
    - One Of These Nights
      - Lyin' Eyes
      - Take It To The Limit
    - Desperado
      - Tequila Sunrise
Nach dem Track "The Happy Whistler" soll der Track "Lyin' Eyes" gespielt werden - also ein Depth-First TreeWalk durch einen Verzeichnisbaum, bei dem die leafs die zu spielenden Tracks darstellen.

Freundliche Grüße

So wie du es oben darstellst, soll es sein, wenn du noch einzelne Files z.B. in Eagles\berücksichtigst sowie eine Maximalgrenze nach oben, ich biete da mal das festgelegte Rootverzeichnis "Audio" an. Ist "Tequila Sunrise" abgespielt, sollte er wieder oben anfangen bzw er geht nach "Dean Martin" durch die Tiefen-Funtion.

Hallo, also ganz so abstrakt sind die Anforderungen ja nicht. Grundsätzlich verwende ich das EasyListView zum darstellen der Struktur und man kann selbst durch alle Ordner zappen und irgendwas anspielen. Befinde ich mich in einem Ordner, spiele ich jetzt diesen ab und am Ende wieder zum ersten Track.

Jetzt kam die Frage bei den Usern auf, ob man nicht am Ende zum nächsten Ordner springen kann und diesen dann abspielen. Das fällt bei mir so in die Art eines CD-Wechslers mit dem Unterschied, das es halt im Verzeichnisbaum auch Tiefen gibt.

Mit weiteren Gedanken kam ich dann dazu, das in jedem Ordner sowie UnterOrdner als auch RestFiles liegen können, die auch automatisiert abgespielt werden müssen.

Um überhaupt das Ganze zu ermöglichen, kann ich 2 Dinge tun:

1: innerhalb des ListViews gezielt die Indexe abfragen und springen, was aber immer eine Aktualisierung des Listviews zur Folge hat, also schlecht (ListView wird über FindAllFiles gefüllt)
2: Die Struktur absuchen mit Funktionen zur Pfadermittlung aber auch Funktionen für die Inhalte der wie Ordner und Files zu haben....und wenn alles richtig läuft, das PlayFile erreicht eine einmalige Aktualisierung des ListView

So mal ganz unprofessionell angefangen (unfertig):

Delphi-Quellcode:
procedure FindDir;
var i:integer;
    aPath:string;
label DirSearch;
begin
  aPath := ExcludeTrailingPathDelimiter(PlayPath);//PlayPath merken ggf noch ändern
  Path := GetAudioplayerDirectory(PlayPath);  //Path eine Ebene höher als PlayPath
  showmessage(path);
DirSearch:

  DirLst.Clear;
  ListeDir(Path,DirLst);                    //dort alle Ordner in Stringliste holen


{****nächsten Ordner unter PlayOrdner suchen und 1.Fileabspielen**************}

  if DirLst.Count >0 then                     //wenn mehr als 0 Ordner vorhanden
   begin
     for I := 0 to DirLst.Count-1 do          //Ordner zählen und Play-Ordnernamen
     if aPath = DirLst.Strings[I] then        //mit Liste vergleichen bzw suchen
     break;                                   //wenn gefunden
     Inc(I);                                  //Index-Nr ab Playordner um 1 erhöhen
   end;


  if (I < DirLst.Count) then               //** wenn OrdnerIndex < DirLsteintraege
   begin
     if DirectoryExists(DirLst.Strings[I]) then //wenn Ordner vorhanden
     Path := FindLastDir(DirLst.Strings[I]); //neuen Path setzen auf tiefsten Ordner
     DirLst.Clear;                           //vom indexierten Ordner setzen
     FileLst.Clear;
     search:=true;
     FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true);//dort alle Ordner...
     search:=false;              // ...und Files in Stringlisten holen,DirLst sollte
                                  //...leer bleiben da in tiefsten Ordner
     if FileLst.Count >0 then              //wenn in Fileliste mehr als 0 Einträge
     begin
       if FileExists(FileLst.Strings[0]) then   //wenn File vorhanden (1. File)
        begin
          ShowMediaFiles(listmedia,false,true); //AudioListe aktualisieren
          showmessage('Play in tiefster Ebene');
          Play(Path,0);                         //dann 1.File abspielen
        end;
     end else                              //wenn keine Einträge in Stringliste, dann
           begin
             showmessage('kein File vorhanden in tiefster Ebene');
             Goto DirSearch;
           end;

   end else if FileLst.Count >0 then     //wenn erhöhter OrdnerIndex >DirLsteinträge
     begin                                      //sprich kein weiterer Ordner mehr
       if FileExists(FileLst.Strings[0]) then   //dann wenn File vorhanden (1. File)
        begin
          ShowMediaFiles(listmedia,false,true); //Audioliste aktualisieren
          showmessage('Play restliche Files unter Ordner');
          Play(Path,0);                         //und 1.File abspielen


        end else
             begin                   //wenn Ordner und Files nicht mehr vorhanden
               showmessage('Loop zum ersten Ordner vom Root')  
               fehlt noch           //dann bei erstem Ordner ab MediaRoot anfangen
             end;

bluescreen25 15. Nov 2007 14:42

Re: suche Funktion FindLastDir
 
Zitat:

Zitat von alzaimar
Leider funktioniert die Funktion :mrgreen: nicht immer. Du willst doch den Pfad des am tiefsten verschachtelten Verzeichnisses haben, oder? Also benötigst Du eine Maximierung der Verschachtelungstiefen. Die fehlt hier.

Weiterhin verstehe ich nicht, wieso Du im FindFirst nur nach 'faDirectory' suchst, und dann trotzdem fragst, ob die gefundene Datei auch wirklich ein faDirectory ist... Also ich würde das weglassen.
Das Break nach dem rekursiven Aufruf wird dann auch überflüssig, weil wir doch ALLE Verzeichnisse durchsuchen müssen, und nicht nur das 'erste'.

Hier meine ungetestete Variante:
Delphi-Quellcode:
function FindLastDir(sDirectory : string) : string;
Var
  sDeepestPath : String;
  iMaxLevel : Integer;

  Procedure _DoFindLastDir (sDirectory : String; aLevel : Integer);
  var
    SearchRec : TSearchRec;

  begin
    sDirectory := IncludeTrailingPathDelimiter(sDirectory);
    If aLevel > iMaxLevel Then Begin // <-- wenn besuchte Tiefe > bisherige maximale Tiefe...
      iMaxLevel := aLevel;          // <-- Dann merken wir uns diese Tiefe
      sDeepestPath := sDirectory;   // <-- Sowie den Pfad, der uns bis hierhin gebracht hat
    End;
    if FindFirst(sDirectory + '*.*', faDirectory, SearchRec) = 0 then
    begin
       try
        repeat
          if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
            _DoFindLastDir(sDirectory + SearchRec.Name, aLevel + 1);
        until FindNext(SearchRec) &lt;&gt; 0;
      finally
        FindClose(SearchRec);
      end;
    end;
  end;

Begin
  iMaxLevel := -1;
  sDeepestPath := '';
  _DoFindLastDir (sDirectory, 0);
End;

Hallo, also eigendlich müssen wir doch nicht alle Ordner durchsuchen, sondern im ersten gefundenen reinspringen und dort wiederum den ersten suchen, bis am Ende der erste unterste Pfad zurückgegeben wird.

Fürs abspielen der Tracks brauche ich immer den ersten Ordner im Verzeichnis in der Tiefe. Den abgespielt, wird der nächste herangezogen, keiner mehr da, dann eine Ebene höher den nachfolgenden Ordner suchen, in die Tiefe gehen....

Die Funktion sollte nur einen Teil des Ganzen sein...damit kann man nicht alle Vorgänge abfangen, wollte das in TeilFunktionen machen und dann zusammensetzen....

bluescreen25 16. Nov 2007 12:58

Re: suche Funktion FindLastDir
 
Soo hier mal die komplette Procedure um den nächsten Track zu finden und abzuspielen:
Vielleicht gibt es ja noch Verbesserungsvorschläge in Bezug auf ein Limit nach oben setzen bzw Abbrechen, wenn er zulange sucht...

Delphi-Quellcode:
procedure PlayAbsoluteNext;
var I:integer;
    bPath:string;

label setIndex,proofFolder,proofFiles,noFiles,areFiles;
begin
  ListFlag := True;                              //PlayIcons ausblenden
  bPath := ExcludeTrailingPathDelimiter(PlayPath);//PlayPath merken
  GetAudioplayerDirectory(PlayPath);             //Drives abfragen

  if (bPath = MediaPath)or(DriveLst.Count >0) then //oberste Rootgrenze erreicht
  begin
    Path := MediaPath;
    I := 0;
    search:=true;
    DriveLst.Clear;
    DirLst.Clear;
    FileLst.Clear;
    FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true);
    (DirLst as TStringList).Sort; //alphab. sortieren
    (FileLst as TStringList).Sort;
    goto proofFolder;
                            //Path eine Ebene höher als PlayPath,Rootgrenze nicht
  end else Path := GetAudioplayerDirectory(PlayPath);        //...erreicht




setIndex:                                 //...Durchlaufpruefungen !

  search:=true;
  DriveLst.Clear;
  DirLst.Clear;
  FileLst.Clear;
  FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true);
  (DirLst as TStringList).Sort; //alphab. sortieren
  (FileLst as TStringList).Sort;

  if DirLst.Count >0 then
   begin
     for I := 0 to DirLst.Count-1 do      //Ordner zählen und Play-Ordnernamen
     if bPath = DirLst.Strings[I] then    //mit Liste vergleichen bzw suchen
     break;                               //wenn gefunden
     Inc(I);                              //Index-Nr ab Playordner um 1 erhöhen
   end;


proofFolder:                                         //...auf Ordner pruefen
  if (I < DirLst.Count) then
   begin
     if DirectoryExists(DirLst.Strings[I]) then
     Path := FindLastDir(DirLst.Strings[I]);//neuen Path setzen auf tiefsten Ordner
     DriveLst.Clear;
     DirLst.Clear;
     FileLst.Clear;
     search:=true;
     FindAllFiles(DirLst,FileLst,Path,FileMask,false,true,true);//Inhalte holen
     (DirLst as TStringList).Sort; //alphab. sortieren
     (FileLst as TStringList).Sort;
   end;
  goto proofFiles;


proofFiles:                                         //..auf Files pruefen
   if FileLst.Count = 0 then goto noFiles
   else if FileLst.Count > 0 then goto areFiles;


areFiles:                                          //..Files vorhanden
   if FileExists(FileLst.Strings[0]) then
    begin
      ShowMediaFiles(listmedia,false,true);
      Play(Path,0);
    end;
   exit;


noFiles:                                       //..keine Files vorhanden
  bPath := ExcludeTrailingPathDelimiter(Path);
  if bPath = MediaPath then Path := MediaPath //oberste Rootgrenze erreicht
   else Path := GetAudioplayerDirectory(Path); //Path eine Ebene höher als PlayPath

  goto setIndex;                              //..dann erneuter Durchlauf


end;

alzaimar 16. Nov 2007 18:15

Re: suche Funktion FindLastDir
 
Oh mann, das muss einem grenzdebilen Frührenter wie mir doch gesagt werden, was überhaupt gewollt ist... :oops:


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