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 01-08-2003
raul_sal raul_sal is offline
No confirmado
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 45
Poder: 0
raul_sal Va por buen camino
Mostrar Form conociendo unicamente el Nombre como String

Que tal amigos

Tengo una aplicacion que tiene n cantidad de opciones en los menues, las cuales estan almacenadas en una tabla, en la cual uno de sus campos es el tipo del formulario de la opcion.

Como puedo hacer para ejecutar esta sentencia mas

Código:
   

type 
   MiForma : TForm;
   . 
   .
   .

   if MiForma = nil then
         Application.CreateForm('TTipodelFormulario', MiForma);
   MiForma.Windowstate := wsNormal;
   MiForma.BringToFront;
   MiForma.Show;
Responder Con Cita
  #2  
Antiguo 01-08-2003
Avatar de __marcsc
__marcsc __marcsc is offline
Miembro
 
Registrado: may 2003
Ubicación: Girona
Posts: 577
Poder: 22
__marcsc Va por buen camino
Hola,

dale un vistazo a este hilo:

http://www.clubdelphi.com/foros/show...=&threadid=334

En él encontrarás un enlace a uno de los posts más famosos del Club Delphi

Saludos!
Responder Con Cita
  #3  
Antiguo 02-08-2003
raul_sal raul_sal is offline
No confirmado
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 45
Poder: 0
raul_sal Va por buen camino
Gracias por contestar

Es bastante ilustrativo el link, pero no me saca de mi problema ya que la solucion final que me dan alli es utilizar las referencias de las clases pero si yo unicamente conozco el nombre de la clase, podrian dar un ejemplo un poco mas ilustrativo.

Gracias
Responder Con Cita
  #4  
Antiguo 02-08-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Me parece que no captaste la esencia:

Para crear una forma (u otro objeto) de manera genérica necesitas referencias de clases mientras que lo que tú tienes son los nombres de las clases que obtienes de una tabla.

La fábrica mantiene una relación entre las referencias y los nombres:

Código:

+----------+--------+
|  Nombre  | Clase  |
+----------+--------+
| 'TForm1' | TForm1 |
| 'TForm2' | TForm2 |
| 'TForm3' | TForm3 |
| 'TForm4' | TForm4 |
+----------+--------+
Cuando obtienes el nombre de una clase la fábrica te da la referencia de clase necesaria para construir la forma.

A continuación te pongo la unidad que define la fábrica. Puedes copiarla y pegarla completa:

Código:
unit FabForm;

interface

uses
  Classes, Forms;

type
  TFabrica = class
  private
    Lista: TStringList;
    function GetClase(Nombre: String): TFormClass;

  public
    constructor Create;
    destructor Destroy; override;
    procedure Registrar(Clase: TFormClass);

    property Clases[Nombre: String]: TFormClass read GetClase;
  end;

var
  Fabrica: TFabrica;

implementation

constructor TFabrica.Create;
begin
  inherited;
  Lista := TStringList.Create;
end;

destructor TFabrica.Destroy;
begin
  Lista.Free;
  inherited;
end;

procedure TFabrica.Registrar(Clase: TFormClass);
var
  I : Integer;

begin
  I := Lista.IndexOf(Clase.ClassName);

  // Registrar si no lo está ya
  if I = -1 then Lista.AddObject(Clase.ClassName, TObject(Clase));
end;

function TFabrica.GetClase(Nombre: String): TFormClass;
var
  I : Integer;

begin
  I := Lista.IndexOf(Nombre);
  Assert(I <> -1, 'Clase no registrada');
  Result := TFormClass(Lista.Objects[i]);
end;

initialization
  Fabrica := TFabrica.Create;

finalization
  Fabrica.Free;
end.
En la unidad de cada formulario que desees 'almacenar' en la tabla registras la clase:

Código:
unit Unit1;

interface

type
  TForm1 = class(TForm)
  ...
  end;

implementation

uses FabForm;

initialization
  Fabrica.Registrar(TForm1);
end.
Finalmente, suponte que NombreForma es una variable string que contiene el nombre de una forma obtenido de tu tabla y que ClaseForma es una variable de tipo TFormClass. La asignación

ClaseForma := Fabrica.Clases[NombreForma];

te da la referencia de clase que necesitas y ahora puedes crear el formulario con:

ClaseForma.Create(nil)

Espero que ahora esté más claro. Si tienes dudas pregunta otra vez.

// Saludos

Última edición por roman fecha: 02-08-2003 a las 04:56:54.
Responder Con Cita
  #5  
Antiguo 08-06-2010
VictorPenyalver VictorPenyalver is offline
Miembro
 
Registrado: abr 2006
Posts: 19
Poder: 0
VictorPenyalver Va por buen camino
Problema con el constructor

Hola,

Siguiendo este hilo me surgió un problema.

No me ejecuta el constructor de la clase form que he pasado como parametro(string).

Lo abre correctamente pero solo ejecuta el evento FormCreate.

Gracias!
Responder Con Cita
  #6  
Antiguo 09-06-2010
VictorPenyalver VictorPenyalver is offline
Miembro
 
Registrado: abr 2006
Posts: 19
Poder: 0
VictorPenyalver Va por buen camino
Contructor

Ahi va el codigo que uso. El formulario se crea bien con el codigo que se publico en este hilo pero no pasa por su constructor.

El formulario que debe crear es heredado y el constructor esta declarado como Virtual.


Código:
procedure TfrmListado.CreaFicha;
var ClaseFicha: TFormClass;
begin
  inherited;
  ClaseFicha := Fabrica.Clases[FFormFicha];
  with ClaseFicha do begin
    Create(Self);
  end;
end;

initialization
  Fabrica.Registrar(TfrmListado);
Gracias por vuestra ayuda!
Responder Con Cita
  #7  
Antiguo 17-10-2011
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.464
Poder: 21
newtron Va camino a la fama
Estimado Román.

Estoy intentando usar tu ejemplo para poder crear un formulario a partir de un string con el nombre y tengo el siguiente problema a ver si me puedes echar una mano:

Yo uso formularios propios que descienden del TForm y con tu ejemplo consigo crearlos correctamente pero ahora no sé como hacer referencia al formulario para poder asignar unas propiedades determinadas y luego presentarlo.

Gracias y un saludo
__________________
Be water my friend.
Responder Con Cita
  #8  
Antiguo 17-10-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No puedes

Tal como está pensada, la fábrica almacena referencias TFormClass y, aunque puedes, desde luego, guardar referencias de clases derivadas, no puedes sino usar los métodos y propiedades definidos en TForm. Claro que el polimorfismo de OOP aún te permite usar clases derivadas con métodos redefinidos y todas esas cosas, pero sólo puedes llamar los métodos que ya tienes.

¿Qué hacer entonces?

Fijar tu propio ancestro común; para lo cual haría falta tener organizados turs formularios en una jerarquía de clases. Así por ejemplo tendrías

Código Delphi [-]
type
  TNewtronForm = class(TForm)
  protected or public
  {
    Aquí un montón de propiedades y métodos cool que usan tus formularios
  }
  end;

Tus formularios derivarían de éste y, para que la fábrica funcione necesitas, primero definir un tipo de datos que referencie tu clase de formulario:

Código Delphi [-]
type
  TNewtronFormClass = class of TNewtronForm;

Y en la definición de la fábrica cambiar las referencias a TFormClass por TNewtronFormClass.

En un escenario muy complicado, con formularios de muy diversas índoles, tendrías que crear no una clase base sino posiblemente varias de ellas para agrupar aquellas con características comunes y hacer fábricas para cada grupo.

// Saludos
Responder Con Cita
  #9  
Antiguo 17-10-2011
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.464
Poder: 21
newtron Va camino a la fama
Estupendo amigo roman.

Como solo tengo un tipo de formulario heredado no creo que tenga grandes problemas para implementar tu solución.

He hecho una prueba y parece que funciona perfectamente.

Gracias por todo y un saludo .
__________________
Be water my friend.
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 21:29:37.


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