Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Al cerrar Form no entra en OnClose (https://www.clubdelphi.com/foros/showthread.php?t=25109)

nowheremanza 12-09-2005 23:54:49

Al cerrar Form no entra en OnClose
 
Buenas...
soy nuevo aquí y espero que tengais paciencia conmigo si he abierto un hilo en el foro equivocado o meto la pata en cualquier tema...
El hecho es que me había currado un pedazo de mensaje y al ir a enviarlo, me ha dicho que no estaba logeado (que si lo estaba antes), y se me ha ido todo a la mi... pero bueno, resumo y listos.
El problema que tengo es con un Form al cual llamo desde el Form Principal. Lo llamo de forma Modal, pero antes de mostrar dicho form informo al usuario que debe hacer una cosa primero (por temas que no vienen al caso). Si acepta muestra el form con algunas opciones menos, etc... pero si cancela, lo único que hago es cerrar el Form (que aún no ha sido mostrado), preguntándole si desea abandonar la acción. Pues bien, si muestro el Form normal se cierra correcto, pero si lo muestro Modal, al hacer el Close, no entra en el evento OnClose.
Como me estoy enrollando demasiado para una cosa tan simple, pongo código:

Form Principal:

Código Delphi [-]
 with TfrmGestioUsuaris.Create(nil) do
 begin
   ShowModal;
 end;
Form :

Código Delphi [-]
 procedure TfrmGestioUsuaris.FormShow(Sender: TObject);
 {...}
   iResposta := MessageBox(Handle, PAnsiChar(USU_QUEST_PRIMER),
   PAnsiChar(TIT_USU_GEST), M B_OKCANCEL+MB_ICONQUESTION);
   case iResposta of
     IDOK: DesactivarBotonsEdicio();
     IDCANCEL: Close;
   end;
 {...}
 end;
Código Delphi [-]
 procedure TfrmGestioUsuaris.FormCloseQuery(Sender: TObject;
   var CanClose: Boolean);
 begin
   case MessageBox(Handle, PAnsiChar(USU_QUEST_SORT),
     PAnsiChar(TIT_USU_SORT), MB_YESNO+MB_ICONQUESTION+MB_DEFBUTTON2) of
     IDYES:
       CanClose := TRUE
   else
     CanClose := FALSE;
   end;
 end;
Bueno, y en el FormClose libero una clase propia que utiliza el Form y asigno al parámetro Action := caFree; . La cuestión es que no entra ni a uno ni a otro.

Si alguien me puede hechar una mao, se lo agradecería muchísimo. Porque, a parte de que es un fastidio, ya la curiosidad de saber por qué es mayor...

Pues muchas gracias por adelantado,
hasta luego.

roman 13-09-2005 01:37:36

Pare entenderlo basta examinar un poco el código de la VCL:

Por un lado el método ShowModal, a grandes rasgos, es así:

Código Delphi [-]
...
Show;
...
ModalResult := 0;
repeat
  Application.HandleMessage;
  if Application.FTerminate then ModalResult := mrCancel else
    if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;
...

Es decir, básicamente efectúa un ciclo que espera y procesa mensajes, y que no termina hasta que el valor de ModalResult sea distinto de cero.

El método Close por su parte, cuando se trata de una ventana modal, lo único que hace es poner el valor de ModalResult en mrCancel.

Por tanto, en un flujo normal, el uso de Close hace que el ciclo termine y se procede a cerrar la ventana (código que sigue al ciclo).

Ahora bien, en ShowModal, si te fijas en el código, antes de que comience el ciclo se llama al método Show. Es este método quien se encarga de llamar a tu evento OnShow, desde donde llamas a Close. Pero justo antes de comenzar el ciclo, ModalResult se inicializa a 0, de manera que poner ModelResult en mrCancel dentro de Close no tiene ningún efecto.

Moraleja: no llames a Close dentro de OnShow.

Lo lógico, al menos partiendo de lo que expones, es quitar la pregunta al usuario del formulario modal. Pregunta antes de crear el formulario, y sólo si su respuesta es afirmativa, creas y muestras el formulario:

Código Delphi [-]
with TfrmGestioUsuarios.Create(nil) do
begin
  if MessageBox(...) = IDOK then
    with TfrmGestioUsuaris.Create(nil) do
    begin
      ShowModal;
      Free;
    end;
end;

// Saludos

nowheremanza 13-09-2005 14:04:41

Pues muchas gracias...
 
Muchas gracias por tu respuesta...

La verdad es que esto que me comentas ya lo había pensado, pero como para hacer la pregunta al usuario, en el OnCreate de dicho Form Modal, hago una serie de comprobaciones (que es por eso que sale el mensaje, si no entra directamente sin mensaje ni nada), pues no quería poner todo ese código en el Principal. Pero como tú bien dices, será mejor ponerlo allí, ya que de otra forma no me será muy fácil. También estoy pensando que puedo hacerlo en el OnCreate, en vez de en el OnShow... ya lo probaré.

El problema que tengo es que estoy utilizando una versión de evaluación, :D y no puedo ver el código fuente de las Units... así que te agradezco que me hayas comentado cómo funciona el Close de un form Modal...

Hasta luego..


La franja horaria es GMT +2. Ahora son las 04:29:40.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi