Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   FireMonkey (https://www.clubdelphi.com/foros/forumdisplay.php?f=50)
-   -   Acceso a objetos de un form desde otro (https://www.clubdelphi.com/foros/showthread.php?t=93413)

vicens22 17-09-2018 22:07:16

Acceso a objetos de un form desde otro
 
1 Archivos Adjunto(s)
Estoy desarrollando con Delphi Tokyo y Firemonkey una aplicación para Android e IOS, y me encuentro con el siguiente problema, que imagino que también sucederá programando en VCL, pero por si acaso lo publico aquí.

Ya me encontré con el mismo problema hace unos meses, pero en ese momento lo pude solventar simplemente poniendo los formularios que contienen los objetos a los que hago referencia como "autocreates" en el project, pero ahora me gustaría poder quitarlos de ahí, ya que ralentizan el arranque de la aplicación en el dispositivo móvil.

Se trata simplemente de poder acceder a objetos (tedit y similares, cambiando por ejemplo su propiedad text), que están en un formulario desde otro, sin que el formulario que contiene esos objetos tenga que ser autocreate. Lo que me ocurre al intentar acceder a sus propiedades es que obtengo un error "Access violation".

He creado un ejemplo simplificando el problema (adjunto los ficheros del mismo).
Son tres unidades/formularios: Main, Form1 y Form2.
Sólo Main está como "autocreate" en el project.
En Main, hay un botón que crea Form1, el cual contiene un objeto tLlabel, un tEdit y un botón que crea Form2.
El error (Access violation) ocurre cuando en este último formulario (Form2), intento modificar las etiquetas .text del label y el edit que se encuentran en Form1 (hay un botón que hace simplemente eso).

Este error no ocurre (y se modifican correctamente los objetos label y tedit), si en el project hago que Form1 sea "autocreate", pero ya he comentado que necesito evitar esto para mejorar el arranque de la aplicación, ya que hay varios formularios en los que me ocurre lo mismo.

Gracias por cualquier ayuda.
Saludos,

Vicens

Caminante 17-09-2018 22:42:44

Hola


La razon para que funcione al tener los forms como autocreate es que para acceder a los mismos deben estar creados. En tal caso deberias crearlos cuando los necesites (No hay necesidad de que esten en autocreate) y liberarlos despues.


Saludos

vicens22 17-09-2018 23:14:48

Hola,

Gracias por tu respuesta, pero si revisas el código del ejemplo subido, verás que los dos formularios que no son "autocreate" (form1 y form2) son creados. Primero form1 desde el main y luego form2 desde form1.
Es decir los tres están creados cuando obtengo el error (Access violation).
Aquí tienes el código del procedimiento que utilizo para crear y visualizar los dos formularios:


Código Delphi [-]
procedure TfMain.OpenTestForm(cForm: string);

procedure OpenForm(form: TForm);
    begin
      form.Show;
    end;
begin
 if cForm = 'form1' then
  begin
     OpenForm(tfForm1.Create(self));
 //    fForm1.Show;    // Si fForm1 es autocreate
  end
  else if cForm = 'form2' then
  begin
     OpenForm(tfForm2.Create(self));
  end
end;

Si tienes oportunidad pruébalo ejecutándolo en Windows y podrás comprobar que como te comento, los tres forms están creados.

Gracias de nuevo.
Saludos,

Caminante 17-09-2018 23:55:59

Hola


Por desgracia no cuento con una version de delphi donde probar pero viendo el codigo que pusiste no veo forma que referencies a los controles de los formularios ya que no tienes ninguna variable apuntando a ellos. En este caso no sirve usar las variables que se crean automaticamente en la unidad de los formularios.


Podrias cambiar los metodos para que te devuelvan una referencia al formulario creado (Lo que tambien lleva sus riesgos de memoria) y ya con la referencia podrias hacer lo que deseas


Saludos

vicens22 18-09-2018 00:03:43

Hola,

Lo siento, pero no veo claro como probar lo que propones.
Pero sigo sin entender, porqué si Form1 es autocreate el mismo código funciona sin problema ??

Saludos,

Caminante 18-09-2018 00:44:59

Cita:

Empezado por vicens22 (Mensaje 528462)
Hola,

Lo siento, pero no veo claro como probar lo que propones.
Pero sigo sin entender, porqué si Form1 es autocreate el mismo código funciona sin problema ??

Saludos,

Supongo que cuando referencias al formulario lo haces asi:

Código Delphi [-]
form1.edit1.text:='Lo que sea'

Al ser forms autocreados la variable form1 ya esta inicializada y puedes usarla sin problemas. Al crear los forms de la otra manera no asignas nada a 'Form1' por eso da errores de memoria.

Podrias probar asi:
Código Delphi [-]
procedure TfMain.OpenTestForm(cForm: string); 
begin  
  if cForm = 'form1' then   
  begin
    form1:=tfForm1.Create(self);      
    fForm1.Show;     
  end  
  else if cForm = 'form2' then   
  begin
    form2:=tfForm2.Create(self);
    form2.show
  end 
end;
Lo hice apegandome a tu codigo. Se puede mejorar pero creo que se puede entender la idea.

Saludos

vicens22 19-09-2018 10:26:35

Efectivamente, tenias toda la razón, ahora sí pude verlo.
No lo veía, aún teniéndolo delante.
Al estar el formulario visible, no caía en que la variable no estaba inicializada.
Ya modifiqué la creación de los formas y pude conseguir lo que pretendía.

Muchísimas gracias por tu ayuda!!!
Saludos


La franja horaria es GMT +2. Ahora son las 07:01:46.

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