Ver Mensaje Individual
  #9  
Antiguo 25-02-2015
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Reputación: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
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
    { Private declarations }
  public
    { Public declarations }
  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.

Última edición por nlsgarcia fecha: 03-03-2015 a las 03:01:03.
Responder Con Cita