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 23-08-2004
sur-se sur-se is offline
Miembro
 
Registrado: may 2003
Posts: 212
Poder: 21
sur-se Va por buen camino
Recorrido de ventanas hijas

Hola. Estoy trabajando con una aplicación MDI en Delphi 5. Tengo definidos dos formularios de tipo MDIChild que utilizo como clases base para los formularios MDI definitivos. Todos los formularios MDI de la aplicación son hijos de estos dos que tengo definidos, y ninguna ventana es directamente alguno de estos dos formularios.

En las clases base he definido un método Puedo_Cerrar de tipo virtual, que nos indica si el formulario puede ser cerrado o no (por encontrarse procesando algo). Estos métodos pueden ser redefinidos (si se desea) en las clases hijas herederas (declarándolos como override).

La cuestión es que al tratar de cerrar la aplicación se recorren todas las ventanas MDIChildren comprobando si pueden cerrarse o no (llamando al método público). El código que utilizo sería el siguiente:

Código:
var cerrar_aplic:boolean;
begin
   for i:=0 to MDIChildCount-1 do
   begin
       if MDIChilren[i] is TMDIBase1 then
           with MDIChildren[i] as TMDIBase1 do
                  if not Puedo_Cerrar then cerrar_aplic:=false;
    
       if MDIChilren[i] is TMDIBase2 then
           with MDIChildren[i] as TMDIBase2 do
                  if not Puedo_Cerrar then cerrar_aplic:=false;
   end;
   if cerrar_aplic then action:=cafree
   else action:=canone;
end;
El problema es que el método Puedo_Cerrar puede haber sido redefinido en la nueva clase hija de alguna de las anteriores por lo que para llamar al método correcto debería poner:
Código:
      if MDIChildren[i] is TMDIHijaBaseX then
          with MDIChildren[i] as TMDHijaBaseX do
                 ....
pero entonces tendría que poner un "if" por cada clase de formularios MDI que defina en mi aplicación. Me gustaría que fuese algo genérico de forma que se llamase al método correcto.
¿Se puede hacer esto de alguna forma? ¿existe alguna otra alternativa?
Gracias.
Responder Con Cita
  #2  
Antiguo 23-08-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Olvidas que delphi, por supuesto, soporta el polimorfismo, que de hecho, es la base de gran parte del funcionamiento de la VCL.

Al declarar el método "puedo_cerrar" como virtual en la(s) clases base, y declararlo como override cada vez que sea necesario redefinirlo, garantizas que cualquier llamada al método se resuelva correctamente en tiempo de ejecución, aún cuando se realice sobre un "molde" de una clase ancestro.

Ahora, veo otros dos problemillas de concepto.

Uno, que para el cerrado de formularios, ya la VCL provee del evento OnCloseQuery, que podrias definir en tus clases. Cuando una aplicación MDI intenta cerrarse, ejecuta el evento en todos los formularios hijos.

Dos, que si tenes ya una estructura de herencia visual, y en ambas formas "base" has declarado el método "puedo cerrar" (y estoy seguro que algún otro)... quizas tu jerarquia merezca una "reingeniería", y estos métodos sea introducido en una clase base para ambas clases actuales, de manera que en casos como este (que espero que cambies por el CloseQuery ya mencionado) podas echar mano de esta clase base.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #3  
Antiguo 23-08-2004
sur-se sur-se is offline
Miembro
 
Registrado: may 2003
Posts: 212
Poder: 21
sur-se Va por buen camino
Hola. Gracias por la respuesta.
Efectivamente el polimorfismo debería actuar aquí al redefinir el método Puedo_Cerrar con override. Lo que no tenía claro es que al hacer el "with MDIChildren[i] as TMDIBase1 do" tomase el Puedo_Cerrar de la nueva clase y no de la TMDIBase1, ya que al decirle que trate al MDIChildren[i] como un formulario TMDIBase1 no llamase al método Puedo_Cerrar redefinido.

Lo que no veo tan claro es lo que me comentas del método OnCloseQuery. Efectivamente si trato de cerrar un formulario me saltaría ese evento y ahí podría hacer ese proceso para que no se cerrara, pero no me solventaría lo que pretendo hacer. Yo quiero saber si puedo o no cerrar el formulario. Tal como tu comentas tendría que hacer un close del formulario, y el se gestionaría, pero desde donde hago el close tendría que hacer más adelante una comprobación de si se cerró o no, por lo que al final tendría que consultar de alguna manera eso. Por ello, lo encapsule en el método Puedo_Cerrar.

Por otra parte, efectivamente, pensé en hacer una clase ancestro inicial con el método puedo_cerrar y después las dos "bases" mdi sobre estas, pero para un solo método no me merecía la pena hacer una clase. Las dos "MDI base" son totalmente diferentes.

Un saludo.
Responder Con Cita
  #4  
Antiguo 23-08-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cool

Hola.

Cita:
Empezado por sur-se
Efectivamente el polimorfismo debería actuar aquí al redefinir el método Puedo_Cerrar con override. Lo que no tenía claro es que al hacer el "with MDIChildren[i] as TMDIBase1 do" tomase el Puedo_Cerrar de la nueva clase y no de la TMDIBase1, ya que al decirle que trate al MDIChildren[i] como un formulario TMDIBase1 no llamase al método Puedo_Cerrar redefinido.
Si no fuese así... ¿que sería el polimorfismo entonces?

Cita:
Lo que no veo tan claro es lo que me comentas del método OnCloseQuery. Efectivamente si trato de cerrar un formulario me saltaría ese evento y ahí podría hacer ese proceso para que no se cerrara, pero no me solventaría lo que pretendo hacer. Yo quiero saber si puedo o no cerrar el formulario. Tal como tu comentas tendría que hacer un close del formulario, y el se gestionaría, pero desde donde hago el close tendría que hacer más adelante una comprobación de si se cerró o no, por lo que al final tendría que consultar de alguna manera eso. Por ello, lo encapsule en el método Puedo_Cerrar.
No tenes que cerrar necesariamente cada formulario. Si seguis con la idea de "hacerlo a mano" podes hacer algo como:

Código Delphi [-]
var 
  cerrar_aplic:boolean;

begin
  cerrar_aplic := True;
  for i:=0 to MDIChildCount-1 do
    if assigned(MDIChildren[i].OnCloseQuery) Then
    Begin
      MDIChildren[i].OnCloseQuery(nil, cerrar_aplic);
      if not CerrarAplic Then
        Break;
    end;
  if cerrar_aplic then 
    action:=cafree
  else 
    action:=canone;
end;

Aunque ciertamente, no hace falta. Como ya dije antes, cuando el usuario trate de cerrar la aplicación, la VCL recorrerá automáticamente todas las formas abiertas, cerrandolas siempre que el CloseQuery deje CanClose en True. Si alguna no puede cerrarse, el proceso se detiene en ese momento, evitando asi que se cierre la aplicación.

Cita:
Empezado por sur-se
Las dos "MDI base" son totalmente diferentes.
Bueno... también comparten el hecho de ser ambas mdi.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
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 09:28:54.


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