RTTI com Delphi 2010.
Boa noite pessoal..
Gostaria de pedir uma ajuda aos amigos do fórum.. tenho a seguinte situação.
Com a nova RTTI do delphi 2010 e possível tirar muito proveito do código, mas me deparei com um caso , vou exemplificar.
Suponha que eu tenha em um form qualquer.
Form1 (TForm) dentro dele Panel1 (TPanel1) dentro dele Label1(TLabel).
Blz. agora com a nota sintaxe da RTTI do delphi 2010 preciso percorrer os objetos até chegar na label1 e recuperar o conteúdo do caption dela.
usando a sintaxe parecida com a abaixo.
Espero ter me expressado bem ..
Agradeço ..
Gostaria de pedir uma ajuda aos amigos do fórum.. tenho a seguinte situação.
Com a nova RTTI do delphi 2010 e possível tirar muito proveito do código, mas me deparei com um caso , vou exemplificar.
Suponha que eu tenha em um form qualquer.
Form1 (TForm) dentro dele Panel1 (TPanel1) dentro dele Label1(TLabel).
Blz. agora com a nota sintaxe da RTTI do delphi 2010 preciso percorrer os objetos até chegar na label1 e recuperar o conteúdo do caption dela.
usando a sintaxe parecida com a abaixo.
for Tabela in Tipo.GetAttributes do for Propriedade in Tipo.GetProperties do for Coluna in Propriedade.GetAttributes do
Espero ter me expressado bem ..
Agradeço ..
Ederson Caldatto
Curtidas 0
Respostas
Marco Salles
03/06/2010
Usamos RTTI em situaçoes que não se consegue usar OO
Porque que vc não acessa diretamente esta propriedade ?????
Outra Observação , que talves esteja passando despercebido para vc é que mesmo
que este Label esteja dentro do Panel como vc mesmo disse o Proprietário desse label
será invariavelmente o Formulario . O Progenitor desse label , este sim , sera o Panel
GOSTEI 0
Ederson Caldatto
03/06/2010
O que estou tentando fazer é o Mapeamento de Objeto relacional para fazera persistencia de objeto no banco, citei o ex, para melhor entendimento, mas o caso que tenho é o seguinte.
Tenho uma Classe e dentro desta tem outras ex Duplicata.
TEmpresa = Class ID: Integer; end; TCLiente = class Empresa: TEmpresa IDCliente : Integer end; TFornecedor = class Empresa: TEmpresa IDFornecedor: Integer end; TDuplicata = class Empresa: TEmpresa IDDup: Integer; Cliente : TCLiente Fornecedor: TFornecedor end; Dup: TDuplicata; Dup.Empresa.ID := 1;Dup.IdDup := 1;Dup.Cliente.IdCliente := 1;
O que estou querendo fazer e em uma classe de persistencia passar um obj, no caso TDuplicata, entao usando RTTI, Context, RTTIProperty, e Atributos, pegar os dados das classes que a duplicata tem referencia ex Percorre meu Objeto Duplicata, quando o atributo for uma outra classe um objeto tbm, faço um Type cast e percorro esta classe até encontrar seu ID.
GOSTEI 0
Marco Salles
03/06/2010
hummm entendi
Vou ver se faço alguma coisa aqui rapidinho , para te dar uma noção Ok
pq o assunto é um pouco delongas
GOSTEI 0
Ederson Caldatto
03/06/2010
Obrigado Marco.. desde já lhe agradeço..
o assunto é muito bom , mas é complicado um pouco =D..
Eu estou usando classe que herdam de TCustomAtributte, assim identifico o nome de minhas class, as chaves da classe e os Fields tbm .. assim na persistência, valido conforme a necessidade.
Até consigo pegar o valor do Objeto so que o retorno do ToString vem (TCliente @ 312345) onde deveria vir o código do mesmo.
o assunto é muito bom , mas é complicado um pouco =D..
Eu estou usando classe que herdam de TCustomAtributte, assim identifico o nome de minhas class, as chaves da classe e os Fields tbm .. assim na persistência, valido conforme a necessidade.
Até consigo pegar o valor do Objeto so que o retorno do ToString vem (TCliente @ 312345) onde deveria vir o código do mesmo.
GOSTEI 0
Marco Salles
03/06/2010
Bem , fiz um pequeno exemplo seguindo inicialmente sua definção de classes
Ainda não implementei o Relacionamento , pq provavelmente teremos que usar RECURSIVIDADE
Modifiquei ainda para a utilização com Interfaces ( pq devemos sempre que possivel Implementar
para Interfaces)
Ficou assim
no formulario principal , coloquei um Botão e um Memo e escrevi o codigo
ps) este codigo é familiar mas não identico ao codigo postado pelo nosso amigo Vitor em seu Artigo
da Revista ClubeDelphi Edição 113 <Não ha muito como fugir disso. Uma vez codigo sempre codigo.
Preferi manter a integra de seus comentários por acha-los oportunos e bem colocados
Modifiquei pequenos trechos para caber em sua colocação inicial e o mais importante implementei o
contador de referencia. Apesar de ser charme dar um obj.Free e mais charme ainda não ter que faze-lo
Entendendo esta parte podemos passar para os Relacionamentos
unit uPessoa;
interface
uses
classes;
Type
IPessoa = Interface
function GetFId: Integer;
procedure SetFId(const Value: Integer);
property ID:Integer read GetFId write SetFId;
End;
Type
TCliente = Class(TInterfacedObject,IPessoa)
private
FId:Integer;
function GetFId: Integer;
procedure SetFId(const Value: Integer);
published
property ID:Integer read GetFId write SetFId;
End;
implementation
{ TPessoa }
function TCliente.GetFId: Integer;
begin
result:=FId;
end;
procedure TCliente.SetFId(const Value: Integer);
begin
FId:=value;
end;
end.
procedure TForm2.Button1Click(Sender: TObject);
var
obj: IPessoa;
MyCliente:TCliente;
infoProps: TPropInfo; //informaçõles sobre a propriedade
plistaProps: PPropList; //ponteiro para array de ponteiros sobre informações da propriedade
listaProps: TPropList; //array de ponteiros para informações da propriedade
i: integer;
totalProps: integer; //valor total de propriedades do objeto
S,Propriedade,Tipo,Valor:string;
begin
//sempre inicialize o ponteiro como nil
plistaProps := nil;
//setando algumas propriedades do nosso objeto
obj := TCliente.Create;
obj.ID:= 1;
MyCliente:=(Obj as TCliente);
try
mTexto.Lines.Add('Propriedade:'+#9#9#9+'Tipo:'+#9#9#9 +'Valor');
//a função GetPropList seta o ponteiro para lista de propriedades e
//também retorna o total de propriedades
totalProps := GetPropList(MyCliente, plistaProps);
//atribundo a listaProps o valor armazenado no endereço plistaProps
listaProps := plistaProps^;
for I := 0 to totalProps - 1 do
begin
//atribuindo a infoProps o valor contido no endereço da posição i do vetor listaProps
infoProps := listaProps[i]^;
if canvas.TextWidth(infoProps.Name) < 46 then
mTexto.Lines.Add(
infoProps.Name+#9#9#9#9+infoProps.PropType^.Name+#9#9#9+
varToStr(getPropValue(MyCliente, infoProps.Name)))
else
mTexto.Lines.Add(
infoProps.Name+#9#9#9+infoProps.PropType^.Name+#9#9#9+
varToStr(getPropValue(MyCliente, infoProps.Name)));
end;
finally
// obj.Free; Trabalhando com Interface temos o contador de Referencia...
//não podemos esquecer de liberar a memoria do ponteiro
FreeMem(plistaProps);
end;
end;
GOSTEI 0
Ederson Caldatto
03/06/2010
Marco ... primeiramente muito obrigado..
vou analisar o código com calma e lhe respondo em seqüência ok..
vou analisar o código com calma e lhe respondo em seqüência ok..
GOSTEI 0