Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Obtener la clase de objetos (https://www.clubdelphi.com/foros/showthread.php?t=21)

Feñiz 04-05-2003 12:33:49

Obtener la clase de objetos
 
Antes de nada, disculpas por volver a postear de nuevo mi duda, creo que ya había sido respondida hace un par de días, pero con el cambio de foros no pude leer la respuesta.

Bueno, la cuestión es si existe algún método para poder trabajar con un objeto de tipo TComponent, accediendo a sus propiedades de clase directamente.

Pongo un ejemplo: Tengo un objeto Componente, te tipo TComponent. Ése es el objeto que paso como parámetro a una función, y puede ser distintos componentes visuales (un TButton, TLabel, Tform, TPanel, etc). Todos ellos tienen la propiedad TCaption, que es la que quiero modificar. La forma en que yo lo hago ahora es mediante un cast de esta forma:

If (Componente is TButton) then TButton(Componente).Caption:='Texto de caption'
else if (Componente is TLabel) then TLabel(Componente).Caption:='Texto de caption'
else ....

Y lo que yo querría saber es si existe alguna función o método que me permita hacerlo de forma similar a esta:

If (Componente is TButton) or (Componente is TLabel) or (Componente is TForm) or (Componente is TPanel) then
//Me aseguro de que pertenezca a una de las clases que tienen la propiedad Caption
(Función que estoy buscando).Caption:='Texto de caption';

En este ejemplo el ahorro de código es insignificante, pero si se está trabajando con 15 componentes diferentes, y modificando varias propiedades, se ahorra mucho tanto en cantidad de código como en claridad.

¿Existe la función que yo estoy buscando?

__marcsc 04-05-2003 12:46:26

Hola muy buenas,

pues te vuelvo a contestar :D (tranquilo, las disculpas no son necesarias en este caso ya que el tema se ha perdido)

Para hacer lo que quieres puedes utilizar 2 funciones de las APITools de Delphi (para ello vas a necesitar poner la unit TypInfo en la clausula uses)

- HasProperty: te permite saber si un componente tiene una determinada propiedad

- SetOrdProp: Te permite establecer el valor de una propiedad por su nombre

Aquí encontrarás un ejemplo:

http://www.delphi32.com/info_facts/faq/faq_699.asp

Ojo que en tu caso tienes que pasarle un string y la función SetOrdProp solo te permite pasarle un entero, por lo que creo que tendrías que hacer algo similar a esto:

Código:


Valor:= 'Prueba';
SetOrdProp(Componente,'Caption',Integer(Pointer(Valor)));

Ojo! No lo he probado, pero diría que es lo que tienes que hacer.

Un saludo.

P.D: Obviando toda la filosofada que tuvimos antes sobre si es conveniente o no utilizar este método en vez de el que utilizas ahora, solo te diré que en mi caso, si el numero de clases es pequeño lo dejaría tal como lo tienes, mientras que si vees que te va a crecer mucho sí que cambiaría de método :)

Feñiz 04-05-2003 12:50:59

Gracias por la rápida respuesta.

Esta noche lo probaré, y ya informaré sobre si me ha funcionado.

Gracias de nuevo.

Feñiz 05-05-2003 12:59:55

Pues sí, funciona.

Ahora he sustituido todo el código anterior por esto:

var p: Pointer; Texto: String;

Texto:='Texto de caption';
p := GetPropInfo(Componente.ClassInfo, 'Caption');
if (p<>nil) then SetOrdProp(Componente , p, Integer(Pointer(Texto)));

Y funciona perfectamente. En este trozo que pongo como ejemplo, no se aprecia, pero el ahorro en código que conseguiré gracias a ello es muy importante.

Feñiz 05-05-2003 19:41:22

Bueno, investigando investigando...

he descubierto que en el ejemplo de mi anterior mensaje:

SetOrdProp (Componente , p, Integer(Pointer(Texto)));

Puede sustituirse perfectamente por:

SetStrProp (Componente, p, 'Texto del caption');

Por si a alguien más le interesa y le puede servir.

__marcsc 05-05-2003 19:43:45

Jejeje, es que me parecía que había una función así, pero cuando quise contestarte la estuve buscando y no la encontré :D

Gracias por el comentario. A ver si me acuerdo para la proxima :rolleyes:

Un saludo.

Gadner 08-05-2003 20:06:07

Las propuestas son validas pero si utilizamos el polimorfismo la cosa puede ser tan simple como:

If Componente is TControl then
TControl(Componente).Caption:='Texto de caption';

Dado que la propiedad caption se implementa ya a nivel de TControl por lo que no necesitas ir mas abajo para actuar sobre dicha propiedad. Delphi se encargara de llamar al metodo de escritura (si lo hubiese) adecuado en funcion de la clase real del componente (eso es polimorfismo).

Saludos

__marcsc 08-05-2003 20:21:55

Hola,

es cierto que la propiedad Caption está definida en TControl, sin embargo la propiedad tiene visibilidad protected con lo cual el código no funcionaría.

Sin embargo es muy sencillo desproteger propiedades, por ejemplo creando una clase heredada de TControl (aprendí este método del amigo roman, del club, aunque supongo que es un clásico :D)

Código:

type
  TUPControl = class(TControl)
begin
  If Componente is TControl then
    TUPControl(Componente).Caption:='Texto de caption';

De todos modos el hilo es una continuación de uno que había en los foros viejos. En el mensaje original preguntaba por la propiedad Text y le dije que no podía utilizar el polimorfismo dado que esa propiedad no existia en ningún ancestro (lo hice después de mirar el help de Delphi). Qué sorpresa la mía hoy al ver que Text también existe en TControl! :D :rolleyes: Si es que mi capacidad de atención está por los suelos :(

Un saludo.


La franja horaria es GMT +2. Ahora son las 18:53:33.

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