Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Creador generico de formulario. (https://www.clubdelphi.com/foros/showthread.php?t=66584)

movorack 02-03-2010 04:39:51

Creador generico de formulario.
 
Hola club... aqui liandome la cabeza yo solo...

en mis progamas siempre para crear/mostrar los formularios uso las siguientes lineas:
Código Delphi [-]
if not Assigned(Form) then
  Application.CreateForm(TForm, Form);
Form.Show;

y luego al cerrar los formularios en el evento OnClose le coloco estas otras lineas
Código Delphi [-]
  Action := caFree;
  Form := nil;

Como el código lo tengo que repetir una y otra vez, me puse a darme solo contra el código e hice este procedimiento, basandome en lo que he leido aqui en el club y en otras partes:

Código Delphi [-]
procedure CreateForm(ClassName: TPersistentClass; FormName: String);
  var
    Component : TComponent;
begin
  Component := Application.FindComponent(FormName);
  if not Assigned(Component) then begin
    try
      FindClass('T'+FormName);
    except
      classes.RegisterClass(ClassName);
    end;
    Application.CreateForm(TComponentClass(ClassName), TForm(FormName));
  end else
      TForm(Component).Show;
end;

Funciona!... pero cuando voy a cerrar el formulario... en algunas ocasiones, me lanza un error "Invalid pointer"... y no se donde está el error exactamente pq es lo único que dice... además que no se deja capturar para revisión... solo sale el error y ya...

de ahi en adelante, el programa sigue trabajando bien hasta que lo cierro y vuelve a sacar el error una y otra vez.

el error "Invalid pointer" no sale siempre, como puede salir en relación 1:10, tambien puede ser 1:1 o 1:20...

se que es un error en el procedimiento que cree, pq al usarlo de la otra manera... ya no salen errores.

bueno ya dejo de tirar lora... y si alguien me puede hacer un comentario o aporte... se lo agardeceré.

Neftali [Germán.Estévez] 02-03-2010 09:08:29

Yo creo que esta línea te puede estar dando problemas:

Código Delphi [-]
  
Application.CreateForm(TComponentClass(ClassName), TForm(FormName));

En el segundo parámetro estás haciendo el CAST como TForm de un string.:confused::confused:

movorack 02-03-2010 12:52:58

así lo ví en un sitio... creo que fué en aboutdelphi... y funciona... a mi también me pareció extraño... pero funcionó... la cuestión es cuando voy a cerrar dicho formulario... y eso no todas las veces.

Neftali [Germán.Estévez] 02-03-2010 13:20:35

Yo en todo caso lo hubiera puesto así:

Código Delphi [-]
Application.CreateForm(TComponentClass(ClassName), TForm(component));

movorack 02-03-2010 13:41:43

Así me genera un error cuando el formulario no ha sido creado aún... la primera línea evalúa si el formulario está creado... cuando no está creado devuelve siempre nil y si lo coloco como parametro del CreateForm me genera un error.

Quité el cast, dejando solo el string como parametro y es más estable que antes... ya el error se presenta muy pocas veces.
Código Delphi [-]
Application.CreateForm(TComponentClass(ClassName), FormName);

rgstuamigo 02-03-2010 14:11:12

Hola movorack, en éste hilo se ha tratado el tema del error y en mi opinión particular para poder resolverlo creo que la respuesta de hach es la mejor solución.;)
Saludos...:)

Neftali [Germán.Estévez] 02-03-2010 14:20:07

1 Archivos Adjunto(s)
Sigo pensando que esa referencia al nombre del formulario va a dar siempre error.
Yo lo he probado cambiando por component, tal y como te he dicho antes y eliminandole el último else y parece que funciona.

Aquí te subo el ejemplo.

Código Delphi [-]
procedure CreateForm1(ClassName: TPersistentClass; FormName: String);
var
  Component : TComponent;
begin
  // busco si el form está ya creado  (a)
  Component := Application.FindComponent(FormName); 
  // No está creado?  ==> Lo creo
  if not Assigned(Component) then begin
    try
      // Buscar la clase
      FindClass('T'+FormName);
    except
      // si no la ha encontrado la registro
      classes.RegisterClass(ClassName);
    end;
    // Creo el form a partir de la clase (queda en component -referencia-) (b)
    Application.CreateForm(TComponentClass(ClassName), component);
  end;

  // Abro el form, ya sea por encontrado(a) o por creado(b)
  TForm(Component).Show;
end;

rgstuamigo 02-03-2010 14:28:53

El problema que veo no está en cómo se crea el formulario sino mas bien en cómo se está destruyendo, recalco el problema del FreeAndNil(bueno en éste caso se asigna "nil" al formulario en el evento OnClose) es la cuestion;) y creo que roman lo a explicado claramente en éste hilo.
Saludos...:)

movorack 02-03-2010 15:16:12

Cita:

Empezado por rgstuamigo (Mensaje 355357)
El problema que veo no está en cómo se crea el formulario sino mas bien en cómo se está destruyendo

Gracias rgstuamigo, de verdad a mi tampoco me gusta mucho esta forma... la uso porque me "funciona" :D:D:D... leí el hilo y me parece interesante el comentario de román... aunque en realidad no habia tenido problemas con la destrucción del formulario.

Cita:

Empezado por Neftali (Mensaje 355356)
Yo lo he probado cambiando por component, tal y como te he dicho antes y eliminandole el último else y parece que funciona

Gracias Neftali, si funciona y no me ha arrojado ningún error hasta ahora... bacano.

--
Comparto este artículo que encontré (Understanding the Birth, Life and Death of a Delphi Form), pues me parece relevante al tema...


La franja horaria es GMT +2. Ahora son las 03:59:01.

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