Ir al contenido


Foto

Sobre formularios modales


  • Por favor identifícate para responder
9 respuestas en este tema

#1 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 16 septiembre 2010 - 02:37

hola amigos del foro, tengo mi formulario principal, desde el formulario pricipal llamo a varios form de forma modal, pero al minimizar un form modal este no devuelve el foco de la aplicacion hasta cerrar el form, ¿es posible hacer que al minimizar devuelva el foco al form main y al maximizar el form modal  se vuelva de forma modal?
espero sus comentarion. saludos! (y)
  • 0

#2 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 16 septiembre 2010 - 02:56

Quizás lo que buscas es un formulario no modal.

Saludos.
  • 0

#3 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 16 septiembre 2010 - 03:41

Quizás lo que buscas es un formulario no modal.

Saludos.

Nop, necesito uno que sea modal, el problema con los forms normales es que si das click fuera de el, este se queda atras de la ventana que seleccones, podria ponerle fsStayOnTop pero no es el efecto que quiero lograr, gracias
  • 0

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 16 septiembre 2010 - 04:02

El punto look es precisamente que ese es el comportamiento esperado en los forms no modales.
Se supone que un form o ventana modal está hecha para emitir avisos e impedir regresar el "foco" si no es hasta una confirmación (sea positiva o negativa) por parte del usuario.
Un form modal NO debería porqué tener la posibilidad de minimizarse. No está pensado para ello.

Quizá si nos platicas más al respecto podríamos ver en que y como asesorarte. No te enojes si te digo que estoy con escafandra y hay por allí un pequeño error de diseño.

Saludos,
  • 0

#5 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 16 septiembre 2010 - 04:11

veran compañeros, solo estoy experiemientando, mi forma favorita de trabajar es con forms mdi, pero queria experimientar algo, mi idea es que, por ejmplo abro mi form de facturacion en forma modal, de este modo no puedre utilizar las otras funciones del menu principal hasta minimizar este form, entonces , para poder abrir otro form como decir... el form de pedidos, minimizaria el de facturacion y este me dejaria darle click al menu principal para abrir el form de pedidos, este tambien seria de forma modal, es con eso lo que quiero jugar, pero solo estoy experimentando haber que sale...
saludos!  (y)
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 16 septiembre 2010 - 04:24

Allí está el tema look, NO SE PUEDE tener el control sobre el principal, sino es hasta CERRAR la ventana Modal.
Del mismo modo, se se tiene una colección de ventanas modales abiertas, para volver a tener el control deben irse cerrando en el orden inverso.

Si lo que buscas es impedir trabajar en una ventana mientras se esté en otra con "foco" y a la vez que se permita volver al principal para abrir más ventanas. Entonces tus forms deben ser no modales.

Luego debes implementar un mecanismo para llevar el control y el orden de creación/visualización de ventanas abiertas. Esto está ya medianamente implementado: la variable global Application mantiene un array con la ventanas abiertas, e incluso se puede obtener la ordenada Z (es la que da el orden) de cada form.

En segundo lugar este mecanismo se debe vincular a otro que se encargue de deshabilitar todo contro, y operación en las ventanas cuyo Z no corresponda a la ventana actualmente en foco.

De este modo cada vez que se vuelva al form principal (el único que no se vería afectado por este mecanismo de deshabilitado/habilitado) y se cree una nueva ventana la última en tener el foco pase a estar deshabilitada.

Luego, por más que se ponga el foco en las ventanas ya abiertas no tendrían los controles y funciones habilitadas. Deben irse cerrando las ventanas en orden inverso.

¿Se entiende?

Saludos,
  • 0

#7 look

look

    Advanced Member

  • Miembros
  • PipPipPip
  • 418 mensajes
  • LocationLa Ceiba-Atlantida-Honduras

Escrito 16 septiembre 2010 - 04:44

Allí está el tema look, NO SE PUEDE tener el control sobre el principal, sino es hasta CERRAR la ventana Modal.
Del mismo modo, se se tiene una colección de ventanas modales abiertas, para volver a tener el control deben irse cerrando en el orden inverso.

Si lo que buscas es impedir trabajar en una ventana mientras se esté en otra con "foco" y a la vez que se permita volver al principal para abrir más ventanas. Entonces tus forms deben ser no modales.

Luego debes implementar un mecanismo para llevar el control y el orden de creación/visualización de ventanas abiertas. Esto está ya medianamente implementado: la variable global Application mantiene un array con la ventanas abiertas, e incluso se puede obtener la ordenada Z (es la que da el orden) de cada form.

En segundo lugar este mecanismo se debe vincular a otro que se encargue de deshabilitar todo contro, y operación en las ventanas cuyo Z no corresponda a la ventana actualmente en foco.

De este modo cada vez que se vuelva al form principal (el único que no se vería afectado por este mecanismo de deshabilitado/habilitado) y se cree una nueva ventana la última en tener el foco pase a estar deshabilitada.

Luego, por más que se ponga el foco en las ventanas ya abiertas no tendrían los controles y funciones habilitadas. Deben irse cerrando las ventanas en orden inverso.

¿Se entiende?

Saludos,

entiendo, gracias por tus comentarios.
  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 16 septiembre 2010 - 05:03

Me alegro que se entienda... Eso en palabras es fácil, ahora el dilema es traducirlo a Delphi  :D .... todavía estoy pensando en como llevarlo  práctica  :p

El punto es que se debe centralizar la creación y visualización de las ventanas en un punto. Y a su vez, cada ventana debe ser capaz de comunicarse con este mecanismo para que este "actualize" el estado general del listado de todos los forms.

En términos abstractos, a mi modo de ver es un caso práctico del principio de "clases amigas" con cardinalidad 1-* (una composición). Puedes ver en acción este principio en TParam y TParans. TParam es una colección de TParams. TParam asume el control de su colección de TParams y se establecen vínculos entre una y otra mandándose mensajes y sincronizandose mutuamente.
Otro posible enfoque que podría ponerse en debate, es la aplicación del patrón Observador; aunque tengo mis reservas si es el caso.

Saludos,
  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 16 septiembre 2010 - 06:16

Hola,
He aquí mi primer acercamiento al tema,

Se cuenta con una clase TAdministradorDeVentanas. Esta clase tendría en forma privada una lista de los forms que se vayan creando y liberando. Algo así:



delphi
  1. TAdministradorDeVentanas = class;
  2. private
  3.   ListaDeVentanas: TObjectList; // o cualquier "List" podría servir
  4. ...
  5. end;



Entre sus obligaciones está de indicar a sus ventanas cual ha de Habilitar y Deshabilitar. Por tanto ya tenemos dos posibles métodos.


delphi
  1. procedure HabilitarVentana(OrdenZ: integer);
  2. procedure DesHabilitarVentana(OrdenZ: integer);



Te preguntarás porqué trabajar con el número de orden Z y no directamente con la ventana en cuestión. Fácil: Me independizo de estar trabajando con algunas clases puntuales (esto permite que existan muchas posibles clases y no algunos TForm* en particular) y además las ventanas no saben (ni les interesa) saber si existen otras ventanas.

Al disponer de este Z podemos asociarlo con el valor Index del array de ListaDeVentanas. De modo que con esto nos posicionamos en la ventana en cuestión.

Las implementaciones podrían ser cosas como:



delphi
  1. procedure TAdministradorDeVentanas.HabilitarVentana(OrdenZ: integer);
  2. begin
  3.   TObject(ListaDeVentanas[OrdenZ]).EventoHabillitar;
  4. end;



Estos métodos (Habilitar/Deshabilitar) mandarían un mensaje que todas las clases entenderían... Para ello se puede disponer del uso de evento. Es decir, ambos métodos disparan el método y esto a su vez permite que cada ventana tenga su propia implementación para el habilitado y deshabilitado.



delphi
  1. TEventoHabilitar= procedure (...) of Object;
  2. TVeventoDeshabilitar = procedure (...) of Object;



Entonces cada Form tendría sus métodos y respuestas propios para el mismo evento.

¿Que otra cosa hace falta? Relacionar las ventanas con este Administrador. No necesariamente el Administrador debería ser el crea las ventanas, pero si el encargado de registrarlas. Por tanto debería tener un método para tal fin:



delphi
  1. procedure TAdministradorDeVentanas.RegistrarVentana(Ventana: TObject*, OrdenZ: integer);
  2. begin
  3.   ListaDeVentanas.Insert(Ventana, OrdenZ) // o era inverso el orden de parámetros? ¡No tengo Delphi a mano!
  4. end;



O algo por el estilo.

* Estoy haciendolo genérico. Quizá en cierto modo sea posible trabajar con alguna clase en particular, al menos con TForm.

No termina allí la cosa... se ha formado el vínculo desde el administrador hacia las ventanas pero no de ventana al administrador. Todas las ventanas deben tener una referencia al administrador (de otro modo no sería posible interactuar):



delphi
  1. TFormX = class(TForm)
  2. private
  3.   FAdministrador: TAdministradorDeVentanas;
  4. public
  5.   property Administrador: TAdministradorDeVentanas write ... read...
  6. ...
  7. end;



En el momento de registrar, se procede además de establecer esta referencia:



delphi
  1. VentanaEnParticular.Administrador := MiAdministrador // el objeto administrador... podría ser global



Ahora listo, ya tenemos una vía de comunicación. Las ventanas cuando reciben foco, o cuando se cierran deberían pedirle su opinión al administrador. Se debe "sincronizar" y quizá actualizar el estado (habilitado/deshabilitado) de alguna.

Ya tenemos otro método para el administrador: Sincronizar. Entonces en los OnActivate y/o OnClose de las ventanas se invocaría a algo como esto:



delphi
  1. Administrador.Sincronizar(Self);



Por su parte, el administrador en Sincronizar exploraría su lista, y tendrá acceso a la ventana que le invocó la orden. Evaluando el Orden Z se puede determinar si se le permite o no habilitar (incluso sería más fácil y elemental, sólo aquel Z que sea igual al último en lista se le permite Habilitar).



delphi
  1. procedure TAdministradorDeVentanas.Sincronizar(Ventana: T....)
  2. var OrdenZ: integer;
  3. begin
  4.   OrdenZ := ObtenerOrdenZ(Ventana)
  5.   if OrdenZ = ListaDeVentanas.Count - 1
  6.     then HabilitarVentana(OrdenZ)
  7.     else HabilitarVentana(ListaDeVentanas.Count - 1);
  8. end;



Esa es más o menos la idea. Esto es sólo un borrrador, algo como para tener una guía. Espero que sea de utilidad para al menos como empezar.

NOTA: No he probado el código. Lo he escrito a mano a medida que redactaba.

Saludos,
  • 0

#10 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 18 septiembre 2010 - 01:35

Hola,

Les agradezco muchachos las gracias  :)
Quisiera preguntar si hay alguna novedad o si es necesario repasar algo del borrador.

Podría ser más claro, y evitar hablar de forma genérica, centrar el ejemplo en TForm (creo que sería lo más conveniente) o en alguna clase heredada de TForm que se haya definido como base (muy útil sobre todo se se combina con la herencia visual).

Saludos,
  • 0




IP.Board spam blocked by CleanTalk.