Seite 2 von 3
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 14:32
von ts-soft
Im timerereignis rufste folgende Procedure auf:
Code: Alles auswählen
Global NewList tocopy.s()
Procedure Kopieren(ziel.s)
Protected count
DisableGadget(#ButtonForCopy, #True)
ForEach tocopy()
CopyFile(tocopy(), ziel)
DeleteElement(tocopy())
count + 1
If count = 5
ProcedureReturn
EndIf
Next
DisableGadget(#ButtonForCopy, #False)
EndProcedure
Wenn im Eventloop abbrechen geklickt wird, löschte den Timer, wenn Kopieren gedrückt wird,
erstellste den Timer.
Das Coden mußte schon selber machen
Gruß
Thomas
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 14:36
von frankmannb
NicTheQuick hat geschrieben:Wichtig ist im Grunde, dass du während dem Kopieren keine Events verschluckst. Das heißt du musst auch während deiner Kopierschleife weiterhin 'WaitWindowEvent()' oder Konsorten aufrufen, damit ankommende Events abgearbeitet werden können. Tust du das nicht, sagt Windows "(Keine Rückmeldung)". Du kannst es deshalb so machen wir Kaeru es vorgeschlagen hat, also immer Stückweise kopieren und zwischendurch nochmal in die Eventschleife wechseln oder du machst es so, wie ich es machen würde, nämlich den kompletten Kopiervorgang in einem Thread abhandeln. Aber bevor du dich mit Threads rumschlägst, probiere erstmal die andere Methode.

Danke für die Info, aber wie springe ich wieder in dei Eventschleife ohne mit dem kopieren von vorne zu beginnen?
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 14:38
von ts-soft
frankmannb hat geschrieben:
Danke für die Info, aber wie springe ich wieder in dei Eventschleife ohne mit dem kopieren von vorne zu beginnen?
Siehe obigen Code, dort werden erledigte Elemente gelöscht, setzt voraus das die Linkliste am ende
nicht mehr benötigt wird, ansonsten eine extra dafür erstellen.
hab obigen code nochmal korrigiert.
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 14:55
von AndyMars
Kurzer Einwurf: Wie gross sind denn die Dateien, die du da kopieren willst? Sollten sie sehr gross sein, kommt hinzu, dass dein Programm blockiert ist, während CopyFile eine solche Datei kopiert... (ausser du würdest Threads verwenden - was ich nicht würde - oder API
CopyFileEx mit Callback...)
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 14:58
von ts-soft
Je nach größe kann er ja in meiner Procedure reagieren. Count runter oder raufsetzen, Timer intervall
hoch oder runter. Das muß er sich schon so anpassen, das es paßt.
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 15:11
von AndyMars
Ich würde gerne sehen, wie deine Procedure reagiert, wenn CopyFile eine 500MB Datei kopiert...
*TS-Soft freundlich knufft*
(das Bild war übrigens sehr witzig ^^ hab mich gefragt was auf der anderen Seite wohl gewesen ist - könnte ja auch die Schweiz gewesen sein)
Das einzige saubere fände ich CopxFileEx mit Callback - ein Beispiel, nicht grad ausführbar, aber das Prinzip müsste ersichtlich sein:
Code: Alles auswählen
Procedure.l _CopyFileExCallback(TotalFileSize, totalbytetransfertalk, StreamSize, StreamBytesTransferred, dwStreamNumber.l, dwCallbackReason.l, hSourceFile.l, hDestinationFile.l, lpData.l, dummy1.l, dummy2.l, dummy3.l, dummy4.l)
Shared KopierenAbbruch.l
TotalFileSize_ = (TotalFileSize>>16) &$FFFFFFFF
StreamSize_ = 100 * (StreamSize>>16) &$FFFFFFFF
If TotalFileSize_ > 0 And StreamSize_ > 0
percent = 100 * (StreamSize>>16) &$FFFFFFFF/(TotalFileSize>>16) &$FFFFFFFF
Else
percent = 100
EndIf
SetGadgetState(#Gadget_Main_ProgressBar, percent)
ev=1
While ev
ev=WindowEvent()
If ev=#PB_Event_Gadget
If EventGadget()=#Gadget_Main_ButtonAbbruch
KopierenAbbruch=1
ProcedureReturn 1 ;1=PROGRESS_CANCEL
EndIf
EndIf
Wend
ProcedureReturn 0 ;0=PROGRESS_CONTINUE
EndProcedure
Procedure.l _CopyFileEx(pSource.s,pTarget.s)
ProcedureReturn CopyFileEx_(@pSource.s, @pTarget.s, @_CopyFileExCallback(), 0, 0, 0)
EndProcedure
Edit: mom,mom, bin am recoden - hab mir ja wieder was eingebrockt...

Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 15:14
von frankmannb
@AndyMars
Es sollen überwiegende mkv,mpg Dateien kopiert werden also 4,7GB. Sprich ich würde wenn ich den counter verwende es auf 1 belassen. Hast du eventuell ein Beispiel für eine Threadlösung.
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 15:21
von ts-soft
Bei so grossen Dateien taugt mein Beispiel natürlich nicht. Da mußte die Datei in kleinen
Teilen kopieren. Ist ein bißchen komplizierter, entsprechendes Beispiel hab ich hier
irgendwann mal gepostet, finde es aber nicht wieder.
Also statt jedesmal 5 Dateien, eben 50 MB. CopyFile ist da natürlich nicht mehr zu
verwenden, sondern einlesen in Speicher und schreiben ist da angesagt.
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 15:46
von ts-soft
Hier ein kleines, ungetestetes Beispiel, wie Du die Datei in stücken kopierst.
Im Timerereignis solange aufrufen, bis die Procedure #True zurückgibt, dann
die nächste Datei. Den rest mußte jetzt aber selber schaffen.
Code: Alles auswählen
Procedure CopyMyFile(source.s, dest.s, buffersize)
Static FD, FS
Protected *mem, result
If Not FD
FD = CreateFile(#PB_Any, dest)
EndIf
If Not FS
FS = ReadFile(#PB_Any, source)
EndIf
*mem = AllocateMemory(buffersize)
If *mem And FS And FD
If Loc(FS) + buffersize < Lof(FS)
ReadData(FS, *mem, buffersize)
WriteData(FD, *mem, buffersize)
Else
buffersize = Lof(FS) - Loc(FD)
If buffersize
ReadData(FS, *mem, buffersize)
WriteData(FD, *mem, buffersize)
EndIf
CloseFile(FS)
CloseFile(FD)
FD = 0
FS = 0
result = #True
EndIf
FreeMemory(*mem)
EndIf
ProcedureReturn result
EndProcedure
Gruß
Thomas
Re: ListViewGadget leeren und neu befüllen
Verfasst: 14.04.2010 15:53
von AndyMars
Och Thomas... ich war wieder mal langsamer...
Getesteter Code

:
Code: Alles auswählen
;CopyFileEx1004.pb
;Beispiel für WinAPI CopyFileEx
;PB 4,4
Procedure.l _CopyFileExCallback(TotalFileSize.q, TotalBytesTransferred.q, StreamSize.q, StreamBytesTransferred.q, dwStreamNumber.l, dwCallbackReason.l, hSourceFile.l, hDestinationFile.l, lpData.l)
TotalMB=TotalFileSize/1048576
MBTrans=TotalBytesTransferred/1048576
SetGadgetText(0,Str(MBTrans)+"/"+Str(TotalMB)+" MB")
ev=1
While ev
ev=WindowEvent()
If ev=#PB_Event_Gadget
If EventGadget()=1 ;STOP-Button
ProcedureReturn 1 ;1=PROGRESS_CANCEL
EndIf
EndIf
Wend
ProcedureReturn 0 ;0=PROGRESS_CONTINUE
EndProcedure
Procedure.l _CopyFileEx(pSource.s,pTarget.s)
Erg = CopyFileEx_(@pSource.s, @pTarget.s, @_CopyFileExCallback(), 0, 0, 0)
ProcedureReturn Erg
EndProcedure
If OpenWindow(0,200,200,80,50,"CopyFileEx Test")
TextGadget(0,5,5,60,20,"")
ButtonGadget(1,5,25,60,20,"STOP")
;hier natürlich bei euch existierende Pfade angeben (mit ner groooossen Datei)
If _CopyFileEx("D:\_Downloads\3DMark06_v110_installer.exe","D:\_temp\3DMark06_v110_installer.exe")
Debug "Kopieren erfolgreich"
Else
Debug "Fehler beim Kopieren"
EndIf
Repeat
ev=WaitWindowEvent()
Until ev=#PB_Event_CloseWindow
CloseWindow(0)
EndIf
Edit2: Evtl. müsste man einen Abbruch noch besser behandeln, damit nicht einfach ein Fehler auftritt - aber ihr dürft ruhig auch noch ein wenig hirnen...
Edit: Hach sind wir wieder produktiv! Gleich zwei Methoden im Angebot. Jetzt kann sich aber niemand mehr beschweren...
Gruss Andy