Solo quiero agregar que cuando llamas a application.processMessages dentro de un bucle, debes tener cuidado con un par de cosas, principalmente deshabilitando controles, pues tu aplicación seguirá respondiendo a todos los mensajes que reciba.
- Si tenes un usuario "travieso", que presiona diez veces el botón "Procesar", vas a tener en la pila diez procesos corriendo, uno detras de otro, y esto podria provocar problemas serios. Digamos, si es un proceso que aumenta los precios en un 10%, al final vas a tener los precios aumentados en un 159.37%!!!. Además, podrias tener problemas de concurrencia.
- Si hay controles para parametrizar alguna acción del proceso (como checkboxes, etc) el usuario podria cambar su valor a mitad del proceso, por ejemplo.
- Otro problema es que el usuario podria cerrar la ventana a medio proceso.
Por lo tanto lo recomendable es deshabilitar todos los controles antes de iniciar el proceso (excepto el botón cancelar) y controlar si se permitirá cerrar la ventana al usuario.
En código, podria ser algo como:
Código:
Type
TForm1 = Class(TForm)
..
Private
FEnProceso : Boolean;
FCancelado : Boolean;
..
Implementation
Procedure TForm1.bProcesarClick(Sender : TObject);
Var
i : Longint;
Begin
FEnProceso := True;
FCancelado := False;
try
InicializarProceso;
DeshabilitarControles;
For i := 1 to 2147483647 do
Begin
RealizarIteracionDelProceso;
Application.ProcessMessages;
if FCancelado Then
Break; // paramos el proceso
End;
if Not FCancelado Then
ProcesoTerminadoConExito;
else
RealizarAccionesParaCancelar;
finally
FEnProceso := False;
HabilitarControles;
end;
End;
Procedure TForm1.CloseQuery(sender : TObject; var CanClose : Boolean);
Begin
// evitamos que el usuario cierre la forma mientras se está ejecutando el proceso
CanClose := not FEnProceso;
End;
Procedure TForm1.bCancelarClick(Sender : TObject);
Begin
FCancelado := ConfirmaQueQuieraCancelarElProceso;
End;
Espero que la idea te sea de ayuda.
Hasta luego.