Page 1 sur 2

Ouvrir une ExplorerTreeGadget sur un répertoire ?

Publié : lun. 09/juin/2008 14:48
par Stefou
Salut les prog hammer ! :?

Voilà j'aurais besoins d'un ExplorerTreeGadget mais ouvert que sur un répertoire, comme lorsque l'on execute cela :

Code : Tout sélectionner

RunProgram(  "C:\WINNT\explorer.exe"   ,  "/n,/e,/root,c:\Program Files\"   ,  ""   ,#PB_Program_Wait) 
Merci d'avance

Publié : lun. 09/juin/2008 17:24
par Neosis
Un "ExplorerTreegadget" avec seulement un répertoire?

Hum... pourquoi pas analyser le dossier et les fichiers grâce à la bibliothèque "FileSystème" et ensuite créer un Simple "Treegadget" grâce au données récupérer. :)

Structure Directory
Type.s
name.s
EndStructure

Global NewList File.Directory()

OpenWindow(0,50,50,600,400," ExplorerTreeGadget (1 seul répertoire")
CreateGadgetList(WindowID(0))
TreeGadget(0,10,10,300,250)

Procedure Analyse_Directory()

Directory$ = "C:\" ; Choisir le répertoire à examiner

If ExamineDirectory(0,Directory$,"*.*")

While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_File
AddElement(File())
File()\Type = " [Fichier] "
File()\name = DirectoryEntryName(0)
Else
AddElement(File())
File()\Type = " [Sous-répertoire] "
File()\name = DirectoryEntryName(0)
EndIf

;Debug DirectoryEntryName(0) + Type$ + "- Taille en octet : " + Str(DirectoryEntrySize(0))
Wend

FinishDirectory(0)
EndIf

EndProcedure

Procedure AddNewElement()

ForEach File()
AddGadgetItem(0,-1,File()\name+File()\Type)
Next

EndProcedure

Analyse_Directory()
AddNewElement()

Repeat

event = WaitWindowEvent()

Until event = #PB_Event_CloseWindow

End

Publié : lun. 09/juin/2008 19:31
par Ollivier
@Stefou

Dans ExplorerTreeGadget, tu as l'option Repertoire$ que tu peux préciser pour avoir ce que tu souhaite.

Ollivier

Publié : lun. 09/juin/2008 19:48
par Stefou
Merci les gars !

@Neosis : l'idée est bonne Neosis. C'est comme cela que j'ai procédé...mais lorsque tu pousse au fond des choses il y a plein d'évenement à gérer :
- développement des noeuds
- mise à jour des répertoires
- icones
- drag and drop
- ....

J'ai fait cela est c'est encore pleins de bug, alors avant de les corriger, je viens voir si depuis ma dernière demande (y a 2 ans) il n'y aurait pas quelqu'un qui saurait...

@Ollivier : Effectivement le tree s'ouvre sur le répertoire mais les autres répertoires sont encore présent. Et je trouve que cela fait fouilli !
Je voudrais que seul les sous répertoire soit accessible, comme dans l'exemple donnée au début.

Y a t-il une option pour faire cela...je continu ma quete....merci pour votre aide.

Publié : lun. 09/juin/2008 20:09
par Ollivier
Doc native : ExplorerTreeGadget >> Options >> #PB_Explorer_NoFiles

Publié : lun. 09/juin/2008 20:17
par Neosis
Effectivement si ta beaucoup d'information à gérer ce n'est pas l'idéal...
Mais en même temps je croie qu'il ni a pas vraiment le choix :roll:

Publié : lun. 09/juin/2008 21:00
par Stefou
Merci Ollivier mais
soit je n'ai pas compris,
soit ce n'est pas ce que je cherche, regarde bien l'explorateur lancé avec la commande du début, tu n'as pas acces au autres (sur)répertoires.

Publié : mar. 10/juin/2008 12:33
par Ollivier
Effectivement... Dans ce cas, la méthode de Neosis est okay.

Ollivier

Publié : mar. 10/juin/2008 17:29
par Jacobus
Neosis a pris la bonne direction. Voilà de quoi agrémenter l'arbre.
- Analyse récursive, on garde les différents niveaux
- On récupère l'icône du fichier ou dossier pour l'affichage.
- On compte en temps réel pour visualiser l'analyse (tant que le compteur tourne on attend...)
- Analyse avec un thread pour le refresh de l'arbre. (Si un gros répertoire doit être analysé, il conviendra d'ajouter un Delay(1) dans la boucle du thread pour soulager le processeur)

code : (PB 4.20 testé avec Windows Vista 32 bits)

Code : Tout sélectionner

Enumeration
#winex
#TreeExplorer
#Statusbar
EndEnumeration

Procedure.l ExtractSmallIconFile(IconPath.s) ; 16*16
  ; 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 
  SHGetFileInfo_(IconPath, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_SMALLICON) 
  ProcedureReturn InfosFile\hIcon 
EndProcedure 

Structure InfoFichier 
  NomElement.s 
  Type.l 
EndStructure 
Global NewList RechercheFichier.InfoFichier() 
Global DossierRecherche.s

Procedure AnalyseDossier(Num, dossier.s)
 If Right(dossier, 1) <> "\" : dossier + "\" : EndIf  
  Dossier2.s = RemoveString(dossier, DossierRecherche) 
  Dossier3.s = ReplaceString(Left(Dossier2, Len(Dossier2) - 1), "\", "\?1?")  
  If Dossier3 
    Dossier3 = "?1?" + Dossier3 + "\" 
  EndIf
  files.l = 0
  folders.l = 0   
  If ExamineDirectory(Num, dossier, "*.*")  
    While NextDirectoryEntry(Num)
      If DirectoryEntryType(Num) = #PB_DirectoryEntry_File
        name.s = DirectoryEntryName(Num) 
        AddElement(RechercheFichier()) 
        RechercheFichier()\NomElement = Dossier3 + "?2?" + name 
        RechercheFichier()\Type = 1 
      ElseIf DirectoryEntryType(Num) = #PB_DirectoryEntry_Directory
        name.s = DirectoryEntryName(Num) 
        If name <> "." And name <> ".." 
          AddElement(RechercheFichier()) 
          RechercheFichier()\NomElement = Dossier3 + "?1?" + name 
          RechercheFichier()\Type = 2         
          AnalyseDossier(Num + 1, dossier + name)
        EndIf 
      EndIf
    Wend
    FinishDirectory(Num)
  EndIf
EndProcedure 

Procedure ExplorerDossier(ValTh.l)
  
  dossier.s = "C:\"  ;<<< A MODIFIER SELON TEMPS DISPO
  If Right(dossier, 1) <> "\" : dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier   
  ClearGadgetItemList(#TreeExplorer) ;nettoyage du précédent arbre (mise à jour)
  ClearList(RechercheFichier())      ;nettoyage de la liste  
  DossierRecherche = dossier  
  AnalyseDossier(0, dossier) 
  SortStructuredList(RechercheFichier(), 2, 0, #PB_Sort_String)   
  ; On retire les ?1? et ?2?, et également l'adresse du dossier d'origine 
  ForEach RechercheFichier() 
    RechercheFichier()\NomElement = RemoveString(RemoveString(RechercheFichier()\NomElement, "?1?"), "?2?") 
  Next  
  ; On rempli l'arbre avec les noms de fichiers 
  Nb_Dossier = 0 
  n = 0 
  ForEach RechercheFichier()
    Temp = CountString(RechercheFichier()\NomElement, "\") 
    
    If Temp < Nb_Dossier ; Temp va être notre référence de niveau dans l'arbre
      Nb_Dossier - 1        
       icone.l = ExtractSmallIconFile(dossier+RechercheFichier()\NomElement) ; c'est mieux ainsi
       AddGadgetItem(#TreeExplorer, -1, dossier+RechercheFichier()\NomElement,icone,Temp)       
    ElseIf Temp > Nb_Dossier 
      Nb_Dossier + 1       
       icone.l= ExtractSmallIconFile(dossier+RechercheFichier()\NomElement)
       AddGadgetItem(#TreeExplorer, -1, dossier+RechercheFichier()\NomElement,icone,Temp)    
    Else       
       icone.l = ExtractSmallIconFile(dossier+RechercheFichier()\NomElement)
       AddGadgetItem(#TreeExplorer, -1, dossier+RechercheFichier()\NomElement,icone,Temp)   
    EndIf
    n + 1
    StatusBarText(#Statusbar, 0, "Listing total  : "+Str(CountGadgetItems(#TreeExplorer))+" Patientez durant l'analyse...")    
  Next 
   StatusBarText(#Statusbar, 0, "Listing total  : "+Str(CountGadgetItems(#TreeExplorer))+" - Analyse terminée.") 
EndProcedure 

If OpenWindow(#winex,50,50,600,400," ExplorerTreeGadget (1 seul répertoire)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
 CreateGadgetList(WindowID(#winex)) 
 TreeGadget(#TreeExplorer,10,10,580,360)
 
 If CreateStatusBar(#Statusbar, WindowID(#winex))
  AddStatusBarField(600)
  StatusBarText(#Statusbar, 0, "",  #PB_StatusBar_Raised)    
 EndIf

EndIf
 CreateThread(@ExplorerDossier(),0) ; permet le refresh sans figer la fenêtre
Repeat 
event = WaitWindowEvent() 
Until event = #PB_Event_CloseWindow 
End

Publié : jeu. 12/juin/2008 10:57
par Stefou
Merci Jacobus,

Ton code ne marche pas chez moi mais des que j'ai un peu de temps je vais le décortiquer, il doit y avoir des chose intéressante pour completer le mien.

Ne passe pas trop de temps, je voulais juste la solution avec un explorertree, mais cela va me servir quand même.

Merci encore et bonne journée

Publié : jeu. 12/juin/2008 18:15
par Jacobus
Stefou a écrit :Ton code ne marche pas chez moi
...mais encore?? Qu'est-ce qui ne marche pas chez toi?
T'as essayé avec un dossier contenant que quelques sous-répertoires et fichiers?

Publié : ven. 13/juin/2008 6:10
par Stefou
J'ai une fentre qui s'ouvre et un treegadget dedans mais il est vide. Il ne se remplie pas.

Publié : ven. 13/juin/2008 9:04
par Jacobus
Je ne vois pas où ça peut merder ??? sur quelle config tu essayes ce code? j'obtiens le résultat suivant

Image

Code légèrement modifié pour la gestion du thread d'analyse. Il se peut que ce soit lent, et je vais chercher un moyen de l'accélérer. Mais dans l'absolu ce code doit fonctionner. A moins que quelqu'un d'autre ait le même problème et obtienne un plantage. :?:

Code : Tout sélectionner

;Cocher "Executable Thread safe" dans les options de compilation
Enumeration 
  #winex 
  #TreeExplorer 
  #STATUSBAR 
EndEnumeration 

;Procedure.l ExtractSmallIconFile(IconPath.s) ; 16*16 
  ; 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 
  ;SHGetFileInfo_(IconPath, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_SMALLICON) 
  ;ProcedureReturn InfosFile\hIcon 
;EndProcedure 

Structure InfoFichier 
  NomElement.s 
  Type.l 
EndStructure 
Global NewList RechercheFichier.InfoFichier() 
Global DossierRecherche.s 
Global ThreadScan.l
Procedure AnalyseDossier(Num, dossier.s) 
  If Right(dossier, 1) <> "\" : dossier + "\" : EndIf  
  Dossier2.s = RemoveString(dossier, DossierRecherche) 
  Dossier3.s = ReplaceString(Left(Dossier2, Len(Dossier2) - 1), "\", "\?1?")  
  If Dossier3 
    Dossier3 = "?1?" + Dossier3 + "\" 
  EndIf 
  files.l = 0 
  folders.l = 0    
  If ExamineDirectory(Num, dossier, "*.*")  
    While NextDirectoryEntry(Num) 
      If DirectoryEntryType(Num) = #PB_DirectoryEntry_File 
        Name.s = DirectoryEntryName(Num) 
        AddElement(RechercheFichier()) 
        RechercheFichier()\NomElement = Dossier3 + "?2?" + Name 
        RechercheFichier()\Type = 1 
      ElseIf DirectoryEntryType(Num) = #PB_DirectoryEntry_Directory 
        Name.s = DirectoryEntryName(Num) 
        If Name <> "." And Name <> ".." 
          AddElement(RechercheFichier()) 
          RechercheFichier()\NomElement = Dossier3 + "?1?" + Name 
          RechercheFichier()\Type = 2          
          AnalyseDossier(Num + 1, dossier + Name) 
        EndIf 
      EndIf 
    Wend 
    FinishDirectory(Num) 
  EndIf 
EndProcedure 

Procedure ExplorerDossier(ValTh.l) 
  
dossier.s = "C:\"  ;<<< A MODIFIER SELON TEMPS DISPO 
If Right(dossier, 1) <> "\" : dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier    
ClearGadgetItemList(#TreeExplorer) ;nettoyage du précédent arbre (mise à jour) 
ClearList(RechercheFichier())      ;nettoyage de la liste  
DossierRecherche = dossier  
AnalyseDossier(0, dossier) 
SortStructuredList(RechercheFichier(), 2, 0, #PB_Sort_String)    
  ; On retire les ?1? et ?2?, et également l'adresse du dossier d'origine 
ForEach RechercheFichier() 
  RechercheFichier()\NomElement = RemoveString(RemoveString(RechercheFichier()\NomElement, "?1?"), "?2?") 
Next  
  ; On rempli l'arbre avec les noms de fichiers 
Nb_Dossier = 0 
n = 0 
ForEach RechercheFichier() 
  temp = CountString(RechercheFichier()\NomElement, "\") 
  
  If temp < Nb_Dossier ; Temp va être notre référence de niveau dans l'arbre 
    Nb_Dossier - 1        
    ;icone.l = ExtractSmallIconFile(dossier+RechercheFichier()\NomElement) ; c'est mieux ainsi 
    AddGadgetItem(#TreeExplorer, -1, dossier+RechercheFichier()\NomElement,0,temp)        
  ElseIf temp > Nb_Dossier 
    Nb_Dossier + 1        
    ;icone.l= ExtractSmallIconFile(dossier+RechercheFichier()\NomElement) 
    AddGadgetItem(#TreeExplorer, -1, dossier+RechercheFichier()\NomElement,0,temp)    
  Else        
   ; icone.l = ExtractSmallIconFile(dossier+RechercheFichier()\NomElement) 
    AddGadgetItem(#TreeExplorer, -1, dossier+RechercheFichier()\NomElement,0,temp)    
  EndIf 
  n + 1 
  StatusBarText(#STATUSBAR, 0, "Listing total  : "+Str(n)+" Patientez durant l'analyse...")    
Next 
StatusBarText(#STATUSBAR, 0, "Listing total  : "+Str(CountGadgetItems(#TreeExplorer))+" - Analyse terminée.") 
EndProcedure 

If OpenWindow(#winex,50,50,600,400," ExplorerTreeGadget (1 seul répertoire)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  CreateGadgetList(WindowID(#winex)) 
  TreeGadget(#TreeExplorer,10,10,580,360) 
  
  If CreateStatusBar(#STATUSBAR, WindowID(#winex)) 
    AddStatusBarField(600) 
    StatusBarText(#STATUSBAR, 0, "",  #PB_StatusBar_Raised)    
  EndIf 
  
EndIf 
 ThreadScan = CreateThread(@ExplorerDossier(),0) ; permet le refresh sans figer la fenêtre 
Repeat 
  Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow 
 ;pour arrêter le thread avant fermeture
 Resultat = IsThread(ThreadScan)
 If Resultat <>0
  KillThread(ThreadScan)
 EndIf
End

Publié : ven. 13/juin/2008 9:23
par Jacobus
En testant sur xp avec PB 4.10 j'ai vu d'où vient le bean's
La création de la linkedlist peut être longue si le répertoire est conséquent.
Je dois pouvoir modifier ça en évitant la linkedlist.... @+

Publié : ven. 13/juin/2008 9:34
par Stefou
Je suis sous win2000