Cita:
Kaesbu escribió
El problema es que cuando llega al application.processmessages el buffer se vacia y el programa sale del bucle. Alguna idea? Gracias.
|
Habría que ver cómo estás bajando el archivo. ¿Qué es lo que haces en cada paso del bucle?
Aquí te va una idea de cómo usar threads. El ejemplo es para copiar un archivo mostrando el avance en un ProgressBar pero puede servirte como punto de partida ya que la situación es similar: copiar bloques de archivos.
Primero debes declarar un descendiente de TThread que se ocupará del copiado:
Código:
type
TCopyFileThread = class
private
ProgressBar: TProgressBar; // Barra de progreso
procedure UpdateProgress;
protected
procedure Execute; override;
public
CopyFrom: String; // Archivo origen
CopyTo: String; // Archivo destino
BufferSize: LongInt; // Tamaño de cada bloque
constructor Create(AProgressBar: TProgressBar);
end;
El método Execute se llama cuando se inicia el hilo y es ahí donde debes poner el código de copiado.
UpdateProgress se encargará de actualizar el ProgressBar.
La implementación es así:
Código:
constructor TCopyFile.Create(AProgressBar: TProgressBar);
begin
// Crear el hilo pero no iniciarlo
inherited Create(true);
ProgressBar := AProgressBar;
BufferSize := 255;
end;
procedure TCopyFile.UpdateProgress;
begin
ProgressBar.StepBy(BufferSize);
end;
procedure TCopyFile.Execute;
var
Source, Dest: TFileStream;
Buffer: Pointer;
BytesRead: LongInt;
begin
Source := TFileStream.Create(CopyFrom, fmOpenRead);
Dest := TFileStream.Create(CopyTo, fmCreate);
GetMem(Buffer, BufferSize);
ProgressBar.Max := Source.Size;
try
/*
En este ciclo se hace el copiado
Terminated es una variable del hilo que es false
hasta que éste termine
*/
while not Terminated do
begin
BytesRead := Source.Read(Buffer^, BufferSize);
Dest.Write(Buffer^, BytesRead);
/*
Es necesario llamar a UpdateProgress mediante
Synchronize ya que UpdateProgress usda objetos
del VCL
*/
Synchronize(UpdateProgress);
if BytesRead < BufferSize then Terminate;
end;
finally
Source.Free;
Dest.Free;
FreeMem(Buffer);
end;
end;
Eso es todo. En tu formulario declaras una variable CopyFile de tipo TCopyFileThread. Para iniciar el copiado haces:
Código:
CopyFile := TCopyFileThread.Create(ProgressBar1);
CopyFile.CopyFrom := archivo origen;
CopyFile.CopyTo := archivo destino;
CopyFile.Resume;
donde ProgressBar1 es un ProgressBar en tu formulario.
// Saludos
En un botones adecuados de tu formulario usas los métodos
CopyFile.Suspend para pausar el copiado
CopyFile.Resume para continuar
CopyFile.Terminate para cancelar el copiado