ts-soft hat geschrieben:Crossplattform, keine API, unterstützt auch x64 usw.
Also langsam beginnt mir dein Code zu gefallen.
Einzig anmerken müsste man, das keine Datei-Attribute, -Datum und NTFS-DataStreams mit kopiert werden - was vielleicht auch gar nicht so tragisch ist... (die ersten beiden wären auch einfach noch hinzu zu fügen - Get-,Set-,-FileAttributes,-FileDate). (Macht CopyFileEx intern noch einen CRC Test?...)
Antworten muss ich nun dennoch:
frankmannb hat geschrieben:Hallo Andy vielen Dank für den Beispielcode. Ich denke davon werde ich schon was für mein Programm verwenden können, werde mal schauen. Eine Frage hätte ich allerdings. Was bedeuten die @ vor den Stringvariablen und warum ist einmal hinter der procedure ein "_" (CopyFileEx_) und das nächste mal _CopyFileExCallback() so wie in diesem Beispiel.
Procedure.l _CopyFileEx(pSource.s,pTarget.s)
Erg = CopyFileEx_(@pSource.s, @pTarget.s, @_CopyFileExCallback(), 0, 0, 0)
ProcedureReturn Erg
EndProcedure
kann man irgendwo erlesen was sich hinter den weiteren Parametern von _CopyFileExCallback verbirgt?
Danke und Grüße aus Potsdam
frankmannb
Ach. Ja, das ist etwas verwirrend im Beispiel - weil ich sehr ähnliche Namen verwendet hab...
Ich stelle meinen Prozeduren gerne ein _ voran, weil sie dann schneller in der Codevervollständigung erscheinen und sich zudem offensichtlich von internen PB Funktionen unterscheiden. Bei nachfolgendem _ wie bei CopyFileEx_, bedeutet das für PB, dass es sich um eine API-Funktion handelt:
CopyFileEx Function
Dieser API-Funktion kann man eine Adresse einer eigenen Funktion angeben, die wiederum von von der API-Funktion aufgerufen wird - deshalb heisst das auch Callback: "zurück rufen". Mit dem @ macht man genau das, man gibt die Adresse einer eigenen Prozedur an - in unserem Fall die von _CopyFileExCallback(). Dieser Prozedur werden einige Daten übergeben - das sind genau diese Parameter, nach denen du fragst:
CopyProgressRoutine Callback Function - benutzen muss man diese Parameter nicht - aber die Prozedur muss die Parameter haben.
Ich hab den Code nochmal geändert, mit anderen Prozedurnamen und noch einer kleinen Unterscheidung, ob vom User unterbrochen wurde.
TS-Soft hat recht, dass mein Eventhandling nicht vom Feinsten ist... So ist das Schliessen des Fensters während des Kopierens zBsp nicht möglich... Wobei man sich darüber noch streiten könnte, ob das möglich sein soll... ^^
Was ich noch gut fände, wäre ein separater Dialog fürs Kopieren und/oder das Deaktivieren von anderen Dialogen - so dass es für den User unzweifelhaft klar ist, dass nichts anderes geht, weil jetzt gerade kopiert wird. Ich behaupte jetzt einfach mal, dass dies der separate Dialog für's Kopieren IST...
Code: Alles auswählen
;CopyFileEx1004b.pb
;Beispiel für WinAPI CopyFileEx
;PB 4.4
Procedure.l WinCopyFileCallBack(TotalFileSize.q, TotalBytesTransferred.q, StreamSize.q, StreamBytesTransferred.q, dwStreamNumber.l, dwCallbackReason.l, hSourceFile.i, hDestinationFile.i, lpData.l)
Shared SWinCopyFileBreak.b
If TotalFileSize
Proz=100*TotalBytesTransferred/TotalFileSize
SetGadgetState(2,Proz)
EndIf
ev=1
While ev
ev=WindowEvent() ;hier werden alle Events gefressen - ausser die folgenden...
If ev=#PB_Event_Gadget
If EventGadget()=3 ;Abbrechen-Button
SWinCopyFileBreak=1
ProcedureReturn 1 ;1=PROGRESS_CANCEL -> sagt CopyFileEx_, dass es abbrechen soll
EndIf
ElseIf ev=#PB_Event_CloseWindow
SWinCopyFileBreak=2
ProcedureReturn 1 ;1=PROGRESS_CANCEL
EndIf
Wend
ProcedureReturn 0 ;0=PROGRESS_CONTINUE
EndProcedure
Procedure.l WinCopyFile(pSource.s,pTarget.s)
Shared SWinCopyFileBreak.b
If OpenWindow(0,200,200,400,105,"Datei Kopieren")
TextGadget(0,5,5,390,20,"Kopiere von: "+pSource,#PB_Text_Center)
TextGadget(1,5,25,390,20,"nach: "+pTarget,#PB_Text_Center)
TextGadget(2,160,50,60,20,"")
ProgressBarGadget(2,20,50,360,20,0,100)
ButtonGadget(3,160,80,80,20,"Abbrechen")
SWinCopyFileBreak=0
Erg = CopyFileEx_(@pSource.s, @pTarget.s, @WinCopyFileCallBack(), 0, 0, 0) ;Windows API-Befehl
If Erg=0
Erg=-SWinCopyFileBreak
EndIf
CloseWindow(0)
EndIf
ProcedureReturn Erg
EndProcedure
;hier natürlich bei euch existierende Pfade angeben (mit ner groooossen Datei)
Erg=WinCopyFile("D:\_Downloads\3DMark06_v110_installer.exe","D:\_temp\3DMark06_v110_installer.exe")
If Erg=1 ;hier könnte man selber auf das Fehler-/Abbruch-/Ergebnis reagieren
Debug "Kopieren erfolgreich"
Else
If Erg=-1
Debug "Kopieren abgebrochen"
ElseIf Erg=-2
Debug "Kopieren abgebrochen durch Fenster schliessen"
Else
Debug "Fehler beim Kopieren"
EndIf
EndIf