Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Listbox Sortierung (https://www.delphipraxis.net/103141-listbox-sortierung.html)

edi-mv 11. Nov 2007 00:53


Listbox Sortierung
 
Hallo, Delphi- Freunde, wer kann helfen ?
Ich habe eine Listbox, die ein gewähltes Verzeichnis listen soll. Tut sie auch. Beim Create der Form wird die Funktion Verzeichnis_Links_Einlesen() aufgerufen.
Diese dreht mit repeat eine Runde alle Unterverzeichnisse listen, dann noch eine repeat- Runde Dateien listen.
In der Listbox kommen dann auch erst alle Ordner, darunter alle Dateien, wie's sein soll.
...Nur nicht alphabetisch. Klar- wie auch..
Wenn ich nun aber nach den "Einlese- Runden" mit der Eigenschaft sortType
Delphi-Quellcode:
Main.MainForm.ListView_Links.sortType := stText ;
einsetze, habe ich danach Ordner UND Dateien zwar alphabetisch sortiert im ListView... aber Ordner und Dateien durcheinander. Sogar schon, wenn ich die Zeile gleich nach der "Verzeichnis- Runde" einsetze, und nach der Dateien- Runde nicht.
Hat jemand eine Idee, warum das ListView das so macht, und wie ich das korrekt hinkriege ?
Vielen Dank im Voraus !
edi

Hier die Funktionen dazu. (Das Listobjekt- Array speichert den vollen Pfad zu Verzeichnis/ Datei für andere Aufgaben)
Delphi-Quellcode:
procedure Verzeichnis_Links_Einlesen(DIR:string);               //
VAR                                                             //
  SR: TSearchRec;                                               //
  INDEX: Integer ;                                             //
  DriveNumber: Integer ;                                        //
  ErrorMode: word;                                              //
                                                                 //
Begin                                                           //
  INDEX := 0 ;                                                  //
{************** 1. Durchgang: Verzeichnisse ***************}     //
{Neues Datenobjekt erzeugen}                                     //
ListObjekt_Links := TListObjekt.Create ;                        //
 {Übergebenes Verzeichnis existent ?...}                         //
 If DirectoryExists(DIR) then                                   //
  Begin ;                                                       //
   if DIR[length(DIR)]<>'\' then                                //
    DIR:=DIR+'\';                                               //
    with MainForm do begin                                      //
      if FindFirst(DIR+'*.*',faAnyFile,SR) = 0 then Begin      //
        repeat                                                  //
     {Nur Verzeichnisse zulassen}                                //
          if (                                                   //
              (SR.Attr and FaDirectory = FaDirectory) and       //
              (SR.Name <> '.') and                             //
              (SR.Name <> '..')                                 //
              ) then                                           //
             Begin                                              //
      {Datenzuweisung an ListView}                               //
               PFAD_LI := Uppercase(DIR) + SR.Name ;            //
               ListView_Links_Items_Add(                         //
                              PFAD_LI,                          //
                              'Dir',                            //
      FormatDateTime ('dd.mm.yyyy',FileDateToDateTime(SR.time)), //
                              Fileops.GetAttribut(SR.attr)      //
                                       );                       //
                                                                 //
      {Datenzuweisung an Array im Datenobjekt}                   //
               ListObjekt_Links.Set_PFAD(INDEX, PFAD_LI) ;      //
               INDEX := INDEX + 1 ;                             //
             End;                                               //
        until FindNext(SR)<>0;                                  //
        FindClose(SR);                                          //
      {Nach jedem findfirst nötig, um sr freizugeben!}           //
      End;                                                      //
    end;                                                        //
                                                                 //
   {************2. Durchgang: Dateien **********************}    //
    if DIR[length(DIR)]<>'\' then                               //
      DIR:=DIR+'\';                                             //
    with MainForm do begin                                      //
      if FindFirst(DIR+'*.*',faAnyFile,SR) = 0 then Begin      //
        repeat                                                  //
              {Nur Dateien zulassen}                             //
          if not (SR.Attr and FaDirectory = FaDirectory) then  //
             Begin                                              //
               {Datenzuweisung an ListView}                      //
               PFAD_LI := Uppercase(DIR) + SR.Name ;            //
               ListView_Links_Items_Add(                         //
                           PFAD_LI,                             //
                           GetCorrectFileSize(PFAD_LI),         //
      FormatDateTime ('dd.mm.yyyy',FileDateToDateTime(SR.time)), //
                             Fileops.GetAttribut(SR.attr)       //
                                        );                      //
                                                                 //
               {Datenzuweisung an Array im Datenobjekt}          //
               ListObjekt_Links.Set_PFAD(INDEX, PFAD_LI) ;      //
               INDEX := INDEX + 1 ;                             //
             End;                                               //
        until FindNext(SR)<>0;                                  //
        FindClose(SR);                                          //
        {Nach jedem findfirst nötig, um sr freizugeben!}         //
      End;                                                      //
    end;                                                        //
                                                                 //
      {Anzeige des Platzes im oberen Editfeld}                   //
    Main.MainForm.Edit_LW_Links.Text :=                         //
                                 DirOps.GetDriveSpaceData(DIR) ; //
                                                                 //
    Main.MainForm.Edit_Links.Text := DIR ;                      //
 end ;                                                          //
end;                                                            //
Delphi-Quellcode:
                                                                 
{Wird von Prozedur Einlesen aufgerufen}                          //
procedure ListView_Links_Items_Add(const PFAD_LI,               //
                                         GROESSE,               //
                                         DATUM,                 //
                                         ATTRIBUTE: string      //
                                         );                     //
var                                                             //
  Newitem: TListItem;                                           //
  Info: TSHFileInfo; {uses shellapi;}                           //
  ANZEIGENAME_LI: String ;                                      //
Begin                                                           //
  ANZEIGENAME_LI := DirOps.Anzeigename(PFAD_LI) ;               //
  NewItem := MainForm.ListView_Links.Items.Add ;                //
  NewItem.Caption := ANZEIGENAME_LI ;                           //
  newItem.subitems.add(GROESSE);                                //
  newItem.subitems.add(DATUM);                                  //
  newitem.subitems.Add(ATTRIBUTE);                              //
                                                                 //
  {if pos('\', PFAD_LI) = 0 then NewItem.ImageIndex := -1 else}  //
    Begin                                                       //
      SHGetFileInfo(PChar(PFAD_LI), 0, Info, SizeOf(TSHFileInfo),//
      SHGFI_SYSIconIndex or SHGFI_TYPENAME);                    //
      NewItem.ImageIndex := Info.IIcon;                         //
    End;                                                        //
end;                                                            //

efknarf 11. Nov 2007 02:18

Re: Listbox Sortierung
 
Hallo,

Schau in der Hilfe mal unter TListView.OnCompare nach. Vielleicht geht es auch einfacher, aber ich würde bei dem Einlesen der Dateinamen den Typ der Datei irgendwie und irgendwo in den ListItems speichern, also ob es sich um eine Datei handelt oder um einen Ordner. Dieser Typ kann dann bei der Sortierung ausgelesen werden und nach diesem Flag erfolgt dann die Sortierung in der Methode OnCompare... . Nicht vergessen, die Eigenschaft SortType auf stData oder stBoth zu setzen, da ansonsten OnCompare nicht aufgerufen wird. Falls du für Ordner ein eigenes Icon verwendest und für Dateien ein anderes, dann kannst du anhand des Item.ImageIndex-es feststellen, ob es Ordner oder Datei ist.


Gruß

Frank

marabu 11. Nov 2007 08:18

Re: Listbox Sortierung
 
Moin Edi,

du hast deine Delphi-Version nicht angegeben - trotzdem: Weißt du, dass die Komponente TShellListView mit der Eigenschaft Sorted = True und in Verbindung mit dem Ereignis OnAddFolder() eigentlich genau das tut, was du nachzustellen versuchst?

SortType <> stNone führt ab dem Zeitpunkt des Setzens zu einer automatischen Sortierung.

Und noch ein paar Tipps:
  • Eine ListView kann auch im virtuellen Modus betrieben werden, so dass deine doppelte Datenvorhaltung unnötig wird.
  • ListBox ist kein Synonym für ListView.
  • Die Funktion IncludeTrailingPathDelimiter() hängt den backslash nur dann an, wenn es auch korrekt ist.
  • Du kannst Dateien und Ordner ruhig in einem Durchgang aufnehmen und die Fallunterscheidung in der einen Schleife machen.
  • Wenn du an den Namen eines Verzeichnisses einen backslash anhängst, dann kannst du bei einer virtuellen ListView und beim Sortieren Ordner und Dateien leicht unterscheiden.
  • Der Zugriff auf visuelle Komponenten aus einer Methode heraus ist in Ordnung, aus einer freien Prozedur oder Funktion solltest du nach Möglichkeit nur auf Objekte zugreifen, die als Parameter übergeben wurden.
Ich kann an deinem Code erkennen, dass du dir Gedanken gemacht hast, aber da steckt noch viel Verbesserungspotential drin.
Vergiss nicht mit einem richtig großen Verzeichnis zu testen.

Freundliche Grüße

edi-mv 11. Nov 2007 14:20

Re: Listbox Sortierung
 
Hallo, Marabu !
Danke für die Tips.

Zitat:

du hast deine Delphi-Version nicht angegeben
Ich arbeite mit Delphi5 Prof. und Delphi6 Personal.

Zitat:

ListBox ist kein Synonym für ListView
Sorry... Sollte natürlich ListView heißen.

Zitat:

Ich kann an deinem Code erkennen, dass du dir Gedanken gemacht hast...
Danke... ja, hab' ich, das wurde ein Programm mit vielen Funktionen, die ICH ständig brauche, und war mein erstes Delphi- Projekt. Deshalb auch die umständliche Zuweisung der Pfade an ein Listview UND an ein Listobjekt- Array. Das ListView kriegt den Pfad "gecuttet", und zeigt nicht den kompletten Pfad an, nur, was hinter dem letzten Backslash steht, im Array ist der Pfad komplett gespeichert, mit Klick auf "Eine Ebene höher" liest die Einlese- Funktion dann immer den jeweils um das hinter dem letzten Backslash stehende gecutteten Pfad ein..

Einige Funktionen, die ich in der damaligen Version nicht hatte, z.B. zur Stringbearbeitung, habe ich auch in einer eigenen Unit "Strings" zu stehen.

Immerhin: es funktioniert, und ich nutze das Programm, daß diese Codes enthält, auch reichlich.

Zitat:

Weißt du, dass die Komponente TShellListView
Ich werde mir die Komponente downloaden... hoffentlich eine Freeware- Version. 119 Dollar, wenn's auch so geht ?...ansonsten werde ich weiter das ListView malträtieren.

edi

marabu 11. Nov 2007 14:32

Re: Listbox Sortierung
 
Die Komponente TShellListView findest du ab D6 auf der Palettenseite "Beispiele".

Wenn du weiter mit TListView arbeitest, dann darfst du den Beitrag von Frank (#2) nicht übersehen - OnCompare ist da sehr hilfreich.

Freundliche Grüße

edi-mv 11. Nov 2007 19:05

Re: Listbox Sortierung
 
Zitat:

Wenn du weiter mit TListView arbeitest, dann darfst du den Beitrag von Frank (#2) nicht übersehen - OnCompare ist da sehr hilfreich
Hab' ich nicht übersehen. Hab's noch nicht hingekriegt, daß es eben erst Ordner, dann die Dateien sortiert, immer nur alle zusammen... außerdem muß ich mir was einfgalölen lassen, da ich ja passende Daten im Listobjekt vorhalte, die dann ja auch umsortiert werden müssen... oder das Konzept umschmeißen. Ich bleibe dran, aber kann erst nächstes Wochenende weitermachen, arbeite im Ausland.
Zitat:

Die Komponente TShellListView findest du ab D6 auf der Palettenseite "Beispiele".
Leider auf meiner Version D6 Personal nicht drauf... :cry:
Erst mal vielen Dank für die Tips !
Mit freundlichen Grüßen an alle
edi


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