PDA

Ver la Versión Completa : progress bar en inno setup


teecweb
06-03-2013, 22:36:17
Holas ..

Tengo un procedimiento que demora en ejecutar..entonces para que el usuario no se quede mirando la pantallapienso poner un progressbar segun el tiempo de demora del progressbar ....este el codigoq eu eh puesto

cuando hago clic en la funcion siguiente de welcome me deberia aparecer un progressbar mientras tanto va ejecutandose este procedimiento CreateTheWizardPages (busca rutas)

wpWelcome:
begin
MsgBox('false', mbInformation, MB_OK);
ProgressPage := CreateOutputProgressPage('My App','');
ProgressPage.SetText('Starting installation...', '');
ProgressPage.SetProgress(0, 0);
ProgressPage.Show;
try
for I := 0 to 10 do begin
ProgressPage.SetProgress(I, 10);
Sleep(100);
end;
finally
ProgressPage.Hide;

end;
end;



en realidad como pueden ver le doy el tamaño del progreso pero en si no controlo el tiempo de demora del procedimiento..estare al tanto de sus respuestas gracias.

Ñuño Martínez
08-03-2013, 14:03:53
Lo que debes controlar no es el tiempo, sino el número de pasos que realiza el procedimiento. No sé cómo se puede hacer esto dentro de InnoSetup pero, basándome en tu código, el algoritmo sería así (más o menos):
CONST
NumPasos = Número de pasos que realice;
BEGIN
MsgBox('false', mbInformation, MB_OK);
ProgressPage := CreateOutputProgressPage ('My App','');
ProgressPage.SetText ('Starting installation...', '');
ProgressPage.SetProgress (0, 0);
ProgressPage.Show;
TRY
FOR I := 1 TO NumPasos DO
BEGIN
RealizaPaso (I);
ProgressPage.SetProgress (I, NumPasos);
END;
FINALLY
ProgressPage.Hide;
ProgressPage.Free; { <--- Olvidaste esto, y es MUY importante. }
END;
END;

Es decir, no espera un tiempo, sino que espera a que se realice cada paso.

Si se usan distintos hilos de ejecución (que es lo que parece), entonces necesitarás una variable global que el procedimiento de instalación deberá ir actualizando. En ese caso, el bucle sería diferente:

CONST
NumPasos = Número de pasos que realice;
VAR
{ Variable global actualizada por el procedimiento que realiza el trabajo. }
PasoActual: INTEGER;
...

BEGIN
MsgBox('false', mbInformation, MB_OK);
ProgressPage := CreateOutputProgressPage ('My App','');
ProgressPage.SetText ('Starting installation...', '');
ProgressPage.Show;
TRY
REPEAT
ProgressPage.SetProgress (PasoActual, NumPasos);
Sleep (1000);
UNTIL PasoActual > NumPasos;
FINALLY
ProgressPage.Hide;
ProgressPage.Free; { <--- Olvidaste esto, y es MUY importante. }
END;
END;

Como ves, aquí sí es necesario un Sleep para evitar la saturación de la UCP. Por otro lado, el procedimiento que realiza la actualización debe contar los pasos desde 1, no desde 0, y asignarle un valor mayor a NumPasos para indicar que ya ha terminado de realizar el trabajo.

Espero que te sirva.

teecweb
12-03-2013, 02:30:22
Gracias , probare el codigo:D

teecweb
16-03-2013, 00:23:02
holas..me podrias eplicar esta parte "{ Variable global actualizada por el procedimiento que realiza el trabajo. }
PasoActual: INTEGER;" ...aqui te muestro mi procedimiento y ala vez este proc llama a otro proc y ese proc a otro proc :..
este es el codigo que llama al progreesbar..cuando esta en el next de Welcome se deberia ejecutar el progreesbar y a la vez el procedimiento que demora en ejecutar

function NextButtonClick(CurPageID: Integer): Boolean;
var
ResultCode: Integer;
MyProgChecked: Boolean;
MyProg: Boolean;
MyProg2: Boolean;
MyProgtexto: String;
resultadomsg: Boolean;
I: Integer;
begin

MyProg :=True;

case CurPageID of
wpSelectDir:
begin
MyProgChecked :=DirExists(WizardDirValue);
if MyProgChecked then
begin
resultadomsg :=MsgBox('Folder:' #13#13 ' ''' + WizardDirValue + ''' ' #13#13 'There, you want to install it anyway?', mbConfirmation, MB_YESNO) = idYes;
if resultadomsg = False then
begin
MyProg := False;
end;

//MyProg := False;
end;
end;
wpWelcome:
begin
CreateTheWizardPages;
ProgressPage := CreateOutputProgressPage('My App','');
ProgressPage.SetText('Starting installation...', '');
ProgressPage.SetProgress(0, 0);
ProgressPage.Show;
try
for I := 0 to 10 do begin
ProgressPage.SetProgress(I, 10);
Sleep(100);
end;
finally
ProgressPage.Hide;

end;
end;
end;//fin del case
Result := MyProg;
end;

este el codigo del procedimiento CreateTheWizardPages y este llama a otro proc llamado BuscarArchivos

procedure CreateTheWizardPages;
var

Edit: TNewEdit;
listado: TStrings;
inicio: Integer;
scale : Integer;
scale1:Integer;
j:Integer;
n: integer;
DataDir: String;


begin
{ TButton and others }
listado := TStringList.Create;
Page := CreateCustomPage(wpWelcome, 'List of files in the system',
'Want to remove any previous versions?, If you want to remove any previous version Callcenter, please select an item.');


Buttona := TNewButton.Create(Page);
Buttona.Width := ScaleX(240);
Buttona.Height := ScaleY(23);
Buttona.Caption := 'Uninstall the selected path';
Buttona.Parent := Page.Surface;
Buttona.Visible := true;
Buttona.OnClick := @ButtonOnClicka;

BuscarArchivos(ExpandConstant('{pf}'+ '\'), 'CallCenter.exe', listado);

scale :=8;
CheckListBox1 := TNewCheckListBox.Create(Page);
j :=5;
scale :=scale+ (j+15);
CheckListBox1 := TNewCheckListBox.Create(Page);//TNewCheckListBox.Create(WizardForm.ScriptDlgPanel);
CheckListBox1.Top := Buttona.Top + Buttona.Height + ScaleY(scale);
CheckListBox1.Width := 410;
CheckListBox1.Height :=180;
CheckListBox1.Parent := Page.Surface;
// CheckListBox1.OnClick:=@uninstaller;

for inicio := 0 to listado.Count - 1 do
// for inicio := 0 to 5 do
begin
CheckListBox1.AddCheckBox(listado[inicio], 'Path', 0, False, True, True, True, nil);
end;
listado.Free;

end;

Por favor me podria explicar como el numero de pasos..gracias por sus respuestas:D

Ñuño Martínez
18-03-2013, 20:27:20
La verdad es que ando perdido cual pulpo en garaje. Ya dije que no me manejo muy bien con InnoSetup. Aun así, voy a ver si explicando qué es una variable global (que parece que es tu duda) lo arreglo.

Una variable global es una que existe durante todo el tiempo de ejecución del programa y es accesible desde cualquier parte del mismo, como contrapartida de una variable local que sólo existe en el tiempo de ejecución de una función o procedimiento y sólo puede accederse desde dicha función. Por ejemplo:

PROGRAM Ejemplo;

VAR
VariableGlobal: INTEGER;

PROCEDURE Procedimiento;
VAR
VariableLocal: INTEGER;
BEGIN
...
VariableGlobal := VariableLocal;
END;

PROCEDURE OtroProcedimiento;
VAR
VariableLocal: INTEGER;
BEGIN
...
VariableGlobal := VariableLocal;
END;

END.

En el caso que nos ocupa, necesitas una variable global puesto que las partes se ejecutan paralelamente (es decir, se ejecutan al mismo tiempo, o eso he entendido a partir de tu explicación). Básicamente lo haría así:

....
CONST
(* Número de pasos necesarios en la instalación. *)
NUM_PASOS := 5;

VAR
(* Número de pasos que se está realizando. *)
NumPasoActual: INTEGER;

(* Procedimiento que muestra la barra de progreso. *)
PROCEDURE MuestraBarra;
BEGIN
ProgressPage := CreateOutputProgressPage('My App','');
ProgressPage.SetText('Starting installation...', '');
ProgressPage.Show;
try
{ Repite hasta que finaliza el proceso. }
REPEAT
ProgressPage.SetProgress(NumPasoActual, NUM_PASOS);
Sleep(100);
UNTIL NumPasoActual > NUM_PASOS;
finally
ProgressPage.Hide;
ProgressPage.Free; { <- Sigo creyendo que olvidas esto. ¿Acaso se destruye sólo? }
end;
END;


(* Procedimiento que instala. *)
PROCEDURE Instalar;
BEGIN
{ Primer paso. }
NumPasoActual := 1;
HacePasoUno (Parametro1, OtroParametro);
{ Segundo paso. }
INC (NumPasoActual)
HacePasoDos (Parametro1, OtroParametro);
{ Tercer paso. }
INC (NumPasoActual)
HacePasoTres (Parametro1, OtroParametro);
{ Perdí la cuenta. }
INC (NumPasoActual)
OtroPaso (Parametro1, OtroParametro);
{ Último paso. }
INC (NumPasoActual)
UltimoPaso (Parametro1, OtroParametro);
{ Para decirle a MuestraBarra que ya hemos terminado. }
NumPasoActual := NUM_PASOS + 1;
END;