Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Un Close pasota.... (https://www.clubdelphi.com/foros/showthread.php?t=59484)

JoysticK 28-08-2008 17:12:49

Un Close pasota....
 
Pues tengo un problemita con un Close un tanto pasota, la cosa es que llamo a un formulario mediante Formulario.ShowModal; y en el OnActivate de este unas cuantas lineas de codigo y cuando termina esas lineas quiero que cierre ese formulario, intento meterle un Close; pero como que no me hace ni caso...

Si utilizo el OnShow, empieza a correr las lineas de codigo pero no da tiempo ni a dibujarse el formulario asi que no veo que es lo que esta haciendo hasta que ya ha terminado.... Alguna sugerencia ?

Delphius 28-08-2008 17:22:28

Cita:

Empezado por JoysticK (Mensaje 309970)
Pues tengo un problemita con un Close un tanto pasota, la cosa es que llamo a un formulario mediante Formulario.ShowModal; y en el OnActivate de este unas cuantas lineas de codigo y cuando termina esas lineas quiero que cierre ese formulario, intento meterle un Close; pero como que no me hace ni caso...

Si utilizo el OnShow, empieza a correr las lineas de codigo pero no da tiempo ni a dibujarse el formulario asi que no veo que es lo que esta haciendo hasta que ya ha terminado.... Alguna sugerencia ?

Hola JoysticK,
Primeramente, el título no es muy adecuado. ¿Qué significa pasota?

Con respecto a tu duda ¿Porqué en el OnActivate? Me parece, por lo que describes, que sería apropiado el evento OnCreate talvez. Si nos pudieras comentar más al respecto podríamos asesorarte mejor. ¿que hacen esas dichosas lineas de código?

Por otro lado, un Form de forma modal no tiene demasiado sentido si va a cerrarse en forma automática. Por lo general se brinda esta opción para permitir al usuario la obligatoriedad de realizar alguna acción e impedirle realizar otras hasta que no "confirme" su pedido.

Saludos,

Caro 28-08-2008 18:29:36

Hola JoysticK, puedes hacerlo de la forma que explica Neftali en este hilo http://www.clubdelphi.com/foros/showthread.php?t=58890 . Solo por curiosidad que significa pasota.

Saluditos

JoysticK 28-08-2008 18:41:29

Hola Delphius, lo siento jeje, pasota significa.... revelde podria ser.....

La cosa es la siguiente, mi aplicacion abre el formulario principal, mira si existen actualizaciones, si existen abre el formulario sincroniza mediante un showmodal para que no haga nada mas hasta que no se descargue todas las actualizaciones, el sincroniza se conecta a la base de datos y empieza a recorrer un loop hasta que todos los registros han sido descargados que es el momento de enviar un mensje y un close para que se cierre el sincronizay continue la aplicación normal...

Si pondo el codigo en el FormCreate, el codigo se ejecuta pero el formulario no se dibuja y no veo los mensajes que devuelve a un Memo que le he puesto, si lo pongo en el OnShow tampoco se llega a dibujar el formulario y estoy utilizando Application.precessmesage cada vez que recore el loop...


P.D. Aqui la definición de "pasota": 1. adj. col. [Persona] generalmente joven que rechaza las normas o principios de la sociedad establecida,adoptando una postura de total desinterés.
Se suele escuchar bastante por aqui por Andalucía jeje

roman 28-08-2008 19:12:28

En mi opinión, el proceso de actualización debería hacerse desde el formulario principal, dejando el otro sólo para mostrar el grado de avance. Yo procedería mas o menos así (desde el formulario principal):

Código Delphi [-]
Self.Enabled := false;

frmAvanceActualizacion.ProgressBar.Max := NumeroDeRegistros;
frmAvanceActualizacion.Step := 1;
frmAvanceActualizacion.Show; // obsérvese que no es ShowModal
frmAvanceActualizacion.Refresh; // forzamos el pintado de la ventana antes del ciclo

while ... do
begin
  {
    código de actualización
  }

  frmAvanceActualizacion.ProgressBar.StepIt;
end;

frmAvanceActualizacion.Close;
frmAvanceActualizacion.Enabled := true;

Aquí, frmAvanceActualizacion sustituiría a Sincroniza y sólo tendría un ProgressBar y algún mensajito.

No podemos usar ShowModal porque entonces no se ejecutaría nada hasta no cerrar el formulario, pero impedimos la interacción con el formulario principal ponieno Enabled := false.

// Saludos

Lord Delfos 28-08-2008 20:37:49

Bueno... O yo estoy más inteligente de lo normal, o los demás están medio dormidos...:rolleyes:

Pero, digo, se me ocurre. ¿Con un Form.Refresh? Ponerlo como primera línea del OnActivate, digo, antes de empezar a hacer cualquier cosa.

PD: Ésta es una de esas situaciones raras en las que uno piensa: "No puedo tener razón, algo tengo que haber entendido mal."

roman 28-08-2008 21:03:45

¿Has probado lo que propones? Recuerda que el amigo necesita cerrar el formulario luego de terminado el proceso.

// Saludos

Lord Delfos 28-08-2008 22:30:06

Sí... Me parece que no entiendo bien lo que quiere hacer, entonces.

Lo que yo digo es que si va a mostrar el formulario, hacer una serie de cosas pesadas y después cerrarlo. Porqué no hacer un refresh o repait del formulario después de mostrarlo y antes de empezar a hacer las cosas pesadas.

Digo, eso es los que yo he hecho siempre.

Por eso aclaro, quizá yo esté entendiendo mal el asunto...

Delphius 28-08-2008 22:35:06

Tuve que ausentarme unas horas.
Tras leer lo que se vino diciendo aqui, yo estoy con roman.
El form principal es que quien se encarga de hacer el trabajo duro. Hacer que el form modal haga ese trabajo rompe con el esquema para el cual fueron concebidos: pedir una "confirmación" rápida.

Saludos,

TOPX 28-08-2008 22:44:42

Ahora yo.

El Close no tiene efecto en el onActivate, porque la forma modal no ha entrado en el ciclo que hace HandleMessage. Pues, como exponen los compañeros del foro, por definición las formas modales no están para comportarse así.

De todas maneras y según entiendo, hay dos opciones prácticas para "forzar" esto, que a la larga pueden ser similares, pero Ud. escoge:
  1. Crear un Hilo que esté modificando la propiedad ModalResult, para que apenas termine el onActivate, se cierre.
  2. Añadir un Timer que en su evento onTimer esté verificando que el proceso ya acabó, para que entonces modifique la propiedad ModalResult.

roman 29-08-2008 00:58:08

Cita:

Empezado por TOPX (Mensaje 310057)
El Close no tiene efecto en el onActivate, porque la forma modal no ha entrado en el ciclo que hace HandleMessage.

¡Exacto! ShowModal implementa su propio ciclo de mensajes en lugar del de la aplicación:

Código Delphi [-]
function TCustomForm.ShowModal: Integer;
begin

  ...

    Show;
    try
      SendMessage(Handle, CM_ACTIVATE, 0, 0);
      ModalResult := 0;
      repeat
        Application.HandleMessage;
        if Application.FTerminate then ModalResult := mrCancel else
          if ModalResult <> 0 then CloseModal;
      until ModalResult <> 0;
      Result := ModalResult;
      SendMessage(Handle, CM_DEACTIVATE, 0, 0);
      if GetActiveWindow <> Handle then ActiveWindow := 0;
    finally
      Hide;
    end;

  ...
end;

La llamada a Show generará el evento OnShow mientras que el mensaje CM_ACTIVATE generará el evento OnActivate, antes de entrar al ciclo repeat-until, como bien señala nuestro amigo TOPX. Ese ciclo sólo termina cuando el valor de ModalResult es distinto de cero y aunque Close lo que hace es poner ModalResult en mrCancel (<> =0), lo hace antes de la inicialización a cero de la variable justo antes de comenzar el ciclo.

Ahora bien, si se insiste en dejar el proceso de descarga en el formulario modal, entonces pueden usar el método del AfterShow. Aquí un ejemplo:

Código Delphi [-]
const
  CM_AFTERSHOW = WM_USER + 1;

type
  TForm2 = class(TForm)
    ProgressBar1: TProgressBar;
    procedure FormShow(Sender: TObject);

  private
    procedure CMAfterShow(var Msg: TMessage); message CM_AFTERSHOW;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormShow(Sender: TObject);
begin
  PostMessage(Handle, CM_AFTERSHOW, 0, 0);
end;

procedure TForm2.CMAfterShow(var Msg: TMessage);
begin
  Refresh;

  { Código para descargar }

  Close;
end;

PostMessage coloca un mensaje en la cola de mensajes de la aplicación, que no se procesará sino hasta que -justamente- se entre al ciclo de mensajes y HandleMessage lo tome.

Trasladamos entonces, todo el proceso al manejador del mensaje que mandamos, en donde ya se puede usar Close sin ningún problema.

// Saludos

JoysticK 29-08-2008 02:14:33

Uff bastante información me habeis reportado, creo que voy a necesitar reflexionar un poco para comprender todo lo expuesto y actuar en consecuencia, aunque lo mas facil que veo es la primera opcion, dejar el trabajo duro al formulario princial como dice roman... es lo mas facil aunque me entran ganas de investigar todo lo que me habeis expuesto como el aftershow que no conocia hasta ahora...

Voy a investigar un poco y os cuento, muchas gracias por vuestra ayuda, ya he aprendido otra cosa más hoy :D


La franja horaria es GMT +2. Ahora son las 22:04:25.

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