angelp4492
11-05-2012, 10:40:23
Buenos días, siguiendo un ejemplo de downloader de Neftali me he creado esta unidad de descarga
unit UnitDownload;
interface
uses
Dialogs,SysUtils,Classes, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,DateUtils;
type
TIdHTTPThread = class(TThread) //DEFINIMOS EL thread de decarga
private
//definimos las variables del thread
FURL: AnsiString; //dirección de descarga
FFilename: AnsiString; //nombre del fichero de descarga
velocidad,transferencia,tiempo,size,porcentaje: string; // velocidad,transferencia de descarga y tamaño del fichero
posProgress,maxProgress : Int64; // datos para la barra de progreso
Proxyport: Int64; //datos para el proxy
ProxyServer:AnsiString;
IdHTTP: TIdHTTP; //objeto TidHTTP
ProxySI : Boolean; // para comprobar si la conexión es por proxy
threadterminado : Boolean; //para esperar que termine el thread
parar : Boolean; //parar el thread.
TID : Integer; //identificador del thread
//definimos los procedimientos del thread
procedure OnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
procedure OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
procedure OnWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
procedure cancel;
procedure Updatelabel;
procedure UpdaProgressbar;
procedure FinThread;
procedure IniThread;
procedure EndNotify;
public
//constructor del thread para pasarle parámetros.
constructor Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:Integer);
Destructor Destroy; override;
//property Url: AnsiString read FURL write FUrl;
//property Filename: AnsiString read FFilename write FFilename;
//property Proxy_SI : Boolean read ProxySI write ProxySI;
//property Proxy_Port: Int64 read Proxyport write Proxyport;
//property Proxy_Server: AnsiString read ProxyServer write ProxyServer;
property terminado :Boolean read Threadterminado write Threadterminado;
// con la propiedad property intercambio información con el thread y el formulario
property parate : Boolean read parar write parar;
protected
procedure Execute; override;
end;
implementation
uses Unit1; // aqui ponemos la unidad desde donde será ejecutado el thread.
constructor TIdHTTPThread.Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:integer);
begin
inherited Create(false);
FreeOnTerminate := True;
FURL :=sFUrl;
FFilename:=destino;
ProxySI:=Proxy;
Proxyport:=sProxyport;
ProxyServer:=sProxyserver;
TID:=sTID
end;
destructor TIdHTTPThread.Destroy;
begin
IdHTTP.Free;
inherited;
end;
procedure TIdHTTPThread.cancel;
begin
if (IdHTTP.Connected) and (parar = True) then
IdHTTP.Disconnect;
end;
procedure TIdHTTPThread.Execute;
var
fs: TFileStream;
idHTTP : TidHttp;
begin
Synchronize(IniThread);
idHttp:= Tidhttp.create(nil);
if ProxySI = true then
begin
IdHTTP.ProxyParams.ProxyServer:=ProxyServer;
IdHTTP.ProxyParams.ProxyPort:=Proxyport;
end;
idHTTP.HandleRedirects := True;
idHTTP.ReadTimeout := 30000;
IdHTTP.ProtocolVersion:= pv1_0;
idHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)';
IdHTTP.OnWork := Onwork;
IdHTTP.OnWorkBegin:=OnWorkBegin;
IdHTTP.OnWorKEnd:=OnWorkEnd;
//ShowMessage('proxy='+ProxyServer);
//ShowMessage(FFilename);
//ShowMessage(furl);
fs := TFileStream.Create(FFilename, fmCreate);
try
IdHTTP.Get(FUrl, fs);
finally
fs.Free;
Synchronize(EndNotify);
end;
end;
//Poner estado de valores cuando se empieza a descargar
procedure TIdHTTPThread.OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
begin
posProgress:= 0;
if AWorkMode = wmRead then //uniquement quand le composant recoit des données
begin
maxProgress := AWorkCountMax; //Maximum = taille du soft à télécharger
posProgress := 0; //Position à zéro
end;
if AWorkMode = wmRead then //uniquement quand le composant recoit des données
begin
velocidad := 'Descarga: 0 Kb/s ';
FStartDate := Now; //enregistre la date
//Application.ProcessMessages; //Evite que l'appli soit "gelée"
end;
Synchronize(Updatelabel);
Synchronize(Updaprogressbar);
end;
procedure TIdHTTPThread.OnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
var
ElapsedTime : Cardinal;
n1,n2 : double;
begin
// Avanzando...
if AWorkMode=wmRead then //quand on recoit des données
begin
posProgress := AWorkCount + 40;
size := Format(' %s Mb',[FormatFloat('0.00',(maxProgress)/1024000)]);
ElapsedTime := SecondsBetween(Now,FStartDate); //Calcule la vitesse de téléchargement
if ElapsedTime>0 then
begin
velocidad := Format('Descarga: %s Kb/s',[FormatFloat('0.00',(AWorkCount/1024)/ElapsedTime)]);
n1:= (AWorkCount/1024000);
n2:= (maxProgress/1024000);
// velocidad := Format('Descarga: %s Kb/s',[FormatFloat('0.00',(AWorkCount*elapsedtime)/1024)]);
transferencia:= Format('Descargado: %s Mb ',[FormatFloat('0.00',(AWorkCount/1024000))])+Format('De: %s Mb',[FormatFloat('0.00',(maxProgress)/1024000)]);;
//lbldescarga.Caption:=lbldescarga.Caption+' de '+ Format('Descargado: %s Mb/s',[FormatFloat('0.00',(ProgressBar1.Max)/1024000)]);
porcentaje:=Format('Porcentaje: %s',[FormatFloat('0',((AWorkCount*100)/maxprogress))])+'%';
tiempo:=Format('Tiempo Restante %s ',[FormatDateTime('tt',((n2-n1)*elapsedtime))]);
//Application.ProcessMessages; //Evite que l'appli soi "givrée"
end;
end;
//ShowMessage(IntToStr(aworkcount));
Synchronize(Updatelabel);
Synchronize(Updaprogressbar);
end;
procedure TIdHTTPThread.OnWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
// Acabado
maxProgress := 0;
transferencia:='Descargando:';
velocidad:='Descarga:';
Synchronize(Updatelabel);
Synchronize(Updaprogressbar);
end;
//procedimiento para actualizar las variables del form
//los llamamos con synchronize (nameprocedimiento=
procedure TIdHTTPThread.Updatelabel;
begin
Form1.UpdateLabel(velocidad,transferencia,tiempo,size,porcentaje);
end;
procedure TIdHTTPThread.UpdaProgressbar;
begin
Form1.UpdateProgressbar(posProgress,maxProgress);
end;
procedure TIdHTTPThread.FinThread ;
begin
form1.finthread:=True;
end;
procedure TIdHTTPThread.IniThread ;
begin
form1.finthread:=false;
end;
procedure TIdHTTPThread.EndNotify;
begin
Form1.eventhreadterminate(TID);
end;
end.
seguramente se podrá mejorar.
El problema es que esto me funciona cuando tengo un solo thread, pero como haria por ejemplo que es lo que quiero hacer para mandar los datos de descarga con un progressbar a un listview y en multithread. O sea un Multidownloader con listview y progressbar al estilo del Jdonwloader.
unit UnitDownload;
interface
uses
Dialogs,SysUtils,Classes, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,DateUtils;
type
TIdHTTPThread = class(TThread) //DEFINIMOS EL thread de decarga
private
//definimos las variables del thread
FURL: AnsiString; //dirección de descarga
FFilename: AnsiString; //nombre del fichero de descarga
velocidad,transferencia,tiempo,size,porcentaje: string; // velocidad,transferencia de descarga y tamaño del fichero
posProgress,maxProgress : Int64; // datos para la barra de progreso
Proxyport: Int64; //datos para el proxy
ProxyServer:AnsiString;
IdHTTP: TIdHTTP; //objeto TidHTTP
ProxySI : Boolean; // para comprobar si la conexión es por proxy
threadterminado : Boolean; //para esperar que termine el thread
parar : Boolean; //parar el thread.
TID : Integer; //identificador del thread
//definimos los procedimientos del thread
procedure OnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
procedure OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
procedure OnWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
procedure cancel;
procedure Updatelabel;
procedure UpdaProgressbar;
procedure FinThread;
procedure IniThread;
procedure EndNotify;
public
//constructor del thread para pasarle parámetros.
constructor Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:Integer);
Destructor Destroy; override;
//property Url: AnsiString read FURL write FUrl;
//property Filename: AnsiString read FFilename write FFilename;
//property Proxy_SI : Boolean read ProxySI write ProxySI;
//property Proxy_Port: Int64 read Proxyport write Proxyport;
//property Proxy_Server: AnsiString read ProxyServer write ProxyServer;
property terminado :Boolean read Threadterminado write Threadterminado;
// con la propiedad property intercambio información con el thread y el formulario
property parate : Boolean read parar write parar;
protected
procedure Execute; override;
end;
implementation
uses Unit1; // aqui ponemos la unidad desde donde será ejecutado el thread.
constructor TIdHTTPThread.Create(sFUrl : AnsiString; destino : AnsiString; Proxy :Boolean; sProxyport : Int64; sProxyserver:AnsiString ; sTID:integer);
begin
inherited Create(false);
FreeOnTerminate := True;
FURL :=sFUrl;
FFilename:=destino;
ProxySI:=Proxy;
Proxyport:=sProxyport;
ProxyServer:=sProxyserver;
TID:=sTID
end;
destructor TIdHTTPThread.Destroy;
begin
IdHTTP.Free;
inherited;
end;
procedure TIdHTTPThread.cancel;
begin
if (IdHTTP.Connected) and (parar = True) then
IdHTTP.Disconnect;
end;
procedure TIdHTTPThread.Execute;
var
fs: TFileStream;
idHTTP : TidHttp;
begin
Synchronize(IniThread);
idHttp:= Tidhttp.create(nil);
if ProxySI = true then
begin
IdHTTP.ProxyParams.ProxyServer:=ProxyServer;
IdHTTP.ProxyParams.ProxyPort:=Proxyport;
end;
idHTTP.HandleRedirects := True;
idHTTP.ReadTimeout := 30000;
IdHTTP.ProtocolVersion:= pv1_0;
idHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)';
IdHTTP.OnWork := Onwork;
IdHTTP.OnWorkBegin:=OnWorkBegin;
IdHTTP.OnWorKEnd:=OnWorkEnd;
//ShowMessage('proxy='+ProxyServer);
//ShowMessage(FFilename);
//ShowMessage(furl);
fs := TFileStream.Create(FFilename, fmCreate);
try
IdHTTP.Get(FUrl, fs);
finally
fs.Free;
Synchronize(EndNotify);
end;
end;
//Poner estado de valores cuando se empieza a descargar
procedure TIdHTTPThread.OnWorkBegin(Sender: TObject; AWorkMode: TWorkMode;const AWorkCountMax: Integer);
begin
posProgress:= 0;
if AWorkMode = wmRead then //uniquement quand le composant recoit des données
begin
maxProgress := AWorkCountMax; //Maximum = taille du soft à télécharger
posProgress := 0; //Position à zéro
end;
if AWorkMode = wmRead then //uniquement quand le composant recoit des données
begin
velocidad := 'Descarga: 0 Kb/s ';
FStartDate := Now; //enregistre la date
//Application.ProcessMessages; //Evite que l'appli soit "gelée"
end;
Synchronize(Updatelabel);
Synchronize(Updaprogressbar);
end;
procedure TIdHTTPThread.OnWork(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
var
ElapsedTime : Cardinal;
n1,n2 : double;
begin
// Avanzando...
if AWorkMode=wmRead then //quand on recoit des données
begin
posProgress := AWorkCount + 40;
size := Format(' %s Mb',[FormatFloat('0.00',(maxProgress)/1024000)]);
ElapsedTime := SecondsBetween(Now,FStartDate); //Calcule la vitesse de téléchargement
if ElapsedTime>0 then
begin
velocidad := Format('Descarga: %s Kb/s',[FormatFloat('0.00',(AWorkCount/1024)/ElapsedTime)]);
n1:= (AWorkCount/1024000);
n2:= (maxProgress/1024000);
// velocidad := Format('Descarga: %s Kb/s',[FormatFloat('0.00',(AWorkCount*elapsedtime)/1024)]);
transferencia:= Format('Descargado: %s Mb ',[FormatFloat('0.00',(AWorkCount/1024000))])+Format('De: %s Mb',[FormatFloat('0.00',(maxProgress)/1024000)]);;
//lbldescarga.Caption:=lbldescarga.Caption+' de '+ Format('Descargado: %s Mb/s',[FormatFloat('0.00',(ProgressBar1.Max)/1024000)]);
porcentaje:=Format('Porcentaje: %s',[FormatFloat('0',((AWorkCount*100)/maxprogress))])+'%';
tiempo:=Format('Tiempo Restante %s ',[FormatDateTime('tt',((n2-n1)*elapsedtime))]);
//Application.ProcessMessages; //Evite que l'appli soi "givrée"
end;
end;
//ShowMessage(IntToStr(aworkcount));
Synchronize(Updatelabel);
Synchronize(Updaprogressbar);
end;
procedure TIdHTTPThread.OnWorkEnd(Sender: TObject; AWorkMode: TWorkMode);
begin
// Acabado
maxProgress := 0;
transferencia:='Descargando:';
velocidad:='Descarga:';
Synchronize(Updatelabel);
Synchronize(Updaprogressbar);
end;
//procedimiento para actualizar las variables del form
//los llamamos con synchronize (nameprocedimiento=
procedure TIdHTTPThread.Updatelabel;
begin
Form1.UpdateLabel(velocidad,transferencia,tiempo,size,porcentaje);
end;
procedure TIdHTTPThread.UpdaProgressbar;
begin
Form1.UpdateProgressbar(posProgress,maxProgress);
end;
procedure TIdHTTPThread.FinThread ;
begin
form1.finthread:=True;
end;
procedure TIdHTTPThread.IniThread ;
begin
form1.finthread:=false;
end;
procedure TIdHTTPThread.EndNotify;
begin
Form1.eventhreadterminate(TID);
end;
end.
seguramente se podrá mejorar.
El problema es que esto me funciona cuando tengo un solo thread, pero como haria por ejemplo que es lo que quiero hacer para mandar los datos de descarga con un progressbar a un listview y en multithread. O sea un Multidownloader con listview y progressbar al estilo del Jdonwloader.