Page 1 sur 2

Lister le contenu d'un dossier avec tri

Publié : mer. 06/avr./2005 12:56
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

Publié : mer. 06/avr./2005 13:10
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()" ?

Publié : mer. 06/avr./2005 13:12
par Le Soldat Inconnu
celle de PB 3.93 :lol:

Publié : mer. 06/avr./2005 13:15
par dlolo
je suis en 3.92, c'est pour ça ?

Publié : mer. 06/avr./2005 13:28
par Le Soldat Inconnu
oui, c'est une nouvelle fonction de PB, donc 3.93 obligatoire :wink:

Publié : mer. 06/avr./2005 13:30
par dlolo
Ah OK merci !

Publié : mer. 06/avr./2005 13:43
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) 

Publié : mer. 06/avr./2005 13:49
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())

Publié : mer. 06/avr./2005 20:45
par Le Soldat Inconnu
ok vu, j'ai corrigé la source :D

Publié : jeu. 07/avr./2005 10:48
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

Publié : mar. 12/avr./2005 19:52
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

Publié : mar. 12/avr./2005 20:14
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

Publié : mar. 12/avr./2005 21:00
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

Publié : mar. 12/avr./2005 21:51
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

Publié : mer. 13/avr./2005 10:38
par bernard13
Régis quand je lance ton code j'ai une fenetre mais rien se passe