()
Newbie
Messaggi:
Iscritto:
|
Ciao a tutti volevo chiedere come far corrispondere l'avanzamento di una progressbar al processo di download via ftp di un file.
Io avevo pensato di fare una cosa del genere:
Impostare il valore massimo della ProgressBar come la grandezza del file da scaricare. Con un TTimer posto ogni millisecondo o 10 millisecondi vedere qual'è la dimensione del file scaricato e impostarlo come la sua ProgressBar.Position.
Cosicchè ho provato ma mi sono accorto di una cosa:
quando arriva al codice ftp.Get(...) in realtà blocca tutti i processi e solo dopo fa partire il TTimer..
Come posso far eseguire il TTImer e la ProgressBar di conseguenza, DURANTE il processo di download?
Grazie
|
|
systemgvp (Normal User)
Expert
Messaggi: 296
Iscritto: 14/04/2008
|
per motrare l'avanzamento con una barra quando si copia un file si usa:
var
FromF,
ToF : file of byte;
Buffer : array[0..4096] of char;
NumRead : integer;
FileLength : longint;
begin
AssignFile(FromF,Source);
reset(FromF);
AssignFile(ToF,Destination);
rewrite(ToF);
FileLength:=FileSize(FromF);
With Progressbar1 do
begin
Min := 0;
Max := FileLength;
while FileLength > 0 do
begin
BlockRead(FromF,Buffer[0],SizeOf(Buffer),NumRead);
FileLength := FileLength - NumRead;
BlockWrite(ToF,Buffer[0],NumRead);
Position := Position + NumRead;
end;
CloseFile(FromF);
CloseFile(ToF);
end;
potresti modificarlo e ottenere ciò che desideri
|
|
alessandrob (Normal User)
Newbie
Messaggi: 17
Iscritto: 19/01/2010
|
Se devi vedere il progress del download Ftp ed utilizzi i componenti di delphi puoi utilizzare gli eventi corrispondenti:
Per il "vecchio" TNMFTP esiste l'evento
OnPacketRecvd: TNotifyEvent;
che ti informa dell'arrivo di dati e le proprietà
BytesRecvd
BytesTotal
per sapere a che punto sei arrivato.
Se utilizzi i componenti Indy, puoi utilizzare gli eventi WorkBegin, Work e WorkEnd, dove trovi indicazioni sul numero di byte totali e ricevuti.
Alessandro
|
|
()
Newbie
Messaggi:
Iscritto:
|
Ciao alessandro. Io uso il componente IndyClient.
Molto interessante questa idea della proprità Work.
Mi potresti spiegare COME potrei usarla... cioè il mio problema era infatti quello di poter DETTAGLIARE il processo di Download DURANTE il download...
e non riesco a capire come mettere insieme i due processi.
Grazie mille anticipatamente
|
|
alessandrob (Normal User)
Newbie
Messaggi: 17
Iscritto: 19/01/2010
|
Un estratto dal codice che utilizzo io direttamente, con alcune piccole spiegazioni: ho creato una estensione del controllo IdFtp, per cui quello che segue è solo una piccola parte del codice completo, che tra le altre cose funziona da dentro una DLL.
Ovviamente puoi anche usare il controllo direttamente in un form, posizionarci il controllo TIdFtp e gestire direttamente gli eventi.
In particolare, nel mio caso, il form FFc è un form dedicato alla visualizzazione dello stato di avanzamento del download e deve essere creato prima di iniziare il processo di download vero e proprio: su questo form è posizionata la progressbar (pbSess).
Eseguo inoltre una verifica di superamento del massimo durante l'avanzamento vero e proprio.
Di seguito il codice, spero che ti possa essere utile.
type
TMyIdFtp = class( TIdFtp )
private
FFc: TFrmDump;
...
end;
procedure TMyIdFtp.DoMyIdFtpWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer);
begin
{ --- Inizio --- }
if FFc <> Nil
then begin
FFc.pbSess.Position := 0;
FFc.pbSess.Max := AWorkCountMax;
FFc.pbSess.Visible := True;
FFc.pbSess.Update;
end;
end;
procedure TMyIdFtp.DoMyIdFtpWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer);
begin
{ --- Verifica di Sicurezza --- }
if FFC <> Nil
then begin
if AWorkCount > FFc.pbSess.Max
then FFc.pbSess.Max := 2 * FFc.pbSess.Max;
{ --- Avanzamento --- }
FFc.pbSess.Position := AWorkCount;
FFc.pbSess.Update;
end;
end;
procedure TMyIdFtp.DoMyIdFtpWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
begin
{ --- Completato --- }
if FFc <> Nil
then begin
FFc.pbSess.Position := FFc.pbSess.Max;
FFc.pbSess.Visible := False;
FFc.pbSess.Update;
end;
end;
|
|
()
Newbie
Messaggi:
Iscritto:
|
Ciao ho posto il tuo codice all'interno della stessa form ma non funziona...
ti posto il mio codice:
Codice sorgente - presumibilmente Delphi |
procedure TMainForm.Button2Click(Sender: TObject); begin ind:= ListBox1.ItemIndex; names:= ftp.DirectoryListing.Items[ind].FileName; ftp.Get(names, 'C:\'+names,False); end; procedure TMainForm.ftpWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); begin if MainForm <> Nil then begin if AWorkCount > Pb.Max then Pb.Max := 2 * Pb.Max; Pb.Position := AWorkCount; Pb.Update; end; end; procedure TMainForm.ftpWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); begin if MainForm <> Nil then begin Pb.Position:= 0; Pb.Max:= AWorkCountMax; Pb.Visible:= True; Pb.Update; end; end; procedure TMainForm.ftpWorkEnd(ASender: TObject; AWorkMode: TWorkMode); begin { --- Completato --- } if MainForm <> Nil then begin Pb.Position := Pb.Max; Pb.Visible := True; Pb.Update; end; end;
|
Button2 è quello che utilizzo per il download... non riesco proprio a capire perchè non va!
Grazie..
|
|
()
Newbie
Messaggi:
Iscritto:
|
mi sono solo accorto aggiungendo dei ShowMessage per monitorare i processi che in realtà AWorkCountMax = 0
Come mai!? Come risolvo il tutto?
|
|
alessandrob (Normal User)
Newbie
Messaggi: 17
Iscritto: 19/01/2010
|
Probabilmente gli eventi non sono agganciati al controllo.
Dovresti provare a selezionare il controllo IdFtp e nella finestra Object Inspector, pagina Events, per gli eventi OnWork, OnWorkBegin, OnWorkEnd (che probabilmente sono vuoti) eseguire un doppio click con il mouse.
Dovrebbe a questo punto apparire l'aggancio con l'evento (la procedura che ti ho descritto sopra)
Ti cosiglio inoltre di rimuovere il test
if MainForm <> Nil ...
visto che lavori direttamente nel form principale.
A questo punto, durante il download, dovresti quanto meno verificare se il codice passa per gli eventi di cui sopra.
Ti consiglio di non usare i messagebox per i test di verifica, ma di inserire un controllo TMemo e aggiungere una linea per ogni volta che passa per l'evento di interesse.
|
|
()
Newbie
Messaggi:
Iscritto:
|
E' esattamente quello che ho fatto...
Il codice passa per gli eventi e infatti gli showmessage, siano utili o no, che ci metto dentro si avviano. Il problema è che AWorkCount mi restituisce un valore numerico maggiore di zero ma proprio la funzione AWorkCountMax mi restituisce 0. E perciò è ovvio che la progressbar non funzioni avendo come MAX 0.
Non riesco a capire come risolvere.
PS: ho anche tolto quel controllo Nil, ho provato di tutto...
|
|