Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Casteo en tiempo de ejecución (https://www.clubdelphi.com/foros/showthread.php?t=23557)

moesis 20-07-2005 22:50:03

Casteo en tiempo de ejecución
 
Saludos gente,
Hacía tiempo que no pasaba por aquí, pero es que he estado muy liado :(, a partir de ahora, si los negocios lo permiten, prometo dedicarle más tiempo.

Tengo un problema que seguramente tendrá una solución la mar de sencilla. A ver cuento cual es el problema.

Estoy desarrollando un formulario (TfrmBrowser) genérico para realizar las operaciones básicas de un mabteniemiento (altas, bajas, modificaciones, borrados, etc), este cuenta en su interior con un Panel donde es incrustado el verdadero form (TFormulario) que contiene los datos y métodos necesarios para verificar la integridad referencial, valores, etc.

Ambos formularios descienden de TForm. y TfrmBrowser en su constructor recibe como parámetro de tipo TComponent, el formulario a incrustar.

En el formulario TfrmBrowser, existen dos métodos que incrustan y liberan dicho formulario. En estos métodos se realiza un cast de la forma TForm(m_formulario).propiedad y funciona fenomenal.

El problema surge cuando intento acceder a las propiedades públicas del formulario TFormulario y no son visibles, algo totalmente lógico. He leido que puedo obtener el nombre de la clase base como string, y la clase como un pointer a TClass, pero ¿Cómo podría realizar un cast en tiempo de ejecución para que reconozca los métodos de TFormulario?
Agradecido de antemano,
Un saludo desde Canarias.

Neftali [Germán.Estévez] 21-07-2005 09:43:01

Cita:

Empezado por moesis
...El problema surge cuando intento acceder a las propiedades públicas del formulario TFormulario y no son visibles, algo totalmente lógico. He leido que puedo obtener el nombre de la clase base como string, y la clase como un pointer a TClass, pero ¿Cómo podría realizar un cast en tiempo de ejecución para que reconozca los métodos de TFormulario?

No acabo de entender (del todo) lo que explicas, pero creo que existen dos formas de poder accedre a los métodos de TFormulario en ejecución, contando que no puedes hacer un CAST, debido a que en el TfrmBrowser no sabes cual es la clase real de TFormulario (debido a que va a ir cambiando):

(1) La primera forma es que todos tus TFormulario deriven de un TFormBase, de forma que los métodos estén definidos en TFormBase como virtual (y abstract, si es necesario) y luego en los TFormulario se redefinan utilizando override; Eso te permitiría llamar a los métodos de TFormBase y estaría ejecutando los de los formularios derivados (por el override).

(2) La otra opción es utilizar RTTI; Para ellos debes definir todos los métodos que vayas a utilizar en la parte published del formulario y accederlos vía RTTI utilizando el nombre del método. En éste hilo puedes encontrar un ejemplo:
http://www.clubdelphi.com/foros/show...05&postcount=2

Si necesitas más, ya dirás,...

moesis 21-07-2005 10:09:04

Agradecido por la contestación, te pongo parte del código que puede ser aclarativo para que te hagas una idea.

Código Delphi [-]
 type
   TfrmBrowser = class(TForm)
    ...
     pnlReceptor: TPanel;     // Aquí será incrustado el form.
    ...
   private
     { Private declarations }
     m_Padre : TComponent;
     m_Conexion : TSQLConnection;
     m_Datos : TDataSource;
     m_FormIncrustado: TComponent;    // Este es el causante ;)
     m_stTextoInformativo: String;
     m_idRegistro : Integer;
 
     { Funciones y procedimientos }
     ...
    procedure IncrustarDialogo;
     procedure LiberarDialogo;
     procedure SetFormularioIncrustado (const Valor: TComponent);
    ...
 
     { Propiedades }
    property Formulario : TComponent Read m_FormIncrustado Write SetFormularioIncrustado;

    { Public declarations }
     constructor Create(Owner: TComponent; aDialogo: TComponent); reintroduce; overload;
     destructor Destroy; reintroduce; overload;
   end;
 
 // Este es el método (público) que arranca el diálogo.
   procedure AbrirDialogo(pVentanaPadre: TComponent;
                        aTextoInfo : String;
                         aDialogo: TComponent;
                         aIdRegistro: Integer);

Código Delphi [-]
   TfrmEmpresas = class(TForm)
     Label2: TLabel;
     edtEmpresa: TRzEdit;
     Label3: TLabel;
     edtDireccion: TRzEdit;
     Label4: TLabel;
     edtCodigoPostal: TRzEdit;
     Label5: TLabel;
     edtCorreoElectronico: TRzEdit;
     Label6: TLabel;
     edtFax: TRzEdit;
     Label7: TLabel;
     edtTelefonos: TRzEdit;
     Label8: TLabel;
     edtContacto: TRzEdit;
   private
     { Private declarations }
     procedure SetEmpresa (const Value : String);
     procedure SetDireccion (const Value : String);
     procedure SetCodigoPostal (const Value : String);
     procedure SetCorreoElectronico (const Value : String);
     procedure SetFax (const Value : String);
     procedure SetTelefonos (const Value : String);
     procedure SetContacto (const Value : String);
 
     function GetEmpresa : String;
     function GetDireccion : String;
     function GetCodigoPostal : String;
     function GetCorreoElectronico : String;
     function GetFax : String;
     function GetTelefonos : String;
     function GetContacto : String;
   public
     { Public declarations }
 
   published
     { Declaraciones publicadas }
     property Empresa : String Read GetEmpresa Write SetEmpresa;
     property Direccion : String Read GetDireccion Write SetDireccion;
     property CodigoPostal : String Read GetCodigoPostal Write SetCodigoPostal;
     property CorreoElectronico : String Read GetCorreoElectronico Write SetCorreoElectronico;
     property Fax : String Read GetFax Write SetFax;
     property Telefonos : String Read GetTelefonos Write SetTelefonos;
     property Contacto : String Read GetContacto Write SetContacto;
   end;

La clase TfrmEmpresas que es la que quiero incrustar, siempre será diferente, por lo que no es posible hacer una herencia, ya que los campos que contiene no coinciden en la mayoría de los casos.

Y lo de published no funciona pues debes indicarle de alguna forma que esa clase tiene esos métodos pues como puedes observar el form está siendo tratado como si fuera un TComponent.

Saludos desde Canarias

Neftali [Germán.Estévez] 21-07-2005 12:27:16

Decartado el tema de herencia, sólo queda RTTI.
Si buscas la unit TypInfo verás que tiene los métodos:

function GetStrProp(Instance: TObject; const PropName: string): string; overload;
procedure SetStrProp(Instance: TObject; const PropName: string;
const Value: string); overload;

Para consultar y asignar valor a una propiedad de tipo String (que sea published).

Revisa éste artículo:
http://www.elists.org/pipermail/delp...ry/002721.html
Se titula: Using RTTI to obtain TString property
Y creo que es lo que necesitas...

moesis 21-07-2005 15:21:56

Saludos,

He solucionado la historia mediante una herencia y la utilización del metodo MethodAddress lo cual me ha permitido ejecutar cualquier método con o sin parámetros solamente pasando el nombre del método y el parámetro que en caso de no estar es definido como ''.

Gracias por tu ayuda pues ha sido muy provechosa. Prometo colgar el código (ya veré que tipo de licencia le pongo) ;) para que todo el mundo pueda utilizarlo y ampliarlo si lo desea.

Creo haber leido por ahí una que se llamaba TapaWare, lo que si no recuerdo mal indicaba que el precio para utilizarlo era el pago de una tapita en un bar... :D.

Saludos desde Canarias.


La franja horaria es GMT +2. Ahora son las 17:00:07.

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