Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Formulario de espera con barra de progreso (https://www.clubdelphi.com/foros/showthread.php?t=34074)

muntasil 26-07-2006 13:28:46

Formulario de espera con barra de progreso
 
Hola, mi problema, (no sé si habrá resuelto en anteriores post, aunque he estado buscando y no le he encontrado) es que necesito que se muestre un formulario con una barra de progreso a modo de espera ante un proceso de otro formulario que no se de antemano cuanto tiempo puede tardar.

Es algo parecido a enviar un correo electronico. Se pulsaría un botón y mientras se envia ese correo electrónico, para que no parezca a ojos del usuario que la aplicación se ha quedado colgada, quiero que otro form en el que se muestra un icono animado y una barra de progreso (que mediante un Timer voy incrementando y decrementando) se muestre hasta que termine de enviarse el correo.

En realidad no es que quiera enviar un correo electronico, pero es para que os hagais la idea de lo que necesitaria.

Muchas gracias de antemano.

gluglu 26-07-2006 17:10:55

Crea un nuevo formulario que sea 'Modal'.

Utiliza un procedimiento CMAfterShow (puedes buscar ayuda adicional sobre este tema en el foro).
Código Delphi [-]
private
  procedure CMAfterShow(var Msg: TMessage); message CM_AFTERSHOW;

En el evento OnShow del nuevo form deberás poner
Código Delphi [-]
procedure TForm_con_Barra.FormShow(Sender: TObject);
begin
  PostMessage(Self.Handle, CM_AFTERSHOW, 0, 0);
end;

Y en el procedimiento CMAfterShow ya ejecutas el código que quieras incrementando la barra o cualquier código que quieras ejecutar. Al final del código deberás poner Self.Close; para que cuando se termine de ejecutar tu código la ventana se cierre sola y vuelvas a la ventana que lo llamó.

Código Delphi [-]
procedure TForm_con_Barra.CMAfterShow(var Msg: TMessage);
begin
  ..
  Tu Código
  ..
  Self.Close;
end;

Al ser una ventana modal, se impedirá clickear con el ratón en ningún otro sitio más que dentro de esa ventana, y al no poner ningún botón de cierre o parecido, hasta que no finalice el proceso de tu código, la ventana con la barra no se cerrará.

Si quieres mejorarlo, puedes interceptar la tecla ESC y ejecutar un nuevo evento que cierra tu ventana con barra, y/o deberás interceptar Ctrl-F4 propio del windows para decidir que quieres hacer si el usuario quiere cerrar la ventana con la barra de progreso mientras se esté ejecutando.

Espero haberte ayudado.

Saludos

gluglu 26-07-2006 17:13:09

Se me olvidó que deberás declarar esta constante
Código Delphi [-]
const
  CM_AFTERSHOW = WM_USER + 1;
dentro del form con la barra de progreso.

muntasil 26-07-2006 22:15:16

Muchisimas gracias lo probaré y mañana te cuento.

De nuevo gracias.

Lepe 27-07-2006 11:24:53

En realidad el mensaje cmAfterShow se usa cuando se quiere hacer algo que lo impide el evento que se quiere usar, Me explico:

Si queremos ocultar una ventana en el evento OnShow, Delphi nos dirá que no podemos hacerlo, en ese caso creamos el mensaje anterior y ya podemos ocultar la ventana en el AfterShow.

En este caso, creo que se puede hacer de otra forma y ahorrarnos un mensaje.
Simplemente llamas a la rutina con ShowModal, y creas un procedimiento público en esa ventana para incrementar la barra de progreso:

Código Delphi [-]
procedure TForm1.IncPg(valor:integer);
begin
  progressbar1.position := valor;
  Form1.Update;
end;

La explicación de que guglu haya usado esa técnica creo deducir cual es:
Código Delphi [-]
procedure TForm_con_Barra.CMAfterShow(var Msg: TMessage);
begin
  progressbar1.position := valor;
  Form1.Update;// Delphi no nos deja usar esta 
//                linea en el evento OnShow (creo recordar)

end;

gluglu 27-07-2006 13:14:37

El problema que se presenta con la opción que dá Lepe es que la ventana que creas se va a quedar abierta hasta que el usuario opte por cerrarla.

Lo que entiendo que se pretende es que se cree una nueva ventana con una barra de progreso que vaya indicando algo, y que al finalizar el proceso se cierre sola.

Y el problema entonces es que en el evento OnShow (o alguno parecido) no puedes cerrar la ventana con Close, por lo que a mi entender se hace necesario el método con AfterShow.

Lepe 27-07-2006 17:34:10

Cita:

Empezado por gluglu
Lo que entiendo que se pretende es que se cree una nueva ventana con una barra de progreso que vaya indicando algo, y que al finalizar el proceso se cierre sola.

Mi intención era otra totalmente distinta.

Creas la ventana con ShowModal, con la rutina IncPg vas aumentando el ProgresBar, y cuando el proceso haya terminado, cierras la ventana por código (Yo no le pongo ni bordes ni botón de cerrar, pero siempre uso un try ..finally para que no se quede abierta en caso de excepciones).

Así no tienes que escribir código en la ventana del ProgressBar, puedes reutilizar esa ventana en todas tus aplicaciones.

muntasil 28-07-2006 09:59:46

Hola, Gracias por vuestros comentarios.

De momento la solución dada por Lepe no me sirve en este caso concreto, ya que lo que deseo es que el formulario con la barra de progreso independientemente de la tarea que se esté haciendo en el otro form, se vaya rellenando, y cuando llegue la barra al final, volvemos a empezar, así hasta que se acabe la tarea. Como veis, la barra de progreso se va rellenando, no tiene mucho en cuenta el tiempo estimado en terminar la tarea, pero por lo menos parece que se están haciendo operaciones.
El problema de hacerlo como dice Lepe, está en que una sentencia (una llamada a una dll que envia un xml y recibe otr xml de respuesta) no sé cuanto tiempo puede tardar, y lo de ir aumentando la barra de progreso en este caso se quedaria "parada" hasta terminar la tarea, de forma que seguiria pareciendo que la aplicacion se queda colgada.

En cuanto a la solucion de Gluglu, tambien la he probado y no me funciona correctamente, me aparece el formulario de la barra de progreso pero está estático.

De momento he optado por mostrar un mensaje fijo en un formulario a modo de mensaje, cuando vuelva de vacaciones volveré a pensar en alguna alternativa para hacerlo.

Quizás seria conveniente hacerlo mediante un hilo (THread)???

Saludos a todos y buen verano.

Lepe 28-07-2006 12:03:52

Busca en Torry.Net, seguro que encuentras una barra de progreso indefinida (como al iniciarse Windows) nunca se llena, solo pasa de izquierda a derecha 3 rayitas.

Incluso un Gif Animado podría servirte.

Saludos

gluglu 28-07-2006 12:27:38

Dos cosas quiero comentar :

Para muntasil preguntarle si no se le ha olvidado incluir Application.ProcessMessages; en el bucle de aumento de la barra, porque si no lo incluyes la barra nunca aumentará.

Y para Lepe estamos de acuerdo que queremos hacer lo mismo. Yo tampoco le pongo borde ni botón de cierre. Y también cierro la ventana por código. Mi pregunta es ¿donde se cierra esa ventana por código? porque precisamente esa es la problemática.

Si quieres que un proceso se active automáticamente al crear la ventana tienes que poner el código en algún evento tal como el OnShow, y ahí en dicho evento no puedo incluir el cierre del Form por código, porque no me lo permite.

Me gustaría en dicho caso saber donde incluyes el código de cierre ?

Saludos

muntasil 28-07-2006 12:32:07

Si que le pongo el application.processmesage.
Lo deseable es un formulario que me sirviera para cualquier tipo de espera, por eso no me gustaria tener que escribir el codigo de la tarea (el envio xml) en el formulario de la barra de progreso.

gluglu 28-07-2006 12:33:16

Volví a leer de nuevo el hilo, y acabo de darme cuenta de lo que Lepe pretende !!

Ya lo entendí, él crea una venta con la barra de progreso y la incrementa desde el form desde el que llamo al form de la barra de progreso ... :rolleyes:

No lo había entendido hasta ahora ...

Claro, son dos cosas diferentes. Ya quedará a la elección de cada uno elegir lo que más le convenga. :D

gluglu 28-07-2006 12:36:31

Pero el incremento de la barra de progreso tiene que ir en función de algún parámetro ?

Porque si no es así, entiendo que el código que escribas en el formulario que contenga la barra sólo debe de ser para hacer un incremento de la misma, que junto con Application.ProcessMessages debe de funcionar de manera independiente.

muntasil 28-07-2006 12:40:25

El incremento solo debe depender de un Timer que cada x tiempo incrementa la barra hasta el final y vuelve al principio hasta que la tarea termine.

Será una tonteria pero como no cree el form de la barra en Modal, la barra de progreso no aumenta. Y claro si es modal, tendria que cerrarla el usuario. Algo estaré haciendo mal, pero no doy con ello.

gluglu 28-07-2006 12:46:56

Yo ciertamente creo mi ventana en modo Modal. No puedo decirte ahora mismo si en modo No Modal la barra de progreso se incrementa o no.

Pero el modo Modal no implica que sea el usuario quien tenga que cerrala. De hecho yo la cierro por código, pero en este caso mediante el método que expresé anteriormente.

Lepe 28-07-2006 19:36:04

Código Delphi [-]
  Application.ProcessMessages;
  if not ExisteFrm(Frminformacion) then
    frminformacion := tfrminformacion.Create('Buscando Facturas de Importe menor a: 2 € :P',
                                                             '',
                                                             oShowProgress,
                                                             query1.RecordCount);
try
  //  Lo que debe hacer esta rutina.. un bucle y poco más
  Frminformacion.Info(objFactura.NFactura); //actualizo un label 
  Frminformacion.StepIt; // actualiza el ProgressBar en una posición
finally
    FreeAndNil(Frminformacion);
end;

Y la forma frmInformacion:
Código Delphi [-]
constructor TFrminformacion.Create(const Titulo: String; const informacion: String;
      const Opciones: TOptions = []; const MaxProgressValue:Integer = 100);
begin

  inherited Create(NIL);
  lblTitulo.Caption      := Titulo;
  lblinformacion.Caption := informacion;

  pnlCancel.Visible   := (oShowCancel in Opciones);
  pnlProgress.Visible := (oShowProgress in Opciones);
  Progessbar1.Max   :=MaxProgressValue;
  Self.AutoSize       := True;

  Show;
  Update;
end;

La forma no es Modal, porque entonces el programa se queda esperando en esta ventana, y el código que debe ejecutarse ¡¡no se ejecuta!!

La ventana FrmInformacion tiene el estilo fsStayOnTop, y la ventana que queda por detrás, suelo inhabilitarla (FormX.Enabled := false)

Creo que ahora si se entiende mucho mejor.

Saludos

Lepe 28-07-2006 19:43:21

Cita:

Empezado por gluglu
Pero el modo Modal no implica que sea el usuario quien tenga que cerrala. De hecho yo la cierro por código, pero en este caso mediante el método que expresé anteriormente.

Pero si implica que el programa se queda esperando hasta que se cierre, así que no realiza las tareas mientras se esté mostrando.

Saludos

ColdFusion 09-02-2009 20:05:59

hola disculpen que pregunte esto aqui pero mi pregunta es como puedo hacer un formulario independiente de la aplicacion, es decir cuando lo doy clic al formulario q se minimice el solo y no tada la aplicacion.

cuando uso self.windowstate:= wsminimized;
si minimiza el el solo pero no ala barra de tares si no que arriba..

como puedo hacer q se minimize solo ala barra dee tareas sin minimizar todos los otros formularios...


La franja horaria es GMT +2. Ahora son las 16:25:24.

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