Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Problemas Forms MDI (https://www.clubdelphi.com/foros/showthread.php?t=86865)

doctorhd 15-10-2014 06:25:24

Problemas Forms MDI
 
Hola Amigos:
Estoy construyendo una aplicación MDI con sus respectivos forms MDICHILD, el problema radica en el comportamiento que tienen los menus asociados a los forms hijos, me explico, el form padre posee un menú que en cada una de sus opciones llama a la creación de form hijos, hasta aquí todo bien. A su vez cada form hijo posee su propio menú asociado con distintas opciones para el trabajo que debe realizar dicho form, el menú de los forms hijos se acopla perfectamente con el menú principal del form padre, el problema sucede cuando creo mas de una instancia de un form hijo, el menú de dicho form hace extensiva las operaciones a todas las instancias del mismo form. Por ejemplo si en una de las instancias proceso el ingreso de un nuevo registro en la tabla de la BD en las demás instancias del form la variable que contiene el status de que se esta realizando una creación asume al valor de la instancia en la cual se esta efectuado la creación. Comportamiento que a mi modo de ver es erróneo. Cada instancia del form debiera comportarse como un form distinto de sus demás instancias de acuerdo a las operaciones que se estén realizando en cada uno. He revisado el código varias veces y no encuentro ningún error que pudiera explicar dicho comportamiento. La forma en que creo los form hijos es la siguiente:

Código Delphi [-]
procedure TfrmMenuPrincipal.accFaenasExecute(Sender: TObject);
  var frmHijo:TfrmFaenas;
  begin
    frmHijo:=TfrmFaenas.Create(Self);{Creamos el nuevo form hijo}
    frmHijo.Show;
  end;

Saludos, espero me puedan ayudar...

engranaje 15-10-2014 10:09:53

Si he entendido bien lo que te pasa es que teniendo dos instancias de la misma clase Tfrmhijo y cambiando una variable en una de ellas esta te cambia también en la otra...

Una de las explicaciones que se me ocurren es que esa variable este declarada en la misma unit en la que tienes declarada la clase tfrmhijo pero no dentro de la clase sino fuera. Si esa variable estuviera declarada dentro de tfrmhijo como protected o incluso como public no se me ocurre como podría pasar lo que estoy entendiendo que te pasa.

Por otra parte y ya mas como opinión veo que en la acción declaras una variable local a la que le asignas del form que creas, despues muestras el form y listo... ¿que pasa despues con esa variable frmhijo? si no me equivoco el resultado final una vez terminada la acción es el mismo que si hubieras hecho:
Código Delphi [-]
 
procedure TfrmMenuPrincipal.accFaenasExecute(Sender: TObject); 
begin   
  with TfrmFaenas.Create(Self) do 
    Show; 
end;

Neftali [Germán.Estévez] 15-10-2014 10:19:49

Cita:

Empezado por doctorhd (Mensaje 483107)
...si en una de las instancias proceso el ingreso de un nuevo registro en la tabla de la BD en las demás instancias del form la variable que contiene el status de que se esta realizando una creación asume al valor de la instancia en la cual se esta efectuado la creación.

Sólo se me ocurre que estés comportiendo la misma fuente de datos (TTable o TQuery) para todos los formularios hijos. En ese caso al cambiarla en un form los demás ven los mismos cambios.
Debes usar la misma conexión, pero diferentes componentes de acceso.
¿Es posible que todos los formularios usen el mismo datamodule y por eso todos utilizan el mismo componente?

doctorhd 15-10-2014 14:08:02

Gracias engranaje y Neftali por responder:

Cita:

Si he entendido bien lo que te pasa es que teniendo dos instancias de la misma clase Tfrmhijo y cambiando una variable en una de ellas esta te cambia también en la otra...
Exato, es precisamente lo que sucede.

Cita:

Una de las explicaciones que se me ocurren es que esa variable este declarada en la misma unit en la que tienes declarada la clase tfrmhijo pero no dentro de la clase sino fuera..
También esto es cierto...esta declarada a continuación de la clase tfrmhijo.

Probé declarándola dentro de la clase, en la sección privada y funciono...Ahora mi pregunta es ¿porque si siendo 2 instancias de form diferentes dicha variable tiene este comportamiento...?

podrías ser mas explicito con esto:
Cita:

Por otra parte y ya mas como opinión veo que en la acción declaras una variable local a la que le asignas del form que creas, despues muestras el form y listo... ¿que pasa despues con esa variable frmhijo? si no me equivoco el resultado final una vez terminada la acción es el mismo que si hubieras hecho:
Código Delphi [-]
procedure TfrmMenuPrincipal.accFaenasExecute(Sender: TObject); 
begin   
  with TfrmFaenas.Create(Self) do 
    Show; 
end;


Saludos...

engranaje 15-10-2014 15:30:28

Tendrías que revisar el ambito de las variables... los dos asuntos se refieren a eso.
A grandes rasgos una variable según donde la declares tiene un ciclo de vida y una accesibilidad distinta.

Las que se añaden como privadas o publicas dentro de una clase se crearan cuando se cree una instancia esa clase y se destruiran cuando se destruya esa instancia. Ya dependiendo de si la declaras public o protected podra accederse a ella facilmente con nombreDeInstancia.nombreDeVariable o solo podra accederse desde dentro de la misma clase. Como ves en este caso lo que habrá realmente será una variable distinta por cada instancia.

Pero en cualquer unit puedes declarar variables antes de la implementation y fuera de cualquier clase. Esa variable podria considerarse global y sera accesible desde la propia unit o desde cualquier otra que la tenga en el uses. Pero en este caso la variable (vuelvo a decir que a grandes rasgos) se creará cuando se inicia la aplicación y se destruirá cuando la aplicación se destruya.

Por otro lado se pueden declarar variables dentro de un procedimiento o una función (en tu caso dentro de la acción) pero en ese caso esas variables son locales y solo existiran dentro de esa función, una vez se salga seran destruidas. En tu caso creas una instancia de un objeto y lo asignas a una variable, pero con ella no vas a hacer nada será destruida y tu instancia seguia existiendo pero realmente solo vas a poder acceder a él a traves de su handle. Sería lo mismo, creo que lo que puse en mi ejemplo hacer un create del form sin asginarselo absolutamente a nada. Si el único motivo por el que necesitabas una variable era acceder a un metodo de la instancia del objeto desde fuera de este bastaria con llamar al método dentro de un with.

Espero no haberme liado demasiado y que me hayas entendido, de todas formas si buscas algo mas acerca de la vida de las variables en delphi fijo que lo encuentras bien explicado en algún sitio.

doctorhd 15-10-2014 19:38:15

Gracias engranaje,

Comprendo lo que mencionas respecto a la accesibilidad de las variables, en función del lugar en que se declaren, pero asumí que el solo hecho de declararla dentro del cuerpo del form la haría parte de la instancia creada sin que sus datos fueran compartidos por las demás instancias.

Respecto a lo que mencionas de la variable que sirve de contenedor para la creación del form y su ciclo de vida, me asalto la duda, cuando se destruye la instancia creada de cada forma, ¿cuando se invoca el evento close del form, o cuando se destruye el form padre que crea dichas instancias, o debo destruir yo las instancias después de cerras estas..?

Saludos...

engranaje 15-10-2014 23:53:25

Lo mejor seria que en el onclose del form hicieras un
Código Delphi [-]
 action := cafree;
Puedes echarle un ojo a este hilo, igual te aclara algo mas el asunto:
http://www.clubdelphi.com/foros/showthread.php?t=4904


La franja horaria es GMT +2. Ahora son las 20:43: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