Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi [TListView & FindFirst/Next] Fehlerhafte Suche (https://www.delphipraxis.net/76328-%5Btlistview-findfirst-next%5D-fehlerhafte-suche.html)

xZise 2. Sep 2006 13:12


[TListView & FindFirst/Next] Fehlerhafte Suche
 
Ich habe selber einen OpdenDialog programmiert...
Wenn ich auf ein TShellTreeView einen Ordner auswähle soll er alle *.mp3/*.wav und Ordner in diesem Ordner anzeigen (im DataView = TListView)!

Das ist die Suchenprozedur:
Delphi-Quellcode:
procedure TfrmOp.FolderShellTreeViewChange(Sender: TObject;
  Node: TTreeNode);
var
  sr : TSearchRec;
  Ext : string;
begin
  DataView.Clear;
  label1.Caption := FolderShellTreeView.Path;
  // Find Directorys
  if FindFirst(FolderShellTreeView.Path, faDirectory, sr) = 0 then begin
    repeat
      Application.ProcessMessages;
      with DataView.Items.Add do begin
        ImageIndex := 0;
        Caption := sr.Name;
      end;
    until FindNext(SR) <> 0;
  end;

  // Find MusicFiles
  if FindFirst(FolderShellTreeView.Path, faAnyFile, sr) = 0 then begin
    repeat
      Application.ProcessMessages;
      Ext := ExtractFileExt(sr.Name);
      if (Ext = '.mp3') or (Ext = '.wav') then
        with DataView.Items.Add do begin
          ImageIndex := 1;
          Caption := sr.Name;
        end;
    until FindNext(SR) <> 0;
  end;
end;
Allerdings zeigt er nur den aktuell markierten Ordner an.
Und wenn es z.B. so aussieht:
Code:
- [O] Meine Musik
- - [D] M1.mp3
- - [D] M2.mp3
- - [D] Windows_ShutDown.wav
- - [O] Alte Musik
Und ich auf "Alte Musik" klicke, zeigt er nicht, wie ich erwartet hätte auch noch die Musikdateien an, sondern nur "Alte Musik"!
([O] = Ordner und [D] = Datei)

Christian Seehase 2. Sep 2006 13:58

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Moin Fabian,

wenn Du die Ordnerstruktur nicht rekursiv durchsuchst, findest Du auch nur die Daten auf eine Ebene.
Für das Durchsuchen einer gesamten Struktur (auch ab einem bestimmten Verzeichnis) findest Du hier eine ganze Menge Beispiele.
(Hier im Forum suchenFindFirst and FindNext and FindClose)

Ausserdem fehlen noch die Resourcenschutzblöcke try/finally und das FindClose sicherzustellen.
(deren Anwendung sollte in den Fundstellen auch beschrieben sein)

xZise 2. Sep 2006 14:09

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Ich möchte auch nur die Dateien die in "Meine Musik" sind und nicht, die in "Alte Musik" sin (ö.ä.)!
Also wie ein standardmäßiger OpenDialog...
Das mit dem FindClose liegt daran, dass ich es das erste mal veruscht habe eine Suche ohne Hilfe von außen zu Progen ... Okay Wird gemacht!

Christian Seehase 2. Sep 2006 16:15

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Moin Fabian,

das Beispiel in der Delphi-Hilfe ist übrigens auch fehlerhaft.
Zum einen fehlt try/finally (wie oben angesprochen), zum anderen werden die Attribute mit + verknüpft.
Diese sollten man aber auf jeden Fall mit OR verknüpfen.
Bezogen auf das Beispiel in der Hilfe:
Sobald die 7. Checkbox und irgendeine (auch mehrere) andere aktiviert wurden, erhält FileAttrs einen ungültigen Wert.

Was mir gerade noch aufgefallen ist:
Also Suchmaske nimmst Du nur den Pfad. Probier's mal mit:

Delphi-Quellcode:
FindFirst(FolderShellTreeView.Path+'\*.*',....
Um die Dateien von vornherein zu filtern:

Delphi-Quellcode:
FindFirst(FolderShellTreeView.Path + '\*.mp3',....

bzw.

FindFirst(FolderShellTreeView.Path + '\*.wav',....
also zweimaliger Aufruf, bzw. besser noch, indem Du die Endungen in einer Schleife der Reihe nach durchgehst.
Du kannst natürlich auch nach allen suchen, und dann hinterher filtern, hierbei solltest Du aber daran denken, das

Delphi-Quellcode:
if Ext = '.mp3' then ...
fehlschlägt, wenn die Endung nicht kleingeschrieben wurde, also z.B. .Mp3 lautet.
Schau Dir dazu mal LowerCase (UpperCase) bzw. AnsiLowerCase an.

xZise 2. Sep 2006 22:45

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Also mit dem Atribut "faDirectory" findet er trotzdem Dateien (Hä?)...

Ich weiß leider nicht, wie ich ein try/finally einbauen soll...
Macht er etwa ein "sr := TSearchRec.Create" im FindFirst?

Was ist den Effektiver (@ Endung):
Eine If Abfrage oder Nur nach der Endung suchen?

Christian Seehase 2. Sep 2006 23:21

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Moin Fabian,

Zitat:

Zitat von xZise
Ich weiß leider nicht, wie ich ein try/finally einbauen soll...
Macht er etwa ein "sr := TSearchRec.Create" im FindFirst?

Intern benutzt FindFirst die API-Funktion FindFirstFile, und belegt, bei erfolgreichem Aufruf, ein Handle.
Dieses muss man mit dem FindClose wieder freigeben.

So eine Routine könnte z.B. so aussehen:

Delphi-Quellcode:
procedure ReadFolder(const AsRoot : string;const AslResult : TStrings);

var
  sr : TSearchRec;

begin
  if FindFirst(AsRoot+'\*.*',faAnyFile,sr) <> 0 then exit;
  try
    repeat
      if ((sr.Attr and faDirectory) = faDirectory) then begin
        if (sr.Name <> '.') and (sr.Name <> '..') then begin
          ReadFolder(AsRoot+'\'+sr.Name,AslResult);
        end;
      end else begin
        AslResult.Add(AsRoot+'\'+sr.Name);
      end;
    until FindNext(sr) <> 0;
  finally
    FindClose(sr);
  end;
end;
Zitat:

Zitat von xZise
Also mit dem Atribut "faDirectory" findet er trotzdem Dateien (Hä?)...

Ja, tut sie. FindFirstFile filtert nicht, und die Implementierung von FindFirst tut dies, entgegeben der Hilfe auch nicht.

Zitat:

Zitat von xZise
Was ist den Effektiver (@ Endung):
Eine If Abfrage oder Nur nach der Endung suchen?

Einmal durch die Verzeichnisse durchgehen, und anschliessend, immer wenn eine Datei gefunden wurde, auf die Endung zu prüfen ist auf jeden Fall einfacher zu schreiben.
Ansonsten müsstest Du bei jedem Verzeichnis, dass Du findest, noch einmal einen FindFirst/FindNext/FindClose-Block für die Endungen durchlaufen.
Welche von den beiden Methoden effektiver ist, kann ich allerdings auch nicht sagen.

xZise 2. Sep 2006 23:39

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Zitat:

Zitat von Christian Seehase
Zitat:

Zitat von xZise
Also mit dem Atribut "faDirectory" findet er trotzdem Dateien (Hä?)...

Ja, tut sie. FindFirstFile filtert nicht, und die Implementierung von FindFirst tut dies, entgegeben der Hilfe auch nicht.

- Und wofür ist dann der Paramter?
- Wie kann ich es realisieren, ob das ein Ordner/Datei ist?

Christian Seehase 2. Sep 2006 23:44

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Moin Fabian,

versuch' doch mal die Funktion, die ich da gepostet habe nachzuvollziehen.
Die unterscheidet zwischen Ordner und Datei.

xZise 3. Sep 2006 11:34

Re: [TListView & FindFirst/Next] Fehlerhafte Suche
 
Oh stimmt... Ich hab nur aufs Try-Finally geguckt... :D


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