RTTI - Run Time Type Information
02/04/2006
0
Estou com uma dúvida cruel.. e é por causa desta dúvida que não estou conseguindo terminar meu framework de persistência em Delphi.
Estou precisando capturar as informações contidas em pripriedades de um objeto.
Para quem nunca viu isso, veja o seguinte exemplo:
coloque um componente Button1
E no evento onclick coloque:
var
PropInfo: PPropInfo;
begin
PropInfo := GetPropInfo(Button1.ClassInfo, ´Caption´);
ShowMessage (GetStrProp (Button1, PropInfo);
end;
O resultado será um ShowMessage contendo o conteúdo que está
no caption do Button1. Até aí tudo bem, porém quando eu troco
o objeto Button1 por um objeto de uma classe minha (ex. Classe TPessoa), na hora de capturar o conteúdo através do GetStrProp, ele dá um erro de acesso na memória.
O exemplo seria mais ou menos assim:
var
PropInfo: PPropInfo;
Pessoa: TPessoa;
begin
Pessoa := TPessoa.Create;
//atribuo um valor para uma propriedade chamada Nome
Pessoa.Nome := ´Daniel´;
//tento capturar o conteúdo que está no objeto Pessoa, dentro da
//propriedade ´Nome´ (que tinha que ser ´Daniel´)
PropInfo := GetPropInfo(Pessoa.ClassInfo, ´Nome´);
//Quando irei mostrar o conteúdo dá erro de memória
ShowMessage (GetStrProp (Pessoa, PropInfo);
end;
Não sei qual é a diferença do Objeto Button para o Objeto Pessoa, pois ambos são objetos e herdam da classe TObject.
Alguém poderia me responder essa dúvida?
Um cordial abraço,
Daniel
Netcrusher
Posts
02/04/2006
Marco Salles
Quem sabe ´ele´ vem corrigindo algo que esta preso em mim . Se eu não botar para fora eu vou morrer sem saber
Pelo pouco que eu sei sobre o assunto eu vejo algumas coisas..
1)eu não sei qual o delphi que voce trabalha , mas a partir do delphi 5.0
ja existem rotinas mais sofisticadas , sem a necessidade de recuperar
o ponteiro GetPropInfo e aplicar uma das funçoes de acesso: GetStrProp
por exemplo
var PropInfo: PPropInfo; begin PropInfo := GetPropInfo(Button1.ClassInfo, ´Caption´); ShowMessage (GetStrProp (Button1, PropInfo);
Pode ser substituido por simplesmente:
showmessage(GetPropValue (button1,´caption´);
2)Não sei qual é a diferença do Objeto Button para o Objeto Pessoa, pois ambos são objetos e herdam da classe TObject.
Sim , so que o obejto Button tb herda da TComponent e tem propriedades publicadas(PuBlished) , e essas tecnicas são aplicadas a propriedades publicadas e não simplesmente ha métodos de uma classe
de uma classe que voce definiu
Teste este exemplo:
procedure TForm1.Button1Click(Sender: TObject); var //PropInfo: PPropInfo; Pessoa: TPessoa; begin Pessoa := TPessoa.Create; //atribuo um valor para uma propriedade chamada Nome Pessoa.Nome := ´Daniel´; //tento capturar o conteúdo que está no objeto Pessoa, dentro da //propriedade ´Nome´ (que tinha que ser ´Daniel´) if IsPublishedProp (Pessoa,´Name´) then Showmessage(GetPropValue (Pessoa,´Name´)) else Showmessage(´Nada a apresentar´); if IsPublishedProp (Button1,´Name´) then showmessage(GetPropValue (Button1,´Name´)) else Showmessage(´Nada a apresentar´); end;
3)voce não deve trocar o polimorfismo e outras tecnicas de acesso a propriedades pelos métodos da Unit TypInfo(RTTI)
02/04/2006
Netcrusher
Para se trabalhar com o RTTI, os objetos devem herdar da classe TComponent, pois está especificada na biblioteca da RTTI. Isso não sou eu quem está dizendo, e sim a própria documentação do RTTI.
O que eu fiz foi um FrameWork que persiste um Objeto no banco de dados.
O interessante é que ele persiste qualquer tipo de objeto que seja derivada da classe TComponent.
Eu sei que fica muito estranho dizer que um Objeto de negócio herda da classe TComponent, porém, a solução funcionou.
Valeu pela tentativa..
Um cordial abraço,
Daniel
03/04/2006
Marco Salles
[b:6f76c742eb]e o que eu disse .. Foi diferente[/b:6f76c742eb] ????? :?: :?: :?:
[b:6f76c742eb]Disse a voce que alem de Button ser um tobject ele Herda da TComponent... [/b:6f76c742eb]
[b:6f76c742eb]Acho que voce não leu direitinho[/b:6f76c742eb] :cry: :cry: :cry: :cry:
Porem . disse alem.. Disse que alem de ter que derivar da TComponent esses métodos , são aplicados somente a propriedades Publisheds...
desses objetos derivados da TComponent.. veja o exemplo :
Type Botao =Class(TButton) public MinhaPropriedade : String; end; var myBotao:TBotao; begin MyBotao:=TBotao.create(self); MyBotao.MinhaPropriedae:=´Não é Piublished´; showmessage(GetPropValue (Mybotao,´MinhaPropriedae´)); end;
[b:6f76c742eb]Não ira funcionar , apresar de obedecer teoricamente a condição de derivar da TComponent[/b:6f76c742eb]
03/04/2006
Netcrusher
Porém, mesmo que em uma classe do gênero de negócio como TPessoa, possuindo seus métodos de acesso através dos properties - property (read and write) sendo publisheds, o RTTI não consegue capturar. Eu tentei fazer com que ele capturasse sem que o objeto TPessoa herdasse de TComponente, mas não funcionou (mesmo tendo seus métodos de acesso publicados - published).
Mas é isso aí..
Um abraço
03/04/2006
Marco Salles
Mas voce registrou esse componente :?: :?: , isto é essas propriedades podem ser visualizadas no Objecto inspector de um objeto do tipo TPessoa????
Porque acho que so nesse casso , voce pode persistir os dados usando os métodos anteriores....
03/04/2006
Netcrusher
A única coisa que eu fiz foi declarar que a classe TPessoa herda de TComponent:
Type
Tpessoa = Class (TComponent)
Bom.. se esse te pessoa fosse um objeto registrado (aparecendo na palheta de componentes) o object Inspector com certeza poderia visualizar os atributos e métodos.
Só pra exclarescer mais a minha idéia... é o seguinte...
Através do RTTI, podemos pegar uma classe e capturar todas as propriedades existentes (ex. NOme, Endereço, Bairro, etc.). E tmb, através do RTTI, conseguimos capturar todos os valores existentes no objeto, através de seus atributos.
Então o que o framewrk faz é, persistir um objeto, sem a necessidade de se utilizar seus get´s, e nem fazer referência para um tipo único de classe.
Não sei se vc entendeu...
Tipow.. a coisa é simples... porém... foi difícil de fazer.
Um forte abraço Marcos..
03/04/2006
Marco Salles
isto eu sei...
So que é mais lento e so e recomendavel quando não se puder aplicar polimorfismo ou operadores is e as
isto eu confesso que não sabia ...
Pois é ... eu tinha te dito anteriormente que Para se trabalhar com o RTTI,[b:cde22b2bf0] os objetos devem herdar da classe TComponent[/b:cde22b2bf0], isto a gente concorda , porem ja tinha feito o teste abaixo < Igualzinho como voce esta se referindo >
Type Tpessoa = Class (TComponent) [/quote] public nome:String; end;
procedure TForm1.Button1Click(Sender: TObject); var pessoa:TPessoa; begin pessoa:=TPessoa.create(self); pessoa.Nome:=´Não esto uconseguindo´; showmessage(GetPropValue (pessoa,´nome´)); end;
[b:cde22b2bf0]Mas dá erro [/b:cde22b2bf0], logo deduzi que alem de derivar da[b:cde22b2bf0] TComponenent [/b:cde22b2bf0], seria necessário registrar o componente...Mas voce esta dizendo que dá certo :cry: :cry: :cry: ..[b:cde22b2bf0] Então aonde eu estou errando amigo [/b:cde22b2bf0] :cry: :cry:
03/04/2006
Netcrusher
Ex.:
type TPessoa = class (TComponent)
private
//atributos do objeto Pessoa
strNome : String;
protected
//Get´s
function getNome : String;
// Set´s
procedure setNome ( strNome : string );
//declaração das propriedades públicas de acesso
public
constructor Create;
destructor Destroy;
//propriedades públicadas
published
property Nome : string read getNome write setNome;
end;
Em seguida, é só fazer os get´s e sets.... e Jaúra...
Não existe nenhuma declaração pra registrar o Componente (Register)...
É uma programação Orientada a Componentes (porém.. tudo é objetos)...
Ele persiste componentes do gênero de negócio (business)..
Pra vc listar os atributos.. vc pode fazer assim:
var
Count, Loop: Integer;
List: TPropList;
begin
Count := GetPropList(TypeInfo(TPessoa), tkProperties, @List);
Listbox1.Items.BeginUpdate;
for Loop := 0 to Pred(Count) do
Listbox1.Items.Add(List[Loop]^.Name);
Listbox1.Items.EndUpdate;
Para acessar já seria outro método (já comentado nesse nosso diálogo).
É isso aí...
Um abraço Marcos..
Um cordial abraço,
Daniel
05/04/2006
Marco Salles
Voltemos ao meu primeiro tópico:
[b:4a9495d1c2][color=darkred:4a9495d1c2]eu disse no primeiro típico que era necessário herdar da TComponent e ainda assim estar na secção Published[/color:4a9495d1c2][/b:4a9495d1c2]
so que nesse tópico que lhe mandei , voce me [b:4a9495d1c2]desacreiditou[/b:4a9495d1c2]... :cry: :cry:
[b:4a9495d1c2][color=darkred:4a9495d1c2]Nisso eu returquei , novamente dizendo que não basta so derivar da TComponent , era preciso estar definido na secção Published[/color:4a9495d1c2][/b:4a9495d1c2]
e novamente voce me [b:4a9495d1c2]desacreditou[/b:4a9495d1c2]...
Ai voce me deixou confuso :cry: :cry: ... e nesse momento eu desviei o foco da discusão... e ao ler esse tópico fiz confusão , porque achei que voce tinha derivado da tcomponent e tinha dado errado :cry: :cry:
[b:4a9495d1c2]Ai eu disse ´sem testar´ que era necessario Registar o componente[/b:4a9495d1c2]
essa foi a unica informação [b:4a9495d1c2]ERRADA[/b:4a9495d1c2] que lhe passei , depois de duas certas e voce[b:4a9495d1c2] desacreditando as duas.. [/b:4a9495d1c2]
E ai o tópico caiu em credibilidade e perdeu seu obejetivo porque eu fiquei todo confuso.
Hoje com mais calma parei para reler o tópico.E não encontrei nada Errado nos primeiros tópicos enviados e sim antevendo o que hoje voce ja sabe
Por fim um cordial abraço....
Clique aqui para fazer login e interagir na Comunidade :)