Lister le contenu d'un dossier avec tri

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Lister le contenu d'un dossier avec tri

Message par Le Soldat Inconnu »

Salut

un petit code qui permet de lister le contenu d'un dossier en triant les dossiers et fichiers comme dans l'explorateur :
les dossiers d'abord puis les fichiers

ça donne ce genre de tri :

Code : Tout sélectionner

Truc
  Truc\Bidule
    Truc\Bidule\1.txt
    Truc\Bidule\2.txt
  Truc\24.txt
Machin
  Machin\45.txt
744.txt
415.txt

Code : Tout sélectionner

NewList RechercheFichier.s()

Procedure RechercheFichiers(Num.l, Dossier.s)
  
  If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf
  
  If ExamineDirectory(Num, Dossier, "*.*")
    Repeat
      FileType = NextDirectoryEntry()
      
      If FileType = 1
        ; On a un fichier
        Name.s = DirectoryEntryName()
        AddElement(RechercheFichier())
        RechercheFichier() = ReplaceString(Left(Dossier, Len(Dossier) - 1), "\", "\?1?") + "\?2?" + Name
        ; on met ?1? devant le nom des dossier et ?2? devant le nom des fichiers
        ; Ainsi lors du tri des données, les dossiers seront placés avant les fichiers
        ; Il suffira ensuite de supprimer les ?1? et ?2? des noms de fichiers ou dossiers
        ; Le caratère ? n'étant pas utilisable dans les noms de fichiers, cet ajout ne présente aucun problème
        Debug RechercheFichier()
      ElseIf FileType = 2
        ; On a un dossier
        Name.s = DirectoryEntryName()
        If Name <> "." And Name <> ".."
          AddElement(RechercheFichier())
          RechercheFichier() = ReplaceString(Dossier, "\", "\?1?") + Name
          Debug RechercheFichier()
          RechercheFichiers(Num + 1, Dossier + Name)
          UseDirectory(Num)
        EndIf
      EndIf
      
    Until FileType = 0
  EndIf

  If Num = 0
    ; si on a finit la recherche
    Debug ""
    Debug "________________"
    Debug ""
    ; On tri les noms de fichiers et dossiers
    SortStructuredList(RechercheFichier(), 2, 0, #PB_Sort_String)
    ; On retire les ?1? et ?2?, et également l'adresse du dossier d'origine
    ForEach RechercheFichier()
      RechercheFichier() = RemoveString(RemoveString(RemoveString(RechercheFichier(), "?1?"), "?2?"), Dossier)
      Debug RechercheFichier()
    Next
  EndIf
  
EndProcedure


; On donne le nom du dossier dont on souhaite lister le contenu
Dossier.s = "C:\Program Files\PureBasic\Catalogs"
If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier

; On lance la recherche
RechercheFichiers(0, Dossier)


; Ouvre une fenêtre
If OpenWindow(0, 0, 0, 500, 200, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered, "Recherche fichiers") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

ListIconGadget(0, 0, 0, 500, 200, "Fichiers et dossiers", 470)

; On rempli la liste de fichier
HideGadget(0, 1)
n = 0
ForEach RechercheFichier()
  AddGadgetItem(0, -1, Space(CountString(RechercheFichier(), "\") * 3) + RechercheFichier())
Next
HideGadget(0, 0)

Repeat
  Event = WaitWindowEvent()
  
Until Event = #PB_Event_CloseWindow
Dernière modification par Le Soldat Inconnu le mer. 06/avr./2005 20:43, modifié 1 fois.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
dlolo
Messages : 118
Inscription : ven. 18/févr./2005 16:29

Message par dlolo »

Salut

Tiens bah ça tombe bien je voulais justement faire un petit prog pour imprimer ou créer un ficher txt avec le contenu d'un répertoire ou d'un CD par exemple. :D

Par contre, il faut quelle librairie pour utiliser "SortStructuredList()" ?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

celle de PB 3.93 :lol:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
dlolo
Messages : 118
Inscription : ven. 18/févr./2005 16:29

Message par dlolo »

je suis en 3.92, c'est pour ça ?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

oui, c'est une nouvelle fonction de PB, donc 3.93 obligatoire :wink:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
dlolo
Messages : 118
Inscription : ven. 18/févr./2005 16:29

Message par dlolo »

Ah OK merci !
dlolo
Messages : 118
Inscription : ven. 18/févr./2005 16:29

Message par dlolo »

J'ai testé avec la 3.93 et j'obtiens l'erreur "Can't mix strings with numericals values" sur la ligne :

Code : Tout sélectionner

    AddGadgetItem(0, -1, Space(CountString(RechercheFichier(), "\") * 3) + RechercheFichier) 
dlolo
Messages : 118
Inscription : ven. 18/févr./2005 16:29

Message par dlolo »

Ok C'est bon, je crois qu'il manque les deux parenthèses à la liste 'Recherchefichier', à la fin de la ligne.

Ce qui donne :

Code : Tout sélectionner

AddGadgetItem(0, -1, Space(CountString(RechercheFichier(), "\") * 3) + RechercheFichier())
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

ok vu, j'ai corrigé la source :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Une petite prière pour le LSI su soir :mrgreen:
Saint Régis, bossez pour nous, que votre code source arrive, sur le forum comme dans mes logiciels...

Merci pour cet inventaire de dossier sous forme d'arborescence, pratique. :D
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

la même chose mais dans un TreeGadget

Code : Tout sélectionner

; Cette liste va recevoir le contenu du dossier dans lequel on a lancé la recherche
NewList RechercheFichier.s()

Procedure RechercheFichiers(Num.l, Dossier.s)
  
  If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier
  
  If ExamineDirectory(Num, Dossier, "*.*")
    Repeat
      FileType = NextDirectoryEntry()
      
      If FileType = 1
        ; On a un fichier
        Name.s = DirectoryEntryName()
        AddElement(RechercheFichier())
        RechercheFichier() = ReplaceString(Left(Dossier, Len(Dossier) - 1), "\", "\?1?") + "\?2?" + Name
        ; on met ?1? devant le nom des dossier et ?2? devant le nom des fichiers
        ; Ainsi lors du tri des données, les dossiers seront placés avant les fichiers
        ; Il suffira ensuite de supprimer les ?1? et ?2? des noms de fichiers ou dossiers
        ; Le caratère ? n'étant pas utilisable dans les noms de fichiers, cet ajout ne présente aucun problème
      ElseIf FileType = 2
        ; On a un dossier
        Name.s = DirectoryEntryName()
        If Name <> "." And Name <> ".."
          AddElement(RechercheFichier())
          RechercheFichier() = ReplaceString(Dossier, "\", "\?1?") + Name
          
          ; On lance l'analyse sur ce nouveau dossier (analyse récursive)
          RechercheFichiers(Num + 1, Dossier + Name)
          
          ; On réactive le dossier de recherche en cours
          UseDirectory(Num)
          
        EndIf
      EndIf
      
    Until FileType = 0
  EndIf

  If Num = 0
    ; si on a finit la recherche
    
    ; On tri les noms de fichiers et dossiers
    ; Je passe ici par un SortStructuredList car SortList à une erreur dans PB 3.93 avec le tri de listes chainés contenant du texte, ceci doit-être résolu pour les future version.
    SortStructuredList(RechercheFichier(), 2, 0, #PB_Sort_String)
    
    ; On retire les ?1? et ?2?, et également l'adresse du dossier d'origine
    ForEach RechercheFichier()
      RechercheFichier() = RemoveString(RemoveString(RemoveString(RechercheFichier(), "?1?"), "?2?"), Dossier)
    Next
  EndIf
  
EndProcedure


; On donne le nom du dossier dont on souhaite lister le contenu
Dossier.s = "C:\Program Files\PureBasic\catalogs\"
If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier

; On lance la recherche
; Le premier paramêtre doit toujours être égal à 0
RechercheFichiers(0, Dossier)


; Ouvre une fenêtre
If OpenWindow(0, 0, 0, 500, 200, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered, "Recherche fichiers") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

; ListIconGadget(0, 0, 0, 500, 200, "Fichiers et dossiers", 470, #PB_ListIcon_FullRowSelect)

TreeGadget(0, 0, 0, 500, 200)

; On rempli la liste de fichier
HideGadget(0, 1) ; Le fait de cacher le gadget permet de le remplir plus rapidement
Nb_Dossier = 0
n = 0
ForEach RechercheFichier()
  Temp = CountString(RechercheFichier(), "\")
  If Temp < Nb_Dossier
    Nb_Dossier - 1
    CloseTreeGadgetNode(0)
    AddGadgetItem(0, n, RechercheFichier())
  ElseIf Temp > Nb_Dossier
    Nb_Dossier + 1
    OpenTreeGadgetNode(0)
    AddGadgetItem(0, n, RechercheFichier())
    SetGadgetItemState(0, n - 1, #PB_Tree_Expanded)
  Else
    AddGadgetItem(0, n, RechercheFichier())
  EndIf
  
  n + 1
  
Next

SetGadgetState(0, 0)

HideGadget(0, 0)

Repeat
  Event = WaitWindowEvent()
  
Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

8) Ouaouh! toujours aussi excellent.
Presque mieux qu'un ExploreListGadget.
Reste plus qu'à ajouter l'ouverture des fichiers depuis cette fenêtre et on obtient un explorateur particulier au répertoire choisi.
Utilisable par exemple dans un programme spécifique pour lequel on ne veut afficher qu'un seul répertoire et ses sous répertoires.
Je pense que je vais m'en servir.
Merci très beaucoup de le code. :D
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
julien
Messages : 846
Inscription : ven. 30/janv./2004 15:06
Contact :

Message par julien »

Jacobus a écrit :Une petite prière pour le LSI su soir :mrgreen:
Saint Régis, bossez pour nous, que votre code source arrive, sur le forum comme dans mes logiciels...

Merci pour cet inventaire de dossier sous forme d'arborescence, pratique. :D

MDR :D
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Avec les icônes de fichiers. Par contre, c'est nettement plus lent, je suis sur un système permettant d'accélérer ceci

Code : Tout sélectionner

; Cette liste va recevoir le contenu du dossier dans lequel on a lancé la recherche
NewList RechercheFichier.s()

Procedure RechercheFichiers(Num.l, Dossier.s)
  
  If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier
  
  If ExamineDirectory(Num, Dossier, "*.*")
    Repeat
      FileType = NextDirectoryEntry()
      
      If FileType = 1
        ; On a un fichier
        Name.s = DirectoryEntryName()
        AddElement(RechercheFichier())
        RechercheFichier() = ReplaceString(Left(Dossier, Len(Dossier) - 1), "\", "\?1?") + "\?2?" + Name
        ; on met ?1? devant le nom des dossier et ?2? devant le nom des fichiers
        ; Ainsi lors du tri des données, les dossiers seront placés avant les fichiers
        ; Il suffira ensuite de supprimer les ?1? et ?2? des noms de fichiers ou dossiers
        ; Le caratère ? n'étant pas utilisable dans les noms de fichiers, cet ajout ne présente aucun problème
      ElseIf FileType = 2
        ; On a un dossier
        Name.s = DirectoryEntryName()
        If Name <> "." And Name <> ".."
          AddElement(RechercheFichier())
          RechercheFichier() = ReplaceString(Dossier, "\", "\?1?") + Name
          
          ; On lance l'analyse sur ce nouveau dossier (analyse récursive)
          RechercheFichiers(Num + 1, Dossier + Name)
          
          ; On réactive le dossier de recherche en cours
          UseDirectory(Num)
          
        EndIf
      EndIf
      
    Until FileType = 0
  EndIf

  If Num = 0
    ; si on a finit la recherche
    
    ; On tri les noms de fichiers et dossiers
    ; Je passe ici par un SortStructuredList car SortList à une erreur dans PB 3.93 avec le tri de listes chainés contenant du texte, ceci doit-être résolu pour les future version.
    SortStructuredList(RechercheFichier(), 2, 0, #PB_Sort_String)
    
    ; On retire les ?1? et ?2?, et également l'adresse du dossier d'origine
    ForEach RechercheFichier()
      RechercheFichier() = RemoveString(RemoveString(RemoveString(RechercheFichier(), "?1?"), "?2?"), Dossier)
    Next
  EndIf
  
EndProcedure

ProcedureDLL.l ExtractSmallIconFile(IconPath.s) ; Extraire l'icône 16*16 d'un fichier
  ; Cette procedure permet d'extraire l'ID de l'icône 16*16 associé au type de fichier ou au dossier dont l'adresse est IconPath
  Extension.s = LCase(GetExtensionPart(IconPath))
  If Extension = "ico" Or Extension = "exe"
    ExtractIconEx_(IconPath, IconIndex, 0, @SmallIcon, 1)
    ProcedureReturn SmallIcon
  Else
    SHGetFileInfo_(IconPath, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_SMALLICON)
    ProcedureReturn InfosFile\hIcon
  EndIf
EndProcedure


; On donne le nom du dossier dont on souhaite lister le contenu
Dossier.s = "C:\Program Files\PureBasic\catalogs\"
If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier

; On lance la recherche
; Le premier paramêtre doit toujours être égal à 0
RechercheFichiers(0, Dossier)


; Ouvre une fenêtre
If OpenWindow(0, 0, 0, 500, 200, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered, "Recherche fichiers") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

; ListIconGadget(0, 0, 0, 500, 200, "Fichiers et dossiers", 470, #PB_ListIcon_FullRowSelect)

TreeGadget(0, 0, 0, 500, 200, #PB_Tree_CheckBoxes)

; On rempli la liste de fichier
HideGadget(0, 1) ; Le fait de cacher le gadget permet de le remplir plus rapidement
Nb_Dossier = 0
n = 0
ForEach RechercheFichier()
  Temp = CountString(RechercheFichier(), "\")
  If Temp < Nb_Dossier
    Nb_Dossier - 1
    CloseTreeGadgetNode(0)
    AddGadgetItem(0, n, GetFilePart(RechercheFichier()), ExtractSmallIconFile(Dossier + RechercheFichier()))
    SetGadgetItemState(0, n, #PB_Tree_Checked)
  ElseIf Temp > Nb_Dossier
    Nb_Dossier + 1
    OpenTreeGadgetNode(0)
    AddGadgetItem(0, n, GetFilePart(RechercheFichier()), ExtractSmallIconFile(Dossier + RechercheFichier()))
    SetGadgetItemState(0, n - 1, #PB_Tree_Expanded | #PB_Tree_Checked)
    SetGadgetItemState(0, n, #PB_Tree_Checked)
  Else
    AddGadgetItem(0, n, GetFilePart(RechercheFichier()), ExtractSmallIconFile(Dossier + RechercheFichier()))
    SetGadgetItemState(0, n, #PB_Tree_Checked)
  EndIf
  
  n + 1
  
Next

SetGadgetState(0, 0)

HideGadget(0, 0)

Repeat
  Event = WaitWindowEvent()
  
Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
bernard13
Messages : 1221
Inscription : mer. 05/janv./2005 21:30

Message par bernard13 »

Régis quand je lance ton code j'ai une fenetre mais rien se passe
Répondre