@AndyMars
Dein Code hat ein Problem, es wird ein Event im Callback gestohlen! Es
können ja ausser Cancel auch andere Ereignisse auftreten!
ListViewGadget leeren und neu befüllen
- 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
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.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- 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
Da hast du recht! Aber ich habe es ehrlich gesagt lieber sequentiell - bei mir müssen User warten, bis eine Datei kopiert ist, oder sie müssen abbrechen. Das ist nicht sehr nett, aber sicherer - bei solchen Backgroundsachen muss der Programmierer verdammt gut aufpassen, dass sein Programm keinen Scheiss macht, wenn der User es darauf anlegt...ts-soft hat geschrieben:@AndyMars
Dein Code hat ein Problem, es wird ein Event im Callback gestohlen! Es
können ja ausser Cancel auch andere Ereignisse auftreten!
-
- Beiträge: 47
- Registriert: 21.02.2010 13:02
Re: ListViewGadget leeren und neu befüllen
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.AndyMars hat geschrieben:Och Thomas... ich war wieder mal langsamer...
Getesteter Code:
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...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
Edit: Hach sind wir wieder produktiv! Gleich zwei Methoden im Angebot. Jetzt kann sich aber niemand mehr beschweren...
Gruss Andy
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
- 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
Naja, meinen Code hab ich zwischendurch mal getestet, ist Fehlerfrei.
Crossplattform, keine API, unterstützt auch x64 usw.
Und um meinen Code zu verstehen genügt die Hilfe, die mit PB mitgeliefert wird,
suchen in MSDN entfällt also.
Hier nochmal eine verfeinerte Version:
wobei die While Wend schleife nur der Demo dient. Tatsächlich soll die Procedure nur bei Timerereignis aufgerufen werden, so kann das Programm normal weiterlaufen.
Crossplattform, keine API, unterstützt auch x64 usw.
Und um meinen Code zu verstehen genügt die Hilfe, die mit PB mitgeliefert wird,
suchen in MSDN entfällt also.
Hier nochmal eine verfeinerte Version:
Code: Alles auswählen
Procedure CopyFileBuffer(source.s, dest.s, buffersize = 4096)
Static FD, FS
Protected *mem, result
If Not FD
FD = CreateFile(#PB_Any, dest)
If FD And buffersize >= 1028
FileBuffersSize(FD, buffersize)
EndIf
EndIf
If Not FS
FS = ReadFile(#PB_Any, source)
If FS And buffersize >= 1028
FileBuffersSize(FS, buffersize)
EndIf
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
While Not CopyFileBuffer("D:\_Downloads\3DMark06_v110_installer.exe", "D:\_temp\3DMark06_v110_installer.exe")
Wend
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.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

-
- Beiträge: 47
- Registriert: 21.02.2010 13:02
Re: ListViewGadget leeren und neu befüllen
@CodeCommander
Auch dir vielen Dank für deine Hilfe mein Problem zu lösen. Ich werde auch versuchen deinen code zu verstehen und ihn in mein Programm einzubauen. Nur ist es erstmal bei mir so das ich eben noch anfänger bin und noch nicht so professional programmieren kann wie Ihr. Ich finde es aber super wie viele von euch hier Ihr bestes geben um anderen zu helfen. Sobald ich eine Version für mein Programm verwendet habe werde ich dies hier kundtun.
grüße aus Potsdam und nochmals vielen Dank
frankmannb
Auch dir vielen Dank für deine Hilfe mein Problem zu lösen. Ich werde auch versuchen deinen code zu verstehen und ihn in mein Programm einzubauen. Nur ist es erstmal bei mir so das ich eben noch anfänger bin und noch nicht so professional programmieren kann wie Ihr. Ich finde es aber super wie viele von euch hier Ihr bestes geben um anderen zu helfen. Sobald ich eine Version für mein Programm verwendet habe werde ich dies hier kundtun.
grüße aus Potsdam und nochmals vielen Dank
frankmannb
- 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 l&b - bzw. Kopieren mit Fortschrittsanze
Also langsam beginnt mir dein Code zu gefallen.ts-soft hat geschrieben:Crossplattform, keine API, unterstützt auch x64 usw.

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:
Ach. Ja, das ist etwas verwirrend im Beispiel - weil ich sehr ähnliche Namen verwendet hab...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
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
-
- Beiträge: 47
- Registriert: 21.02.2010 13:02
Re: ListViewGadget leeren und neu befüllen
Hallo TS-Soft,ts-soft hat geschrieben:wobei die While Wend schleife nur der Demo dient. Tatsächlich soll die Procedure nur bei Timerereignis aufgerufen werden, so kann das Programm normal weiterlaufen.
ich versuche gerade deinen Code bei mir im Programm unterzubringen. Das Klappt sofern man nicht in das Fenster klickt prima. Aber ich bekomme es nicht hin das das Programm "normal" weiterläuft (ohne keine Rückmeldung ) oder das ich das Programm abbrechen kann. Irgendwie stehe ich hier auf dem Schlauch. Könntest du mir hier nochmal helfen und mir ein kleines Beispiel mit einem Abbrechen bzw. fortsetzten Button coden?.
Vielen Dank
frankmannb