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 Aktualisierung ListView mit FindAllFiles (https://www.delphipraxis.net/79566-aktualisierung-listview-mit-findallfiles.html)

bluescreen25 24. Okt 2006 21:44


Aktualisierung ListView mit FindAllFiles
 
Hallo,
ich bringe durch FindAllFiles gesuchte Dateien in meine ListView.

In FindallFiles adde ich direkt in Stringlisten, damit die Anzeige kontinuierlich File für File kommt.
Für den schnelleren virtual-Mode muss ich jedoch ListView.beginupdate bzw endupdate einfügen, das ist mir innerhalb der Repeatschleife gelungen.

Klappt jetzt wunderbar schnell und kontinuierlich, wenn ich jedoch während des addens mit der Maus über das ListView fahre, hängt das Programm.

Es liegt wohl daran, das ich in der Schleife das ListView daran hindere sich neu zu zeichnen und beim Überfahren mit der Maus muss ein Event kommen, welche wahrscheinlich das ListView neuzeichnen lassen will, nur was genau kann es sein ???

Hier mal der Code:
Delphi-Quellcode:
procedure FindAllFiles(DirList:TStrings; FileList: TStrings; RootFolder: string; Mask: string; Recurse: Boolean = True; AddFolderNames: Boolean = False; IgnoreMaskAtFolderNames: Boolean = True);
var Tick : Cardinal;
  procedure LFindAllFiles(AParentFolder: String);
  var LSearchRec: TSearchRec;
  begin
    if FindFirst(AParentFolder + '*', faAnyFile, LSearchRec) = 0 then
    begin
      repeat
        ListMedia.BeginUpdate;

        if GetTickCount <= Tick then
        begin
          Tick := GetTickCount + 200;
          Application.ProcessMessages;
        end;

        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
              begin
               DirList.AddObject(AParentFolder + LSearchRec.Name, TObject(True));
               ListMedia.Items.AddVirtual(DirLst);
              end;

            if Recurse then
              LFindAllFiles(AParentFolder + LSearchRec.Name + '\');
          end
          else if Like(AnsiLowerCase(LSearchRec.Name), Mask) then
             begin
              FileList.AddObject(AParentFolder + LSearchRec.Name, TObject(False));
              ListMedia.Items.AddVirtual(FileLst);
             end;
         end;
        ListMedia.EndUpdate;
       until FindNext(LSearchRec) <> 0 ;
      FindClose(LSearchRec);
     end;
   end;

  begin
  tick:=gettickcount;
  Mask := AnsiLowerCase(Mask);
  LFindAllFiles(IncludeTrailingPathDelimiter(RootFolder));
 
end;
Gruß bluescreen25

SirThornberry 24. Okt 2006 21:56

Re: ein weiteres ListView Problem
 
Könntest du bitte deinem Beitrag, entsprechend den Regeln des Forums, einen aussagekräftigen Titel verleihen?

Matze 24. Okt 2006 21:59

Re: ein weiteres ListView Problem
 
Hi,

gib BeginUpdate und EndUpdate mal um die Repeat-Schleife herum.

bluescreen25 25. Okt 2006 12:42

Re: ein weiteres ListView Problem
 
Zitat:

Zitat von SirThornberry
Könntest du bitte deinem Beitrag, entsprechend den Regeln des Forums, einen aussagekräftigen Titel verleihen?

Hmm da haste natürlich Recht... :oops:

Gruß bluescreen25

bluescreen25 25. Okt 2006 12:45

Re: ein weiteres ListView Problem
 
Zitat:

Zitat von Matze
Hi,

gib BeginUpdate und EndUpdate mal um die Repeat-Schleife herum.

Ausserhalb der Schleife habe ich dann kein kontinuierliches Befüllen mehr, sondern erst nach Abarbeiten der Schleife.

Genau das ist ja mein Problem bei vielen Einträgen (>5000)das solange das Listview leer bleibt. Anderherum ohne BeginUpDate etc...ist es schnarchend langsam...

Gruß bluescreen25

C.Schoch 25. Okt 2006 19:34

Re: Aktualisierung ListView mit FindAllFiles
 
Wann möchtest du denn das ListView Updaten? wenn man mit der Maus drüberfährt?

wie wärs damit?
Delphi-Quellcode:
procedure ListView1OnMouseEnter();
begin
ListView1.EndUpdate;
end;

procedure ListView1OnMouseLeave();
begin
ListView1.BeginUpdate;
end;
OnMouseEnter/Leave sind beides events des ListViews wenn ichs noch genau weis.

bluescreen25 25. Okt 2006 22:35

Re: Aktualisierung ListView mit FindAllFiles
 
Zitat:

Zitat von C.Schoch
Wann möchtest du denn das ListView Updaten? wenn man mit der Maus drüberfährt?

wie wärs damit?
Delphi-Quellcode:
procedure ListView1OnMouseEnter();
begin
ListView1.EndUpdate;
end;

procedure ListView1OnMouseLeave();
begin
ListView1.BeginUpdate;
end;
OnMouseEnter/Leave sind beides events des ListViews wenn ichs noch genau weis.

eigendlich nicht, es sollte in kontinuierlich updaten, vielleicht zeitlich in Abständen.

Deine Möglichkeit würde das Problem überbrücken, das wenn ich mit der Maus über das ListView fahre,das Programm nicht sich aufhängen zu lassen. Müsste ich aber prüfen.

Grüße,bluescreen25

bluescreen25 28. Okt 2006 12:29

Re: Aktualisierung ListView mit FindAllFiles
 
Damit die Frage auch beantwortet ist:
Nochmal zur Erinnerung: Es geht um die Kompo EasyListView im schnellen virtualMode, kann aber auch in der normalen ListView in virtualMode genutzt werden.


1.) In FindAllFiles werden die gefundenen Ordner und Files jeweils in eine StringList gebannt.

Delphi-Quellcode:
...
   Search := True;
...
     begin
       ShowList.Items.Clear; //ListView
       FileLst.Clear;       //StringList
       DirLst.Clear;        //StringList
       LastAdded:=0; //Zähler bisher aktualisierte Items in ListView
       tiAddTimer.Enabled := True; //addTimer aktualisiert ListView
       FindAllFiles(DirLst, FileLst, Path, FileMask, Rekursive, False, True);//FileSuche
       form1.AddSearchItems(FileLst.count); //Aktualisierung nach FileSuche beendet
     end;                                  //bzw nach letzter addTimer-Aktualisierung
...
2.) Ein Timer ruft in Intervallen die AddVirtual-procedure auf.
Timer beendet sich selbst nach letztem Durchlaufen, damit nach Ende der Suche auch die letzten
gefundenen Einträge übergeben werden.

Delphi-Quellcode:
procedure TForm1.tiAddTimerTimer(Sender: TObject);//TimerInterval bestimmt erste
begin                                          //und folgende Aktualisierungen                                    //guter Mittelwert = 500 ms
    ShowLabel('songvalue', Format('%.0n Song(s) in Playlist', [1.0 * FileLst.Count]));
    if Search then
      AddSearchItems(FileLst.count) // procedure Files AddVirtual
    else
      tiAddTimer.Enabled := False; //FileSuche/Aktualisierung beendet
end;
3.) Die jeweils noch nicht geaddeten Einträge werden beim timerDurchlauf angefügt.

Delphi-Quellcode:
procedure TForm1.AddSearchItems(Count: Integer);
var
  i: Integer;                        // Items Virtual geaddet
begin
   ListMedia.BeginUpdate;  //ListView NeuzeichnungsStop
   ListMedia.Items.ReIndexDisable := True;
   LastAdded:=0; //Zähler bisher aktualisierte Items in ListView
   LastAdded := FileLst.Count - ListMedia.Items.count;//Count,wichtig für Virtual
  try
    for i := 0 to LastAdded - 1 do
      ListMedia.Items.AddVirtual;  //virtual geaddete Items, sichtbar durch:
  finally                                   //procedure SkinListItemGetCaption
    ListMedia.Items.ReIndexDisable := False;
    ListMedia.EndUpdate;   //ListView NeuzeichnungsStop aufgehoben
  end;
end;

4.) Die eigendliche Anzeige der Items im ListView

Delphi-Quellcode:
procedure TForm1.SkinListItemGetCaption(Sender: TCustomEasyListview;Item: TEasyItem; Column: Integer; var Caption: WideString);
var idx : integer; // Index of Dir/FileList
    s : TStrings; // Dir/FileList
    t : integer;  // ohne Dateiendung (4 Stellen gekürzt)
begin
  case Column of
    0:begin
       if item.index < DirLst.Count then
         begin
           s := DirLst;
           idx := item.Index;
           t := 0;
         end
       else
         begin
           s := FileLst;
           idx := item.index - DirLst.Count;
           t := 4;
         end;                       // gekürzte Filenames in Column 0 von ListView
       caption := (copy(ExtractFilename(s.strings[idx]),0, length(ExtractFilename(s.strings[idx]))-t));
      end;
    1:begin
        if item.index < DirLst.Count then
         begin
           s := DirLst;
           idx := item.Index;
         end
       else
         begin
           s := FileLst;
           idx := item.index - DirLst.Count;
         end;
       caption := s.strings[idx]; // komplette Pfade in Column 1 von ListView
      end;
    end;
end;
Viele Grüße,bluescreen25


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