Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 12-05-2005
Avatar de Aura
Aura Aura is offline
Miembro
 
Registrado: mar 2004
Ubicación: Veracruz, Ver., México
Posts: 43
Poder: 0
Aura Va por buen camino
Question Cerrar una ventana desde otra

Hola, a todos , estoy utilizando delphi 6, Database desktop y las tablas en paradox. Gracias por la atención que me prestan, estoy desarrolando un sistema en el se cual manejan formas FsNormal y FsMDIChild, entonces estoy en una forma (ventana1) FsMDIChild y mando a llamar una(ventana2) FsNormal, estoy utilizando timers para que se despliegue esta y otra ventana tambien (Ventana3)FsNormal cada determinado tiempo cada una. El problema esta en que si desde la Ventana1 se llama la Ventana2 todo bien, si mientras esta cerrada la Ventana2 se despliega la Ventana3, todo sigue trabajando correcto, pero si mientras esta desplegada la Ventana2 y se llama la Ventana3, no logro cerrar la ventana2 y marca error al volver mandarla a llamar... espero haberme explicado... mi pregunta es ¿alguien sabe como cerrar una ventana FSNormal desde una FsMDIChild?, muchas gracias de antemano...
__________________
----------------->> Saluditos <<-----------------
Responder Con Cita
  #2  
Antiguo 12-05-2005
PeLuCa PeLuCa is offline
Miembro
 
Registrado: abr 2005
Posts: 20
Poder: 0
PeLuCa Va por buen camino
Una Prueba

Hola, has probado con CloseWindow(handle de la ventana que quieres cerrar).
Chau Saludos.
Responder Con Cita
  #3  
Antiguo 12-05-2005
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.271
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
¿Puedes poner algo de código? El que utilizas para mostrar las ventanas. Eso tal vez ayudaría.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 12-05-2005
Avatar de Aura
Aura Aura is offline
Miembro
 
Registrado: mar 2004
Ubicación: Veracruz, Ver., México
Posts: 43
Poder: 0
Aura Va por buen camino
Exclamation mas dudas...

hola gracias por la ayuda , el CloseWindow nunca lo he usado pero hice la prueba segun con lo que entendi, pero sigo teniendo el mismo error:

Código:
Project NRC.exe raised exception class EInvalidOperation with message 
'Cannot make a visible window modal1. Process stopped. use Step or Run to 
continue
El código lo tengo de la siguiente manera:
Código:
unit UMenu;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
...
...
procedure TFMenu.pendientes(Sender: TObject);
begin
	MTabla.QComodin.Close;
	if ((varcon = 'S')OR(varresp = 'S') OR (varver = 'S') OR (varimp = 'S')) THEN
	begin
	   FMensaje11.ShowModal;
	end
end;
procedure TFMenu.RelojTimer(Sender: TObject);
begin
	//******************************************
	//***mandara mensaje de si hay pendientes  cada 20 segundos
	//*******************************************
	Mtabla.Session.Close;
	pendientes(Sender);
end;
 
procedure TFMenu.reloj2Timer(Sender: TObject);
begin
	 //******************************************
	 //***cerrara sesion en determinado momento  cada 40 segundos
	 //*******************************************
	 Mtabla.Session.Close;
	 if (reloj.Enabled = false) then   //aqui confirmo que este desplegada
						  //en pantalla la forma FMensaje11
	  FMensaje11.close; //aqui indico que quiero se cierre la forma
	  //closeWindow(FMensaje11.Handle);  // tambien lo intente con esta 
							//instrucción y nada
	 
	 FSeguridad.ShowModal;   // aqui mando a llamar otra y cuando cierro esta
						//se hace un llamado al proceso Pendientes
end;
He visto la instrucción
Código:
FMensaje11.FormClose()
pero realmente no se que parámetros son los que lleva... espero esto explique mejor mi problema muchas gracias por el tiempo y la ayuda
__________________
----------------->> Saluditos <<-----------------
Responder Con Cita
  #5  
Antiguo 13-05-2005
PeLuCa PeLuCa is offline
Miembro
 
Registrado: abr 2005
Posts: 20
Poder: 0
PeLuCa Va por buen camino
Otra Prueba

Aura, colocando la propiedad ModalResult en un valor distinto de cero. Es decir, cambiar el Fmensaje1.close; por FMensaje1.ModalResult=1;
Prueba con esto haber si te funciona. Saludos.
Responder Con Cita
  #6  
Antiguo 13-05-2005
Avatar de Aura
Aura Aura is offline
Miembro
 
Registrado: mar 2004
Ubicación: Veracruz, Ver., México
Posts: 43
Poder: 0
Aura Va por buen camino
sigo probando

pues nada, puse el modalresult = 1; en lugar de FMensaje11.close puse FMensaje11.modalresult := 1 y me sigue marcando el mismo error.... mil gracias por el tiempo que toman en ayudarme.
__________________
----------------->> Saluditos <<-----------------
Responder Con Cita
  #7  
Antiguo 13-05-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Este código es demasiado enredado y obscuro como para poder confiar en él aun en el supuesto de que logres resolver este problema específico.

Es de suponerse que el error te lo marca por intentar abrir una ventana modal que nunca se cerró. En reloj2Timer comentas que confirmas que FMensaje1 está abierta e intentas cerrarla. Pero no se ve claro en absoluto que la condición que usas (reloj.Enabled = false) realmente determine si la ventana está abierta. ¿Has intentado poner un punto de corte en la línea que cierra la ventana para saber si efectivamente el flujo del código llega a ese punto?

Quizá si nos explicas- esta vez sin código ni tecnicismos, pero claramente -cuál es la idea que persigues, podamos sugerirte alguna forma de desarrollar tu idea.

Visto así nada más, tratado de abstraer lo que quieres, parece que deseas desplegar una ventana modal cada x tiempo y el problema surge cuando dicha ventana ya está abierta. Entonces necesitas una manera fiable de determinar si está o no abierta.

Para ello podrías usa una bandera (alguna variable booleana) que pones a true al momento de mostrar la ventana y a false al momento de cerrarla. En el timer usarías esta bandera para ver si tienes que cerrar la ventana.

Pero como te digo, será mejor que tú misma nos aclares cuál es el objetivo.

// Saludos
Responder Con Cita
  #8  
Antiguo 13-05-2005
Avatar de Aura
Aura Aura is offline
Miembro
 
Registrado: mar 2004
Ubicación: Veracruz, Ver., México
Posts: 43
Poder: 0
Aura Va por buen camino
Smile mejorando

hola muchas gracias por la ayuda y el tiempo que me han dedicado. Aviso que al parecer he encontrado la solución, reemplace la instrucción FMensaje11.ShowModal por FMensaje11.Show con esto ha dejado de marcarme el error, seguire haciendo pruebas.
Aun asi tratare de explicar que es lo que quiero conseguir:
Tengo una ventana de logueo (Ventana A) la cual confirma el login y contraseña de los usuarios, al permitir el acceso al sistema despliega la pantalla del menú (Ventana B) y revisa que ese usuario no tenga pendientes por revisar, de tenerlos despliega un aviso (Ventana C).
La ventana C se manda a llamar por medio de un timer(reloj) cada X tiempo desde la ventana B, la cual siempre esta desplegada, y si no esta abierta ninguna otra ventana del sistema, esto para estar refrescando los pendientes que tiene el usuario.
La ventana A es desplegada con otro timer(reloj2) cada X2 tiempo tambien desde la ventana B, es decir, si el usuario tiene abierto el sistema pero lleva mucho tiempo sin realizar ninguna tarea en él deberá loguearse nuevamente por el tipo de información que utiliza.
Ahora como estaba se desplegaba la Ventana C y si el usuario la cerraba inmediatamente todo el proceso seguía norma, se podía ver la Ventana C y la Ventana A cerrando cada una en el momento en que se desplegaban.
Pero si se desplegaba la Ventana C y no la cerraba el usuario, al momento de desplegarse la Ventana A por codigo se mandaba cerrar la Ventana C, aqui el problema la siguiente vez que se llamaba la Ventana C marcaba el error.
Espero haber sido clara con lo que quiero lograr y que el cambio realmente me funcione.

Muchas muchas gracias por el tiempo y la ayuda gracias gracias gracias
__________________
----------------->> Saluditos <<-----------------

Última edición por Aura fecha: 13-05-2005 a las 18:59:55.
Responder Con Cita
  #9  
Antiguo 14-05-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Hola,

Ya entiendo lo que quieres hacer y por qué. No estoy seguro de que sea la mejor forma. Quizá podrías dejar un Memo o algo por el estilo fijo dentro de tu formulario principal para mostrar los mensajes pues creo que tantas ventanas apareciendo de improviso pueden resultar disturbantes para el usuario. El memo lo irías actualizando conforme se generen nuevos avisos.

De cualquier forma estuve haciendo varias pruebas y creo que he encontrado la solución. Sé dónde está el problema aunque no me queda muy claro el porqué.

Vamos a fijar ideas. Llamemos MenuForm al formulario menú, LoginForm al formulario del login y AvisosForm al formulario de avisos.

En MenuForm hay dos timer, TimerMenu y TimerAvisos para controlar cuándo se muestran los respectivos formularios.

Según entiendo, AvisosForm sólo debe mostrarse si LoginForm no está activado ya que primero debe hacerse el login, y LoginForm debe cerrar el de avisos antes de mostrarse.

Entonces, un primer intento sería:

Código Delphi [-]
procedure TimerLoginTimer(Sender: TObject);
begin
  if not LoginForm.Visible then
  begin
    AvisosForm.Close;
    LoginForm.ShowModal;
  end;
end;

procedure TimerAvisosTimer(Sender: TObject);
begin
  if not AvisosForm.Visible and not LoginForm.Visible then
    AvisosForm.ShowModal;
end;

Es decir, LoginForm se muestra sólo si no está ya visible y en tal caso cierra AvisosForm (no hace falta verificar si AvisosForm está abierto ya que no vamos a destruir ninguna ventana, sólo ocultarlas, de manera que Close no afecta en caso de que AvisosForm estuviera ya cerrada).

Y AvisosForm se muestra sólo si no está ya abierto y si en esos momentos no está abierto LoginForm.

Tal como está el código me parece que no presenta errores ya que las verificaciones de visibilidad evitan que se use ShowModal sobre un formulario ya abierto.

Sin embargo, como ya lo notaste tú, AvisosForm.Close no parece funcionar, el formulario no se cierra sino hasta después de que se cierra LoginForm.

Dada la naturaleza de la aplicación que describes, supongo que es deseable o indispensable que AvisosForm se cierre cuando el sistema se suspenda por falta de actividad y se muestre LoginForm.

¿Cuál es el problema?

La llamada a AvisosForm.Close sí funciona pero en forma "retardada" y sólo tiene efecto hasta que se cierra LoginForm. Esta es la parte que no entiendo del todo pero tiene que ver con la forma en que se procesan los mensajes cuando se muestra una ventana modal.

Normalmente, toda la aplicación se ejecuta dentro de un bucle:


Código:
repeat
  PeekMessage;
  ProcessMessage;
until Application.Terminate;
Como quizá sepas, en Windows todo funciona mediante mensajes que se mandan a las aplicaciones. Toda actividad de teclado y ratón se manda en forma de mensajes a las aplicaciones y toda aplicación Windows consta de un blucle similar al anterior:

toma mensaje -> procesa mensaje

Así hasta que termine la aplicación.

Pero en Delphi, el comportamiento modal de una ventana se logra haciendo que la ventana misma maneje la cola de mensajes. El método ShowModal básicamente reintroduce un bucle como el de arriba hasta que el valor de ModalResult sea distinto de 0.

Es decir, la ventana modal inhibe el flujo normal de los mensajes; en lugar de que éstos sean procesados por el bucle principal de la aplicación, ella misma los procesa.

Entonces, en

Código Delphi [-]
procedure TimerLoginTimer(Sender: TObject);
begin
  if not LoginForm.Visible then
  begin
    AvisosForm.Close;
    LoginForm.ShowModal;
  end;
end;

la llamada a ShowModal impide que se procesen todos los mensajes que normalmente culminan en el cierre de AvisosForm y sólo se procesan hasta que LoginForm se cierra y se devuelve el conrol al bucle de la aplicación.

Era de esperarse entonces que una llamada intermedia a Application.ProcessMessages:

Código Delphi [-]
procedure TimerLoginTimer(Sender: TObject);
begin
  if not LoginForm.Visible then
  begin
    AvisosForm.Close;

    Application.ProcessMessages;

    LoginForm.ShowModal;
  end;
end;

hubiera bastado ya que ProcessMessages procesa todos los mensajes pendientes y no devuelve el control hasta que termina con todos.

Pero no. El formulario sigue sin cerrarse.

Esto es lo que no me queda claro. Pero puede solucionarse "retardando" la llamada a LoginForm.ShowModal.

Para ello deberás mandar un mesaje personalizado al formulario:

Código Delphi [-]
procedure TimerLoginTimer(Sender: TObject);
begin
  if not LoginForm.Visible then
  begin
    AvisosForm.Close;
    PostMessage(Handle, CM_CLOSEAVISOS, 0, 0);
  end;
end;

y postergar la llamada a LoginForm.ShowModal en el manejador del mensaje:

Código Delphi [-]
const
  // mensaje personalizado
  CM_CLOSEAVISOS = WM_USER + 100;

type
  TMenuForm = class(TForm)
  private
    // manejador del mensaje CM_CLOSEAVISOS
    procedure CMCloseAvisos(var Msg: TMessage); message CM_CLOSEAVISOS;
  end;

implementation

procedure TMenuForm.CMCloseAvisos(var Msg: TMessage);
begin
  LoginForm.ShowModal;
end;

¡Y listo! Ahora parece funcionar todo correctamente. La ventana de avisos se cierra cuando se muestra la del Login.

Sugerencia:

Los timer más que manejar el tiempo en que se muestran las ventanas, deberían simplemente tomar nota de cuánto tiempo ha pasado desde la última vez que se abrió una de ellas llevando la cuenta de este tiempo aparte y reinicializándolo cada vez que se cierren. De lo contrario, el tiempo en que se muestran es confuso. Por ejemplo, dependiendo de qué tanto tiempo se haya mantenido abierta LoginForm pudiera ser que al cerrarla el timer la volviera a mostrar inmediatamente.

// Saludos
Responder Con Cita
  #10  
Antiguo 16-05-2005
Avatar de Aura
Aura Aura is offline
Miembro
 
Registrado: mar 2004
Ubicación: Veracruz, Ver., México
Posts: 43
Poder: 0
Aura Va por buen camino
Thumbs up listo

muchisimas gracias, he probado el procedimiento que describes y funciona perfecto y como mencionas suena y se ve mejor que poner un Show en lugar del Showmodal. Mando a llamar las ventanas de todas las formas posibles y no genera ningun error, además gracias por la explicación del proceso de los mensaje ya que yo creía que si se llegaba a terminar el llamado antes de bloquear con el siguiente , lo de los timer si lo estoy manejando de esa manera cada vez que se hace un llamado se reinician, en fin mil gracias por tu ayuda y tiempo ...
__________________
----------------->> Saluditos <<-----------------
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 00:35:22.


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
Copyright 1996-2007 Club Delphi