atani123,
Cita:
Empezado por atani123
...Tengo un problema de visualización...el Progressbar no sigue el ritmo...las cuatro primeras veces la barra solo llega hasta el 10% y vuelve a comenzar, y la ultima vez, sale el mensaje de "fin" y el Progressbar aun va por el 70%...Supongo que el tema es que el ProgressBar lleva un Thread independiente, ¿pero es posible evitar esto y sincronizarlo exacto?...Solo es estético...Antes con Delphi 7 esto era clavado pero ahora con XE tengo este problema...
|
Pregunto: ¿Que versión de
Delphi y Windows utilizas?, ¿Es Windows de
32 o 64 bits?.
Revisa este código:
Código Delphi
[-]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ProgressBar1: TProgressBar;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FreePBThread(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
private
public
end;
TPBThread = class(TThread)
private
procedure UpdatePB;
protected
procedure Execute; override;
end;
const
Max = 100000;
PBStep = 1;
var
Form1: TForm1;
PBThread : TPBThread;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Caption := EmptyStr;
Label1.AutoSize := True;
Label1.Font.Color := clBlue;
end;
procedure TPBThread.UpdatePB;
var
PctDone : Extended;
PBPos, PBMax, PctPB : String;
begin
with form1 do
begin
if Assigned(PBThread) then
begin
ProgressBar1.StepBy(PBStep);
PctDone := ProgressBar1.Position / ProgressBar1.Max;
PBPos := FormatFloat('#,###,###,###', ProgressBar1.Position);
PBMax := FormatFloat('#,###,###,###', ProgressBar1.Max);
PctPB := FormatFloat('0.00 %', PctDone * 100);
Label1.Caption := Format('Estadística : %s de %s (Ejecutado %s)',[PBPos, PBMax, PctPB]);
end;
end;
end;
procedure TPBThread.Execute;
var
i : Integer;
begin
FreeOnTerminate := True;
for i := 1 to Max do
begin
if not Terminated then
Synchronize(UpdatePB)
else
Exit;
end
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(PBThread) then
begin
ProgressBar1.Position := 0;
ProgressBar1.Min := 1;
ProgressBar1.Max := Max;
PBThread := TPBThread.Create(False);
PBThread.OnTerminate := FreePBThread;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if Assigned(PBThread) then
begin
PBThread.Terminate;
PBThread := nil;
ProgressBar1.Position := 0;
Label1.Caption := EmptyStr;
end
else
MessageDlg('No Existe un Hilo Activo para Finalizar', mtInformation, [mbOK], 0);
end;
procedure TForm1.FreePBThread(Sender: TObject);
begin
PBThread := nil;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if Assigned(PBThread) then
CanClose := False;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
end.
El código anterior en Delphi XE7 sobre Windows 7 Professional x32,
Ejemplifica el uso de un TProgressBar en un hilo y como sincronizar este con la aplicación, como se muestra en la siguiente imagen:
Nota: El código del ejemplo,
funciona correctamente en Delphi 7 sobre Windows 7 Professional x32.
Espero sea útil
Nelson.