[RESOLU] Copier fichiers avec boîte de progression st

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
gansta93
Messages : 1448
Inscription : jeu. 26/févr./2004 11:17
Localisation : Le Village
Contact :

[RESOLU] Copier fichiers avec boîte de progression st

Message par gansta93 »

Bonjour,

Je voudrais que lorsque je copie des fichiers, j'aie la boîte de dialogue standard de Windows qui marque la progression de la copie. Comment peut-on faire ça ? sans doute encore de l'API... quelqu'un sait-il comment faire cela ?

Merci d'avance.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Voici un code de El Choni que j'avais mis de côté

A adapter pour le besoin

Code : Tout sélectionner

; Tested on Windows XP Pro SP1

Procedure Ansi2Uni(st$)
  blen = (Len(st$)*2)+2
  wbuf = AllocateMemory(blen)
  MultiByteToWideChar_(#CP_ACP, 0, st$, -1, wbuf, blen)
  ProcedureReturn wbuf
EndProcedure

#CLSCTX_INPROC_SERVER = 1

#PROGDLG_NORMAL = 0
#PROGDLG_AUTOTIME = 2

#PDTIMER_RESET = 1

#IDA_COPY_ANIMATION = 160 ; AVI file resource ID (I use an arbitrary constant name)
                          ; This one is from shell32.dll.
                          ; You can use any AVI file resource as long as it's
                          ; uncompressed or RLE8 compressed, silent and
                          ; smaller or equal to 272 by 60 pixels in size.

CoInitialize_(0)
hr = CoCreateInstance_(?CLSID_ProgressDialog, #Null, #CLSCTX_INPROC_SERVER, ?IID_IProgressDialog, @ppv.IProgressDialog)
If hr=#S_OK
  *Title = Ansi2Uni("System progress dialog box")
  ppv\SetTitle(*Title)
  hShell = OpenLibrary(0, "shell32.dll")
  If hShell
    ppv\SetAnimation(hShell, #IDA_COPY_ANIMATION)
  EndIf
  *Cancel = Ansi2Uni("Cancel")
  ppv\SetCancelMsg(*Cancel, 0)
  *Line1 = Ansi2Uni("System progress dialog test in PureBasic")
  ppv\SetLine(1, *Line1, #True, 0)
  ppv\StartProgressDialog(#Null, 0, #PROGDLG_AUTOTIME|#PROGDLG_NORMAL, 0)
  ppv\Timer(#PDTIMER_RESET, 0)
  Repeat
    If ppv\HasUserCancelled()
      MessageRequester("Messsage", "Progress cancelled")
      Break
    Else
      ppv\SetProgress(dwCompleted, 100)
      If dwCompleted>=100
        MessageRequester("Messsage", "Progress completed")
        Break
      Else
        dwCompleted+1
        *Line2 = Ansi2Uni("We are at progress point number "+Str(dwCompleted))
        ppv\SetLine(2, *Line2, #True, 0)
        FreeMemory(*Line2)
      EndIf
    EndIf
    Delay(100)
  ForEver
  ppv\StopProgressDialog()
  ppv\Release()
  FreeMemory(*Title)
  FreeMemory(*Cancel)
  FreeMemory(*Line1)
  If hShell:CloseLibrary(0):EndIf
Else
  Debug Hex(hr)
EndIf
CoUninitialize_()

DataSection
CLSID_ProgressDialog:
Data.l $F8383852
Data.w $FCD3, $11D1
Data.b $A6, $B9, 0, $60, $97, $DF, $5B, $D4
IID_IProgressDialog:
Data.l $EBBC7C04
Data.w $315E, $11D2
Data.b $B6, $2F, 0, $60, $97, $DF, $5B, $D4
EndDataSection 
gansta93
Messages : 1448
Inscription : jeu. 26/févr./2004 11:17
Localisation : Le Village
Contact :

Message par gansta93 »

Merci, je vais tester ça. :-D
Quelqu'un a testé sous Windows 98 ?
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

nickel avec mon chtit SE

Dri ;)
gansta93
Messages : 1448
Inscription : jeu. 26/févr./2004 11:17
Localisation : Le Village
Contact :

Message par gansta93 »

Dr. Dri a écrit :nickel avec mon chtit SE

Dri ;)
Merci. :-D
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: Copier un/des fichier(s) et avoir la boîte de progressio

Message par NY152 »

Je suis tombé sur ce code qui me conviendrais parfaitement pour une copie (de fichiers multiples ou non) mais pas moyen d'y arriver. Soit ça plante,soit ça se compile pas, soit la progression est erronée (pourtant bien calculée)

Quelqu'un s'y est essayé avec ce code pour une copie ?
.:NY152:.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Copier un/des fichier(s) et avoir la boîte de progressio

Message par Kwai chang caine »

Marche niquel sur VISTA 32 Bits et v4.51 :wink:
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: [RESOLU] Copier fichiers avec boîte de progression st

Message par NY152 »

Le code cité fonctionne oui mais pour y intégrer une routine de copie, ça se complique (pour moi en tout cas).
.:NY152:.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: [RESOLU] Copier fichiers avec boîte de progression st

Message par Mesa »

Il faudrait mélanger le code de dessus avec celui-ci :

Code : Tout sélectionner

#PROGRESS_CONTINUE        = 0
#PROGRESS_CANCEL          = 1
#PROGRESS_STOP            = 2
#PROGRESS_QUIET           = 3
#COPY_FILE_FAIL_IF_EXISTS = 1
#COPY_FILE_RESTARTABLE    = 2
;- Window Constants
Enumeration
  #Window_0
EndEnumeration
;- Gadget Constants
Enumeration
  #Text_0
  #String_0
  #Text_1
  #String_1
  #Text_2
  #ProgressBar_FileProgress
  #Button_Copy
  #Button_1
  #Button_2
  #Button_Cancel
EndEnumeration
Global Copy_FileSource.s ; 
Global Copy_FileDestination.s ; 
Global Copy_cancel
Procedure Open_Window_0()
  If OpenWindow(#Window_0, 344, 256, 334, 200,"copie",#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
      TextGadget(#Text_0, 5, 5, 320, 15,"Le chemin vers le fichier copié:")
      StringGadget(#String_0, 5, 20, 290, 20,"",#PB_String_ReadOnly)
      TextGadget(#Text_1, 5, 55, 320, 15,"Pour copier un fichier:")
      StringGadget(#String_1, 5, 70, 290, 20,"",#PB_String_ReadOnly)
      TextGadget(#Text_2, 5, 140, 200, 15,"copier un fichier:")
      ProgressBarGadget(#ProgressBar_FileProgress, 5, 155, 250, 15, 0, 100,#PB_ProgressBar_Smooth)
      ButtonGadget(#Button_Copy, 80, 100, 190, 25,"copier")
      ButtonGadget(#Button_1, 300, 20, 30, 20,"...")
      ButtonGadget(#Button_2, 300, 70, 30, 20,"...")
      ButtonGadget(#Button_Cancel, 260, 150, 70, 25,"annulation") : DisableGadget(#Button_Cancel,1)
  EndIf
EndProcedure
; Interruption d'une copie si Copy_cancel
; une constante égale au nombre # PROGRESS_CANCEL
Procedure.l CopyProgressCallback(TotalFileSize.q, TotalBytesTransferred.q, StreamSize.q, StreamBytesTransferred.q, dwStreamNumber.l , dwCallbackReason.l, hSourceFile.l, hDestinationFile.l, lpData.l)
  SetGadgetState(#ProgressBar_FileProgress, TotalBytesTransferred)
  ProcedureReturn Copy_cancel
EndProcedure
; Une copie du fichier courant séparé.
; Ne pas oublier de marquer le point "Créer une application avec le flux le plus sûr" dans la compilation
Procedure CopyFile_Thread(*v)
  DisableGadget(#Button_Copy, 1)
  DisableGadget(#Button_Cancel, 0)
  SetGadgetAttribute(#ProgressBar_FileProgress, #PB_ProgressBar_Maximum, FileSize(Copy_FileSource))
  SetGadgetState(#ProgressBar_FileProgress,0)
  If CopyFileEx_( @Copy_FileSource, @Copy_FileDestination, @CopyProgressCallback(), 0, cancel, 0)
    MessageRequester("", "Le fichier est copié", #MB_OK|#MB_ICONINFORMATION)
  Else
    MessageRequester("", " a été interrompu", #MB_OK|#MB_ICONWARNING)
  EndIf
  DisableGadget(#Button_Copy, 0)
  DisableGadget(#Button_Cancel, 1)
EndProcedure
Open_Window_0()
Repeat ; 
  Event = WaitWindowEvent(); 
  If Event =#PB_Event_Gadget
    Select EventGadget(); 
      Case #Button_1; Bouton pour sélectionner un fichier
        File.s=OpenFileRequester("","","tous les fichiers|*.*",0)
        If File<>""
          SetGadgetText(#String_0, File)
        EndIf
      Case #Button_2; Emplacement du bouton pour enregistrer le fichier
        File.s=SaveFileRequester("","","tous les fichiers|*.*",0)
        If File<>""
          SetGadgetText(#String_1, File)
        EndIf
      Case #Button_Copy ; Bouton pour copier un fichier
        Copy_FileSource=GetGadgetText(#String_0)
        Copy_FileDestination.s=GetGadgetText(#String_1)
        If FileSize(Copy_FileSource)>0 And Copy_FileDestination<>""
          Copy_cancel = #PROGRESS_CONTINUE
          CreateThread(@CopyFile_Thread(), 0)
        Else
          MessageRequester("","Remplissez les champs!", 48)
        EndIf
      Case #Button_Cancel ; Le bouton Annuler jusqu'à
        Copy_cancel=#PROGRESS_CANCEL
    EndSelect
  EndIf
Until Event = #PB_Event_CloseWindow
Pas le temps de le faire, désolé.

Mesa.
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: [RESOLU] Copier fichiers avec boîte de progression st

Message par NY152 »

Je creuserais ça dès que j'en aurais le temps,merci :)
.:NY152:.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: [RESOLU] Copier fichiers avec boîte de progression st

Message par Mesa »

J'ai mélangé les 2 codes.

Ça marche mais il y a un petit bug : Il faut que les fichiers à copier soient assez gros, plusieurs 100taines de Mo, pour que la boîte de dialogue apparaisse. Je ne sais pas pourquoi.

Quand on annule la copie, ça n'annule que le fichier en cours. Une petite modif permettrai d'annuler toutes les copies en cours.

Code : Tout sélectionner

Procedure Ansi2Uni(st$)
  blen = (Len(st$)*2)+2
  wbuf = AllocateMemory(blen)
  MultiByteToWideChar_(#CP_ACP, 0, st$, -1, wbuf, blen)
  ProcedureReturn wbuf
EndProcedure

#CLSCTX_INPROC_SERVER = 1

#PROGDLG_NORMAL = 0
#PROGDLG_AUTOTIME = 2

#PDTIMER_RESET = 1

#IDA_COPY_ANIMATION = 160 ; AVI file resource ID (I use an arbitrary constant name)
; This one is from shell32.dll.
; You can use any AVI file resource as long as it's
; uncompressed or RLE8 compressed, silent and
; smaller or equal to 272 by 60 pixels in size.


;==================================================

#PROGRESS_CONTINUE        = 0
#PROGRESS_CANCEL          = 1
#PROGRESS_STOP            = 2
#PROGRESS_QUIET           = 3
#COPY_FILE_FAIL_IF_EXISTS = 1
#COPY_FILE_RESTARTABLE    = 2
;- Window Constants
Enumeration
  #Window_0
EndEnumeration
;- Gadget Constants
Enumeration
  #Text_0
  #String_0
  #Text_1
  #String_1
  #Text_2
  #ProgressBar_FileProgress
  #Button_Copy
  #Button_1
  #Button_2
  #Button_Cancel
  
EndEnumeration

Global ppv.IProgressDialog
Global Copy_FileSource.s ;
Global Copy_FileDestination.s ;
Global Copy_cancel

Procedure Open_Window_0()
  If OpenWindow(#Window_0, 344, 256, 334, 200,"copie",#PB_Window_MinimizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    TextGadget(#Text_0, 5, 5, 320, 15,"Fichiers sources :")
    StringGadget(#String_0, 5, 20, 290, 20,"",#PB_String_ReadOnly)
    TextGadget(#Text_1, 5, 55, 320, 15,"Destination :")
    StringGadget(#String_1, 5, 70, 290, 20,"",#PB_String_ReadOnly)
    TextGadget(#Text_2, 5, 140, 200, 15,"Progression :")
    ProgressBarGadget(#ProgressBar_FileProgress, 5, 155, 290, 15, 0, 100,#PB_ProgressBar_Smooth)
    ButtonGadget(#Button_Copy, 80, 100, 190, 25,"copier")
    ButtonGadget(#Button_1, 300, 20, 30, 20,"...")
    ;ButtonGadget(#Button_2, 300, 70, 30, 20,"...")
    ;ButtonGadget(#Button_Cancel, 260, 150, 70, 25,"annuler") : DisableGadget(#Button_Cancel,1)
  EndIf
EndProcedure
; Interruption d'une copie si Copy_cancel= #PROGRESS_CANCEL
Procedure.l CopyProgressCallback(TotalFileSize.q, TotalBytesTransferred.q, StreamSize.q, StreamBytesTransferred.q, dwStreamNumber.l , dwCallbackReason.l, hSourceFile.l, hDestinationFile.l, lpData.l)
  SetGadgetState(#ProgressBar_FileProgress, TotalBytesTransferred)
  
  If ppv\HasUserCancelled()
    MessageRequester("Message", "Copie annulée")
    Copy_cancel=#PROGRESS_CANCEL
    ProcedureReturn Copy_cancel
  Else
    
    If dwCompleted>=100
      MessageRequester("Message", "Copie Complète")
      ProcedureReturn Copy_cancel
    Else
      
      dwCompleted=TotalBytesTransferred
      ppv\SetProgress(dwCompleted, FileSize(Copy_FileSource));ppv\SetProgress64() pour copier des fichiers de plus de 4 Go
      
      *Line2 = Ansi2Uni("Pourcentage de progression : "+Str(100*dwCompleted/FileSize(Copy_FileSource)))
      ppv\SetLine(2, *Line2, #True, 0)
      FreeMemory(*Line2)
    EndIf
  EndIf
  
  ProcedureReturn Copy_cancel
EndProcedure

; Procedure CopyFile_Thread(*v)
;   DisableGadget(#Button_Copy, 1)
;   DisableGadget(#Button_Cancel, 0)
;   SetGadgetAttribute(#ProgressBar_FileProgress, #PB_ProgressBar_Maximum, FileSize(Copy_FileSource))
;   SetGadgetState(#ProgressBar_FileProgress,0)
;   If CopyFileEx_( @Copy_FileSource, @Copy_FileDestination, @CopyProgressCallback(), 0, cancel, 0)
;     MessageRequester("", "Le fichier est copié", #MB_OK|#MB_ICONINFORMATION)
;   Else
;     MessageRequester("", " a été interrompu", #MB_OK|#MB_ICONWARNING)
;   EndIf
;   DisableGadget(#Button_Copy, 0)
;   DisableGadget(#Button_Cancel, 1)
; EndProcedure

Procedure CopyFilew()
  
  ;CoInitialize_(0)
  ;CoInitializeEx_(0,0)
  CoInitializeEx_(0,2)
  hr = CoCreateInstance_(?CLSID_ProgressDialog, #Null, #CLSCTX_INPROC_SERVER, ?IID_IProgressDialog, @ppv.IProgressDialog)
  If hr=#S_OK
    *Title = Ansi2Uni("Copie de fichiers...")
    ppv\SetTitle(*Title)
    hShell = OpenLibrary(0, "shell32.dll")
    If hShell
      ppv\SetAnimation(hShell, #IDA_COPY_ANIMATION)
    EndIf
    *Cancel = Ansi2Uni("Cancel")
    ppv\SetCancelMsg(*Cancel, 0)
    *Line1 = Ansi2Uni(Copy_FileSource)
    ppv\SetLine(1, *Line1, #True, 0)
    ppv\StartProgressDialog(#Null, 0, #PROGDLG_AUTOTIME|#PROGDLG_NORMAL, 0)
    ; vista et + seulement            #PROGDLG_AUTOTIME|#PROGDLG_NORMAL|#PROGDLG_MARQUEEPROGRESS
    ppv\Timer(#PDTIMER_RESET, 0) 
    ;====================== 
    
    DisableGadget(#Button_Copy, 1)
    ;DisableGadget(#Button_Cancel, 0)
    SetGadgetAttribute(#ProgressBar_FileProgress, #PB_ProgressBar_Maximum, FileSize(Copy_FileSource))
    SetGadgetState(#ProgressBar_FileProgress,0)
    
    CopyFileEx_( @Copy_FileSource, @Copy_FileDestination, @CopyProgressCallback(), 0, cancel, 0)
    
    DisableGadget(#Button_Copy, 0)
    
    ppv\StopProgressDialog()
    ppv\Release()
    FreeMemory(*Title)
    FreeMemory(*Cancel)
    FreeMemory(*Line1)
    If hShell:CloseLibrary(0):EndIf
  Else
    Debug Hex(hr)
  EndIf
  CoUninitialize_()
  
EndProcedure


Open_Window_0()

Repeat ;
  Event = WaitWindowEvent();
  If Event =#PB_Event_Gadget
    Select EventGadget();
      Case #Button_1; Bouton pour sélectionner un fichier
        Fileo.s=OpenFileRequester("","","tous les fichiers|*.*",0,#PB_Requester_MultiSelection )
        If Fileo<>""
          SetGadgetText(#String_0, Fileo)
        EndIf
        
        CheminInitial$ = "C:\"   ; Répertoire par défaut qui sera affiché (une chaîne vide est aussi possible)
        Chemin$ = PathRequester("Choisissez un répertoire", CheminInitial$)
        
      Case #Button_Copy ; Bouton pour copier un fichier
        While Fileo
          Copy_FileSource=Fileo
          Copy_FileDestination.s=chemin$+GetFilePart(Fileo)
          SetGadgetText(#String_0, Copy_FileSource)
          SetGadgetText(#String_1, Copy_FileDestination)
          If FileSize(Copy_FileSource)>0 And Copy_FileDestination<>""
            Copy_cancel = #PROGRESS_CONTINUE
            ;CreateThread(@CopyFile_Thread(), 0)
            CopyFilew()
          Else
            MessageRequester("","Problème ?", 48)
          EndIf
          Fileo=NextSelectedFileName()
        Wend
        
    EndSelect
  EndIf
Until Event = #PB_Event_CloseWindow


DataSection
  CLSID_ProgressDialog:
  Data.l $F8383852
  Data.w $FCD3, $11D1
  Data.b $A6, $B9, 0, $60, $97, $DF, $5B, $D4
  IID_IProgressDialog:
  Data.l $EBBC7C04
  Data.w $315E, $11D2
  Data.b $B6, $2F, 0, $60, $97, $DF, $5B, $D4
EndDataSection
Mesa.
NY152
Messages : 148
Inscription : dim. 14/mai/2006 20:41

Re: [RESOLU] Copier fichiers avec boîte de progression st

Message par NY152 »

Merci,je teste ça dès que je peux ^^
.:NY152:.
Répondre