PDA

Ver la Versión Completa : Obtener la clase de objetos


Feñiz
04-05-2003, 12:33:49
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:



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)


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.