Ver Mensaje Individual
  #1  
Antiguo 24-01-2010
Avatar de DriverOp
DriverOp DriverOp is offline
Miembro
 
Registrado: ago 2007
Posts: 93
Reputación: 19
DriverOp Va por buen camino
Ventana modal y cómo cerrarla por código.

Uso Delphi 6.0 con updates 1 y 2.

Mi problema trata sobre cómo es la forma correcta de cerrar y liberar por código ventanas modales ya que en mi aplicación de la forma que lo estoy haciendo a veces me lanza una excepción y a veces no.

Cuando sucede una excepción puede ser un clásico Access Violation y a veces un "Abstract Error" que nunca vi en mi vida.

La situación es esta. Le muestro al usuario una lista de datos, internamente la lista es un TObjectList. El usuario puede hacer doble clic en cualquier dato y le traerá una ventana modal donde puede manipular ese dato en particular. Como la ventana es modal no puede hacer otra cosa más que eso mientras la tenga abierta.

La ventana modal la creo dinámicamente así (simplificado):

Código:
if not Assigned(FrmModif) then
  FrmModif:=TFrmModif.Create(Self);
try
  FrmModif.Nodo:=Nodo; // 'Nodo' es el nodo de la lista que está por ser editada
  FrmModif.ShowModal;
finally
  FreeAndNil(FrmModif);
end;
Lo que me asegura que la ventana quede liberada.

Pero sucede que bajo ciertas circunstancias, la lista que está "detrás" puede cambiar, y me refiero a cambiar totalmente, debido a un evento externo al programa de forma tal que los datos mostrados en la lista dejan de ser válidos. Aquí la forma de proceder es cuando sucede el evento elimino la lista actual y la vuelvo a construir con los nuevos datos.

Como podrán darse cuenta el problema está en que si el usuario justo en ese momento tiene una ventana modal abierta está tratando de manipular un dato que ya no existe en la lista de datos. Lo que hago aquí es cerrarle la ventana modal por código[1]. Aquí es donde aparece el problema.

Lo que hago es esto:

Código:
if Assigned(FrmModif) then
  FrmModif.ModalResult:=MrCancel;
Es decir, es como si el usuario hubiese cancelado la ventana.
Supongo que esto causa que se ejecute el resto del código que está más arriba, es decir, que se ejecute el FreeAndNil().

Sin embargo como he mencionado, a veces me causa excepción por Access Violation y a veces por 'Abstract Error' pero a veces no causa ningún problema y el código funciona lo más bien. No he podido determinar bajo qué circunstancias ocurre una cosa o la otra y el debugger de Delphi no me ayuda en mucho porque cuando sucede la excepción me la marca en el procedimiento Application.Run;

Evidentemente algo estoy haciendo mal pero no sé qué es.

Gracias por su atención.

[1]En realidad el evento que invalida la lista entera es causado indirectamente por el usuario, el usuario 'sabe' que los datos actuales de mi programa no serán válidos pero eso no quita que el problema siga estando allí. No le puedo decir al usuario "antes de hacer A tienes que hacer B porque sino tendrás un feo error", es algo que tiene que manejar mi programa transparentemente.
Responder Con Cita