Oppure

Loading
17/02/10 12:59
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
17/02/10 13:30
systemgvp
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
aaa
17/02/10 14:03
alessandrob
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
aaa
17/02/10 16:22
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
17/02/10 17:32
alessandrob
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;
aaa
17/02/10 20:21
Ciao ho posto il tuo codice all'interno della stessa form ma non funziona...
ti posto il mio codice:
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..
17/02/10 20:57
mi sono solo accorto aggiungendo dei ShowMessage per monitorare i processi che in realtà AWorkCountMax = 0
Come mai!? Come risolvo il tutto?
18/02/10 14:35
alessandrob
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.
aaa