Ver Mensaje Individual
  #3  
Antiguo 06-08-2003
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Reputación: 28
jachguate Va por buen camino
Cool

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.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita