ListViewGadget leeren und neu befüllen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: ListViewGadget leeren und neu befüllen

Beitrag 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 :wink:

Gruß
Thomas
Zuletzt geändert von ts-soft am 14.04.2010 14:40, insgesamt 2-mal geändert.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
frankmannb
Beiträge: 47
Registriert: 21.02.2010 13:02

Re: ListViewGadget leeren und neu befüllen

Beitrag 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. :allright:

Danke für die Info, aber wie springe ich wieder in dei Eventschleife ohne mit dem kopieren von vorne zu beginnen?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: ListViewGadget leeren und neu befüllen

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
AndyMars
Beiträge: 141
Registriert: 08.09.2004 11:59
Computerausstattung: Win11 Prof 64bit, i5-13500 @ 4.8 GHz, 32GB RAM, Nvidia RTX 4070 TI
Wohnort: Zürich, Schweiz
Kontaktdaten:

Re: ListViewGadget leeren und neu befüllen

Beitrag 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...)
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: ListViewGadget leeren und neu befüllen

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
AndyMars
Beiträge: 141
Registriert: 08.09.2004 11:59
Computerausstattung: Win11 Prof 64bit, i5-13500 @ 4.8 GHz, 32GB RAM, Nvidia RTX 4070 TI
Wohnort: Zürich, Schweiz
Kontaktdaten:

Re: ListViewGadget leeren und neu befüllen

Beitrag 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... ;)
Zuletzt geändert von AndyMars am 14.04.2010 15:27, insgesamt 1-mal geändert.
frankmannb
Beiträge: 47
Registriert: 21.02.2010 13:02

Re: ListViewGadget leeren und neu befüllen

Beitrag 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.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: ListViewGadget leeren und neu befüllen

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: ListViewGadget leeren und neu befüllen

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
AndyMars
Beiträge: 141
Registriert: 08.09.2004 11:59
Computerausstattung: Win11 Prof 64bit, i5-13500 @ 4.8 GHz, 32GB RAM, Nvidia RTX 4070 TI
Wohnort: Zürich, Schweiz
Kontaktdaten:

Re: ListViewGadget leeren und neu befüllen

Beitrag von AndyMars »

Och Thomas... ich war wieder mal langsamer... /:->

Getesteter Code :D :

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
Zuletzt geändert von AndyMars am 14.04.2010 15:59, insgesamt 2-mal geändert.
Antworten