Re: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

2010-07-21 Por tôpico Roni Rodrigo
propriedades da seção published e métodos da public
métodos private e protected não podem ser chamados externos à classe, 
pois isso quebra o paradigma da orientação a objetos
o/

Em 19/07/2010 22:07, Fabricio Colombo escreveu:
 Essa rotina só funciona em um método declarado na seção published, correto?





RES: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

2010-07-21 Por tôpico Rubem Rocha
Então a RTTI foi revisada para atuar no escopo public de objetos. Isso
aconteceu a partir de qual versão do Delphi?

Sds.

 

De: delphi-br@yahoogrupos.com.br [mailto:delphi...@yahoogrupos.com.br] Em
nome de Roni Rodrigo
Enviada em: quarta-feira, 21 de julho de 2010 11:51
Para: delphi-br@yahoogrupos.com.br
Assunto: Re: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

 

  

propriedades da seção published e métodos da public
métodos private e protected não podem ser chamados externos à classe, 
pois isso quebra o paradigma da orientação a objetos
o/

Em 19/07/2010 22:07, Fabricio Colombo escreveu:
 Essa rotina só funciona em um método declarado na seção published,
correto?
 

 



[As partes desta mensagem que não continham texto foram removidas]



Re: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

2010-07-21 Por tôpico Roni Rodrigo
Corrigindo... na empresa a gente usa o 2007 tb... e tem a mesma rotina 
funcionando
não sei quanto as anteriores, pois não lembro de ter utilizado mto a 
rtti
o/

Em 21/07/2010 13:10, Roni Rodrigo escreveu:
 eu to usando a 2010... mas se eu não me engano eu vi isso na 2009 tb...
 o/

 Em 21/07/2010 12:59, Rubem Rocha escreveu:
  Então a RTTI foi revisada para atuar no escopo public de objetos. Isso
  aconteceu a partir de qual versão do Delphi?
 
  Sds.
 
  De: delphi-br@yahoogrupos.com.br 
 mailto:delphi-br%40yahoogrupos.com.br
  mailto:delphi-br%40yahoogrupos.com.br
  [mailto:delphi-br@yahoogrupos.com.br 
 mailto:delphi-br%40yahoogrupos.com.br
  mailto:delphi-br%40yahoogrupos.com.br] Em
  nome de Roni Rodrigo
  Enviada em: quarta-feira, 21 de julho de 2010 11:51
  Para: delphi-br@yahoogrupos.com.br 
 mailto:delphi-br%40yahoogrupos.com.br 
 mailto:delphi-br%40yahoogrupos.com.br
  Assunto: Re: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]
 
  propriedades da seção published e métodos da public
  métodos private e protected não podem ser chamados externos à classe,
  pois isso quebra o paradigma da orientação a objetos
  o/
 
  Em 19/07/2010 22:07, Fabricio Colombo escreveu:
   Essa rotina só funciona em um método declarado na seção published,
  correto?
   



[As partes desta mensagem que não continham texto foram removidas]



Re: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

2010-07-20 Por tôpico Fabricio Colombo
Essa rotina só funciona em um método declarado na seção published, correto?

Em 19 de julho de 2010 20:27, Roni Rodrigo ronirodr...@yahoo.com.brescreveu:



 cara... eu utilizo a RTTI pra fazer chamadas a métodos da classe...
 para manipular os métodos e propriedades eu utilizo helpers para as
 classes da RTTI... se eu não me engano funciona com os métodos de
 qualquer escopo (ou menos da strict private.. não tenho certeza)... na
 verdade esse código eu achei na internet.. no site da embarcadero
 mesmo... mas agora não consegui achar pra passar o link.. então vou
 colocar o exemplo de como eu utilizo aqui

 ---
 Uses TypInfo, ObjAuto, uRClassProperties;
 type

 // declara os helpers para a RTTI
 TParamInfoHelper = record helper for TParamInfo
 public
 function AsString: string;
 function NextParam: PParamInfo;
 end;

 TReturnInfoHelper = record helper for TReturnInfo
 public
 function AsString: string;
 end;

 TMethodInfoHeaderHelper = record helper for TMethodInfoHeader
 private
 function GetReturnInfo: PReturnInfo;
 public
 property ReturnInfo: PReturnInfo read GetReturnInfo;
 end;

 TObjectHelper = class helper for TObject
 public
 function RTTIMethodsAsString: string;
 end;

 function DescriptionOfMethod( Obj: TObject; MethodName: string ): string;

 implementation

 uses
 SysUtils;

 const
 SHORT_LEN = sizeof(ShortString) - 1;

 function DescriptionOfMethod( Obj: TObject; MethodName: string ): string;
 var
 header: PMethodInfoHeader;
 headerEnd: Pointer;
 Params, Param: PParamInfo;
 returnInfo: PReturnInfo;
 begin
 header := ObjAuto.GetMethodInfo( Obj, MethodName );
 if Header.Len = SizeOf(TMethodInfoHeader) - SHORT_LEN +
 Length(Header.Name) then
 begin
 Result := 'No rich RTTI';
 exit;
 end;
 headerEnd := Pointer(Integer(header) + header^.Len);
 Params := PParamInfo(Integer(header) + SizeOf(header^) - SHORT_LEN +
 SizeOf(TReturnInfo) + Length(header^.Name));
 Param := Params;
 Result := '';
 while Integer(Param)  Integer(headerEnd) do
 begin
 Result := Result + Param.AsString + '; ';
 Param := Param.NextParam;
 end;
 Delete( Result, Length(Result)-1,2 );
 returnInfo := header.ReturnInfo;
 if assigned( returnInfo.ReturnType ) then
 Result := Format( 'function %s( %s ): %s', [ MethodName, Result,
 returnInfo.AsString ] )
 else
 Result := Format( 'procedure %s( %s )%s', [ MethodName, Result,
 returnInfo.AsString ] );
 end;

 { TParamInfoHelper }

 function TParamInfoHelper.AsString: string;
 begin
 Result := '';
 if pfResult in Flags then exit;
 Result := Name + ': ' + ParamType^.Name;
 if pfVar in self.Flags then
 Result := 'var ' + Result;
 end;

 function TParamInfoHelper.NextParam: PParamInfo;
 begin
 Result := PParamInfo(Integer(@self) + SizeOf(self) - SHORT_LEN +
 Length(Name));
 end;

 { TMethodInfoHeaderHelper }

 function TMethodInfoHeaderHelper.GetReturnInfo: PReturnInfo;
 begin
 Result := PReturnInfo(Integer(@self) + SizeOf(TMethodInfoHeader) -
 SHORT_LEN + Length(Name));
 end;

 { TReturnInfoHelper }

 function TReturnInfoHelper.AsString: string;
 var
 c: string;
 begin
 Assert( Version = 1, 'Version of ReturnInfo incorrect' );
 if assigned( ReturnType ) then
 Result := ReturnType^.Name;
 Result := Result + ';';
 case CallingConvention of
 ccRegister: ;// Default
 ccCdecl: c := 'cdecl';
 ccPascal: c := 'pascal';
 ccStdCall: c := 'stdcall';
 ccSafeCall: c := 'safecall';
 end;
 if c  '' then Result := Result + ' ' + c + ';';
 end;

 { TObjectHelper }

 function TObjectHelper.RTTIMethodsAsString: string;
 var
 MethodInfo: Pointer;
 Count: Integer;
 method: PMethodInfoHeader;
 i: Integer;
 begin
 MethodInfo := PPointer(Integer(PPointer(self)^) + vmtMethodTable)^;
 if MethodInfo  nil then
 begin
 Count := PWord(MethodInfo)^;
 Inc(Integer(MethodInfo), 2);
 method := MethodInfo;
 for i := 0 to Count - 1 do
 begin
 Result := Result + DescriptionOfMethod(self, method.Name) +
 sLineBreak;
 Inc(Integer(method), PMethodInfoHeader(method)^.Len);
 end;
 end;
 end;

 --

 feito isso, adicione essa unit a Uses que irá fazer as chamadas... e
 utilize normalmente os métodos da RTTI
 para recuperar as informacoes do objeto em um TreeView, por exemplo:

 ---
 procedure GenerateNodes(Obj: TObject; Node: TTreeNode);
 var
 i: byte;
 InternalNode1, InternalNode2, InternalNode3: TTreeNode;
 PropList: PPropList;
 PropListCount: byte;
 MethodInfo: Pointer;
 MethodListCount: byte;
 Method: PMethodInfoHeader;
 begin
 if Assigned(Node) then
 InternalNode1 := Node
 else
 InternalNode1 := TreeView1.Items.Add(nil, Obj.ClassName);
 //Propriedades
 InternalNode2 := TreeView1.Items.AddChild(
 InternalNode1, 'Propriedades');
 PropListCount := GetPropList(Obj, PropList);
 for i := 0 to Pred(PropListCount) do
 begin
 InternalNode3 := TreeView1.Items.AddChild(InternalNode2,
 string(PropList[i].Name) + '=' +
 QuotedStr(
 string(
 GetPropValue(
 Obj,
 string(Proplist[i].Name)
 )
 )
 )
 );
 if PropType(Obj, string( PropList[i].Name )) = 

[delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

2010-07-19 Por tôpico eric_developer
Não consegui resolver e vou deixar isso de lado.
Talvez o delphi não permita (mesmo me parecendo tão ilógico) ou é uma caixa 
preta até mesmo para uma lista de quase 5000 pessoas.

Obrigado aquelas que tentaram ajudar, há uns dias o Bruno da Embarcadero disse 
que era possivel, espero que um dia nos mostre como rsrs, e que não seja nada 
que dependa do Delphi 2010 ou 2020.

Grato,
Eric

--- Em delphi-br@yahoogrupos.com.br, eric_developer developer.syst...@... 
escreveu

 Boa tarde pessoal,
 
 alguem sabe como obter o ponteiro de métodos existentes ? no exemplo, se eu 
 criar o método teste para o form2, funciona, retornando o ponteiro.
 
 No lugar de form2, usarei componentes edit, combobox, etc e metodos 
 existentes.
 
 myCallMethod( edit1, 'SETFOCUS' ) ;
 myCallMethod( form3, 'SETFOCUS' ) ;

 procedure TForm2.teste ;
 begin
   ShowMessage('OLA');
 end;
 
 
 procedure TForm2.Button1Click(Sender: TObject);
 var
routine : TMethod ;
 Begin
 
routine.data:=pointer(form2) ;
routine.Code:=Form2.MethodAddress('teste') ; // Nome do metodo
if routine.Code  nil then
   begin
   ShowMessage('OK');
   end;
 
 end;
 
 Grato,
 Eric Developer Systems





Re: [delphi-br] Re: MethodAddress retornando NIL [CANCELADO]

2010-07-19 Por tôpico Roni Rodrigo
cara... eu utilizo a RTTI pra fazer chamadas a métodos da classe...
para manipular os métodos e propriedades eu utilizo helpers para as 
classes da RTTI... se eu não me engano funciona com os métodos de 
qualquer escopo (ou menos da strict private.. não tenho certeza)... na 
verdade esse código eu achei na internet.. no site da embarcadero 
mesmo... mas agora não consegui achar pra passar o link.. então vou 
colocar o exemplo de como eu utilizo aqui


---
Uses TypInfo, ObjAuto, uRClassProperties;
type

   // declara os helpers para a RTTI
   TParamInfoHelper = record helper for TParamInfo
   public
function AsString: string;
function NextParam: PParamInfo;
   end;

   TReturnInfoHelper = record helper for TReturnInfo
   public
function AsString: string;
   end;

   TMethodInfoHeaderHelper = record helper for TMethodInfoHeader
   private
 function GetReturnInfo: PReturnInfo;
   public
 property ReturnInfo: PReturnInfo read GetReturnInfo;
   end;

   TObjectHelper = class helper for TObject
   public
 function RTTIMethodsAsString: string;
   end;

function DescriptionOfMethod( Obj: TObject; MethodName: string ): string;

implementation

uses
   SysUtils;

const
   SHORT_LEN = sizeof(ShortString) - 1;

function DescriptionOfMethod( Obj: TObject; MethodName: string ): string;
var
   header: PMethodInfoHeader;
   headerEnd: Pointer;
   Params, Param: PParamInfo;
   returnInfo: PReturnInfo;
begin
   header := ObjAuto.GetMethodInfo( Obj, MethodName );
   if Header.Len = SizeOf(TMethodInfoHeader) - SHORT_LEN + 
Length(Header.Name) then
   begin
 Result := 'No rich RTTI';
 exit;
   end;
   headerEnd := Pointer(Integer(header) + header^.Len);
   Params := PParamInfo(Integer(header) + SizeOf(header^) - SHORT_LEN + 
SizeOf(TReturnInfo) + Length(header^.Name));
   Param := Params;
   Result := '';
   while Integer(Param)  Integer(headerEnd) do
   begin
 Result := Result + Param.AsString + '; ';
 Param := Param.NextParam;
   end;
   Delete( Result, Length(Result)-1,2 );
   returnInfo := header.ReturnInfo;
   if assigned( returnInfo.ReturnType ) then
 Result := Format( 'function %s( %s ): %s', [ MethodName, Result, 
returnInfo.AsString ] )
   else
 Result := Format( 'procedure %s( %s )%s', [ MethodName, Result, 
returnInfo.AsString ] );
end;

{ TParamInfoHelper }

function TParamInfoHelper.AsString: string;
begin
   Result := '';
   if pfResult in Flags then exit;
   Result := Name + ': ' + ParamType^.Name;
   if pfVar in self.Flags then
 Result := 'var ' + Result;
end;

function TParamInfoHelper.NextParam: PParamInfo;
begin
   Result := PParamInfo(Integer(@self) + SizeOf(self) - SHORT_LEN + 
Length(Name));
end;

{ TMethodInfoHeaderHelper }

function TMethodInfoHeaderHelper.GetReturnInfo: PReturnInfo;
begin
   Result := PReturnInfo(Integer(@self) + SizeOf(TMethodInfoHeader) - 
SHORT_LEN + Length(Name));
end;

{ TReturnInfoHelper }

function TReturnInfoHelper.AsString: string;
var
   c: string;
begin
   Assert( Version = 1, 'Version of ReturnInfo incorrect' );
   if assigned( ReturnType ) then
 Result := ReturnType^.Name;
   Result := Result + ';';
   case CallingConvention of
 ccRegister: ;// Default
 ccCdecl: c := 'cdecl';
 ccPascal: c := 'pascal';
 ccStdCall: c := 'stdcall';
 ccSafeCall: c := 'safecall';
   end;
   if c  '' then Result := Result + ' ' + c + ';';
end;

{ TObjectHelper }

function TObjectHelper.RTTIMethodsAsString: string;
var
   MethodInfo: Pointer;
   Count: Integer;
   method: PMethodInfoHeader;
   i: Integer;
begin
 MethodInfo := PPointer(Integer(PPointer(self)^) + vmtMethodTable)^;
 if MethodInfo  nil then
 begin
   Count := PWord(MethodInfo)^;
   Inc(Integer(MethodInfo), 2);
   method := MethodInfo;
   for i := 0 to Count - 1 do
   begin
 Result := Result + DescriptionOfMethod(self, method.Name) + 
sLineBreak;
 Inc(Integer(method), PMethodInfoHeader(method)^.Len);
   end;
 end;
end;

--

feito isso, adicione essa unit a Uses que irá fazer as chamadas... e 
utilize normalmente os métodos da RTTI
para recuperar as informacoes do objeto em um TreeView, por exemplo:

---
procedure GenerateNodes(Obj: TObject; Node: TTreeNode);
var
   i: byte;
   InternalNode1, InternalNode2, InternalNode3: TTreeNode;
   PropList: PPropList;
   PropListCount: byte;
   MethodInfo: Pointer;
   MethodListCount: byte;
   Method: PMethodInfoHeader;
begin
   if Assigned(Node) then
 InternalNode1 := Node
   else
 InternalNode1 := TreeView1.Items.Add(nil, Obj.ClassName);
   //Propriedades
   InternalNode2 := TreeView1.Items.AddChild(
  InternalNode1, 'Propriedades');
   PropListCount := GetPropList(Obj, PropList);
   for i := 0 to Pred(PropListCount) do
   begin
 InternalNode3 := TreeView1.Items.AddChild(InternalNode2,
string(PropList[i].Name) + '=' +