Clique para saber mais...
  Home     Download     Produtos / Cursos     Revista     Vídeo Aulas     Fórum     Contato   Clique aqui para logar | 12 de Junho de 2026
  Login

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
80 Usuários Online

  Revista ActiveDelphi
 Assine Já!
 Edições
 Sobre a Revista

  Conteúdo
 Apostilas
 Artigos
 Componentes
 Dicas
 News
 Programas / Exemplos
 Vídeo Aulas

  Serviços
 Active News
 Fórum
 Produtos / Cursos

  Outros
 Colunistas
 Contato
 Top 10

  Publicidade

  [Artigos]  Conhecendo um pouco da RTTI. Parte II
Publicado por rboaro : Quarta, Dezembro 19, 2012 - 11:44 GMT-3 (372 leituras)
Comentários comentar   Enviar esta notícia a um amigo Enviar para um amigo   Versão para Impressão Versão para impressão
Diego Garcia Dando continuidade aos estudos sobre a poderosa RTTI do Delphi, como eu havia prometido na primeira parte do artigo, vamos nos aprofundar um pouco mais no TRttiContext no TRttiType e no TRttiField.
- TRttiContext: O TRttiContext é praticamente a parte principal da RTTI, é através dele que se torna possível ter acesso aos métodos e atributos de um objeto em tempo de execução. Como vimos no post anterior, foi através dele que obtivemos toda estrutura do nosso objeto, utilizando o método GetType().
var
ctxRtti : TRttiContext;
typRtti : TRttiType;
begin
typRtti := ctxRtti.GetType(objeto.ClassType);
- TRttiType: O TRttiType por sua vez armazena as informações que foram obtidas com o método GetType do TRttiContext. A partir do momento em que foram armazenadas as informações do type do objeto em um TRttiType é possível acessar qualquer informação deste objeto.
- TRttiField: O TRttiField é responsável por armazenar informações sobre um campo recuperado através de um TRttiType. Com o TRttiField é possível recuperar informações como o nome do campo e seu tipo e até mesmo manipular o valor armazenado neste campo em uma instancia qualquer do objeto em questão.
Para deixar as coisas um pouco mais interessantes, vamos fazer um exemplo prático, primeiramente vamos fazer um método para listar todos os campos disponíveis em um objeto
procedure pegarListaCamposRttiObj(classe: TClass;
linhasRetorno: TStrings);
var
fldRtti: TRttiField;
typRtti: TRttiType;
ctxRtti: TRttiContext;
begin
ctxRtti := TRttiContext.Create;
try
typRtti := ctxRtti.GetType(classe);
for fldRtti in typRtti.GetFields do
linhasRetorno.Add(fldRtti.Name + '<' + fldRtti.FieldType.ToString + '>');
finally
ctxRtti.Free;
end;
end

Agora vamos fazer um método que recupere um TRttiField através do nome do campo

function retornarRttiField(ctxRtti : TRttiContext; classe: TClass; const nomeCampo: String): TRttiField;
var
typRtti : TRttiType;
begin
typRtti := ctxRtti.GetType(classe);
Result := typRtti.GetField(nomeCampo);
end;

Vale ressaltar que este método retornará NIL caso não seja encontrado nenhum campo com o nome passado no parâmetro nomeCampo.
Para finalizar vamos fazer um método para recuperar o valor armazenado neste campo e um método para atribuir um valor qualquer neste campo.

function retornarValorRttiField(objeto : TObject;
const nomeCampo: String): TValue;
var
ctxRtti : TRttiContext;
retorno : TValue;
begin
retorno := nil;
ctxRtti := TRttiContext.Create;
try
try
retorno := retornarRttiField(ctxRtti,objeto.ClassType,nomeCampo).GetValue(objeto);
except
retorno := nil;
end;
finally
ctxRtti.Free;
Result := retorno;
end;
end;

procedure TForm1.setarValorRttiField(objeto: TObject; const nomeCampo : string;
const valor: TValue);
var
ctxRtti : TRttiContext;
begin
ctxRtti := TRttiContext.Create;
try
try
retornarRttiField(ctxRtti,objeto.ClassType,nomeCampo).SetValue(objeto,valor);
except
end;
finally
ctxRtti.Free;
end;
end;
Agora vamos finalmente testar nossos métodos, vamos criar uma classe para realizar o teste.

type
TTesteRtti = class
private
FCampoString : string;
FCampoReal : real;
FCampoBoolean : boolean;
FCampoDate : TDate;
published
property campoString : string read FCampoString write FCampoString;
property campoReal : real read FCampoReal write FCampoReal;
property campoBoolean : boolean read FCampoBoolean write FCampoBoolean;
property campoDate : TDate read FCampoDate write FCampoDate;
end;


Depois, para deixar nosso teste ?mais visual? vamos fazer um form com um EDIT, três BUTTONS, um LISTBOX e um LABEL. No onCreate do Form, crie uma instancia da nossa classe de teste e libere ela no onClose do Form. Em um dos Buttons vamos povoar nosso ListBox com os campos da nossa classe

pegarListaCamposRttiObj(objTesteRtti.ClassType,ListBox1.Items);

Em outro Button, vamos fazer a rotina para setar o valor do Edit em um campo selecionado no ListBox, note que será necessário realizar alguns casts devido ao fato de estarmos trabalhando com String no Edit.

var
valor : TValue;
nomeCampo : string;
tipoCampo : string;
begin
nomeCampo := ListBox1.Items.Strings[ListBox1.ItemIndex];
nomeCampo := Copy(nomeCampo,1,Pos('<',nomeCampo) - 1);

tipoCampo := ListBox1.Items.Strings[ListBox1.ItemIndex];
tipoCampo := Copy(tipoCampo,pos('<',tipoCampo) + 1);
tipoCampo := Copy(tipoCampo,1,length(tipoCampo) -1);

if UpperCase(tipoCampo) = 'STRING' then
valor := TValue.FromVariant(Edit1.Text)
else if UpperCase(tipoCampo) = 'TDATE' then
valor := TValue.FromVariant(StrToDate(Edit1.Text))
else if UpperCase(tipoCampo) = 'BOOLEAN' then
valor := TValue.FromVariant(StrToBool(Edit1.Text))
else if UpperCase(tipoCampo) = 'REAL' then
valor := TValue.FromVariant(StrToFloat(Edit1.Text));

setarValorRttiField(objTesteRtti,nomeCampo,valor);
Para finalizar, vamos fazer no Button que sobrou a rotina para recuperar o valor do campo selecionado no ListBox

var
nomeCampo : string;
begin
nomeCampo := ListBox1.Items.Strings[ListBox1.ItemIndex];
nomeCampo := Copy(nomeCampo,1,Pos('<',nomeCampo) - 1);
Label1.Caption := retornarValorRttiField(objTesteRtti,nomeCampo).ToString;

Pronto, agora nosso teste já está pronto, bastar executá-lo e ir adaptando o conceito de acordo com a sua necessidade.







Um detalhe importante é que ao invés de trabalhar com os campos da classe, poderíamos trabalhar com suas Propertys, basta substituir o TRttiField pelo TRttiProperty.
Na próxima parte do estudo veremos um pouco sobre o TRttiMethod e como poderemos invocar métodos dinamicamente, inclusive com passagem de parâmetro.


Comentários Comentários
   Ordem:  
Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos.
  Edição 112

Revista ActiveDelphi

  50 Programas Fontes


  Produtos

Conheça Nossos Produtos

Copyright© 2001-2016 – Active Delphi – Todos os direitos reservados