Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-06-2006
JavierSotillos JavierSotillos is offline
Registrado
 
Registrado: abr 2006
Posts: 4
Poder: 0
JavierSotillos Va por buen camino
Obtener lista de procedimientos de un objeto

Hola,

Me guastaria saber como obtener la lista de todos los procedures, function y metodos de un objeto.

Gracias
Responder Con Cita
  #2  
Antiguo 08-06-2006
Sick boy Sick boy is offline
Miembro
 
Registrado: may 2003
Ubicación: Cantabria
Posts: 245
Poder: 22
Sick boy Va por buen camino
En runtime??

Si la respuesta es no, desde el delphi crea un objeto y luego escribe su nombre, pulsa un . y espera a que salga la lista desplegable.

Var
objeto: TObject;

objeto.

La ayuda interactiva del delphi hará el resto.

La verdad es que salvo leer los manuales, no conozco otra forma.
Responder Con Cita
  #3  
Antiguo 08-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

En el artículo Run-Time Type Information (RTTI) in Delphi, de Brian Long, se explica bastante bien cómo puede obtenerse información sobre tipos en tiempo de ejecución. No os perdáis el resto de documentación disponible en la página Web de Brian Long.

Bueno. A lo que vamos. El caso es que no parece demasiado complicado listar los métodos de un determinado objeto, empero, no estoy yo muy puesto en este tema, y así, únicamente puedo listar los métodos correspondientes a los eventos de un formulario, por ejemplo, tal como se ve a continuación:

Código Delphi [-]
uses
  TypInfo;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, numProps: integer;
  propsInfo: PPropList;
begin
  numProps := GetPropList(Self, propsInfo);
  for i := 0 to Pred(numProps) do begin
    if ( propsInfo^[i].PropType^.Kind = tkMethod ) then
    begin
      Memo1.Lines.Add(propsInfo^[i].Name);
    end;
  end;
end;

Sin embargo, como digo, no he conseguido que me incluya en la lista un procedimiento que he puesto a modo de prueba como privado, público y "published". Es el caso que no entiendo muy bien esto y no sé porqué no me lista el método que yo añado al objeto (al formulario, en este caso).

Pero, de cualquier modo, revisa el artículo que te enlazo más arriba, echa un vistazo a la unidad "TypInfo", busca en estos Foros y en Internet en general lo que puedas sobre RTTI (Run-Time Type Information) en Delphi y ya nos contarás lo que sea.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 08-06-2006 a las 18:14:44.
Responder Con Cita
  #4  
Antiguo 08-06-2006
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Es oportuno aclarar no todos los objetos guardan "Run Time Type Information", solo aquellos objetos que implementen clases que han sido declaradas bajo la directiva {$M} y todas las clases heredadas de estas. (Ref.)

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #5  
Antiguo 08-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Federico, ¿cómo es posible que si declaro e implemento un método dentro de un bloque "published" de un formulario, al hacer uso del código de más arriba no me aparezca listado dicho método y sí todos los demás ("OnCreate", "OnShow", etc., etc., etc.)? ¿Sabes algo al respecto? ¿Alguien sabe algo?
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #6  
Antiguo 08-06-2006
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Cita:
Empezado por dec
Federico, ¿cómo es posible que si declaro e implemento un método dentro de un bloque "published" de un formulario, al hacer uso del código de más arriba no me aparezca listado dicho método y sí todos los demás ("OnCreate", "OnShow", etc., etc., etc.)? ¿Sabes algo al respecto? ¿Alguien sabe algo?
¿Hablas de en tiempo de ejecución o del "Code Insight"?
Si es del Code Insight, tenes en cuenta que por defecto aparece los métodos, propiedades y eventos ordenados por Scope y no alfabéticamente?

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #7  
Antiguo 08-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Gracias por responder Federico.

Cita:
Si es del Code Insight, tenes en cuenta que por defecto aparece los métodos, propiedades y eventos ordenados por Scope y no alfabéticamente?
Esa me la apunto, que no me la sabía. Empero, yo me pregunto porqué no puedo obtener en "tiempo de ejecución" el nombre del método que declaro como "published", es decir, de la misma forma que obtengo el nombre de los otros métodos del objeto (formulario, en este caso), como "OnCreate", "OnShow", etc.

Es que se me hace muy raro, pero, evidentemente, tiene que haber una explicación que lo aclare todo, vamos, digo yo.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #8  
Antiguo 08-06-2006
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
No te entiendo.. no los ves cómo?.. usando Rtti??.. tenes el código??
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #9  
Antiguo 08-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por Federico
No te entiendo.. no los ves cómo?.. usando Rtti??.. tenes el código??
Claro, el que más arriba he mostrado:

Código Delphi [-]
uses
  TypInfo;

procedure TForm1.Button1Click(Sender: TObject);
var
  i, numProps: integer;
  propsInfo: PPropList;
begin
  numProps := GetPropList(Self, propsInfo);
  for i := 0 to Pred(numProps) do begin
    if ( propsInfo^[i].PropType^.Kind = tkMethod ) then
    begin
      Memo1.Lines.Add(propsInfo^[i].Name);
    end;
  end;
end;

Ese código lista en un "Memo" todos los métodos del formulario en que se encuentra,... ¿todos? No, un irreductible método que yo mismo declaro e implemento en el bloque "published" del formulario no aparece listado en el "Memo1".
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #10  
Antiguo 08-06-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por dec
Ese código lista en un "Memo" todos los métodos del formulario en que se encuentra,... ¿todos? No, un irreductible método que yo mismo declaro e implemento en el bloque "published" del formulario no aparece listado en el "Memo1".
Podría decirte que lo que pasa es que tal método no está publicado por más que aparezca en la sección published. Claro que la respuesta no dice nada pero es que los formularios son bestias distintas a otros objetos al menos en lo que al IDE se refiere. Y como el IDE y su inspector de objetos se basan en RTTI supongo, aunque no aseguro, que tiene relación una cosa con otra.

En una componente, las propiedades- que no métodos: OnCreate no es un método es una propiedad -publicadas quedan registradas en el IDE al momento de registrar el paquete con RegisterComponents. Pero si añades propiedades publicadas a un formulario, éstas no las detecta el IDE, es decir, no se publican así nada más, puesto que para empezar no hay ningún punto donde uses RegisterComponents.

Para registrar un formulario con el IDE, y que, por tanto, el inspector de objetos publique sus propiedades, necesitas usar RegisterCustomModule. Los detalles puedes verlos en la página de gexperts en la sección de Open Tools. Busca el apartado que dice How can I add published properties to a TForm descendent?.

No sé hasta qué punto tenga que ver una cosa con la otra pero no pierdes nada investigándole.

// Saludos
Responder Con Cita
  #11  
Antiguo 08-06-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por dec
Bueno. A lo que vamos. El caso es que no parece demasiado complicado listar los métodos de un determinado objeto, empero, no estoy yo muy puesto en este tema, y así, únicamente puedo listar los métodos correspondientes a los eventos de un formulario, por ejemplo, tal como se ve a continuación:
Creo que esto hay que aclararlo. No sé, si con RTTI se pueden listar los métodos de un objeto. Lo que sí puede listarse son sus propiedades. Un evento no es un método, es una propiedad cuyo valor es un puntero a un método.

// Saludos
Responder Con Cita
  #12  
Antiguo 09-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Observa el "TTypeKind" Román, el que se utiliza en la sentencia "if" en el código anterior, es decir, se mira si lo que tenemos entre manos es un "tkMethod".

Ahora echa un vistazo al artículo de Brian Long y mira lo que dice de este "TTypeKind":

Cita:
tkMethod: Procedure and function method types value
Yo me he venido guiando por eso. Cierto que los "OnCreate", "OnShow", etc., son propiedades de "TForm", pero, no es menos cierto que el código de arriba los lista cuando le pedimos que liste "tkMethod".

No sé. La verdad es que creo comprender lo que dices perfectamente Román. Quizás todo esto no es más que producto de la poca información de la que se dispone sobre estas cuestiones.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #13  
Antiguo 09-06-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
A ver, tkMethod no significa que tengamos un método entre manos, sino que tenemos una propiedad cuyo tipo de datos es un método. Recuerda, por ejemplo, qué esTNotifyEvent:

Código Delphi [-]
type
  TNotifyEvent = procedure (Sender: TObject) of object;

TNotifyEvent es un tipo de datos; el tipo procedimiento (de objeto).

Si te fijas, la misma función que mencionas, GetPropList, justamente, lo que obtiene es una lista de propiedades, no de métodos, sólo propiedades.

Cuando haces:

Código Delphi [-]
if ( propsInfo^[i].PropType^.Kind = tkMethod ) then

estás aislando sólo aquellas propiedades cuyo tipo de datos es un procedimiento (o función) lo cual incluye todos los eventos (por cierto, se pueden definir eventos que devuelven valores; funciones, aunque nunca he visto uno).

En resumen, no es lo mismo método, que propiedad tipo método.

Si pones

Código Delphi [-]
type
  TMiTipoEvento = procedure (...) of object;

  TForm1 = class(TForm)
  published
    property Algo: Integer;
    property PasaAlgo: TMiTipoEvento;

    procedure HazAlgo;
  end;

GetPropList te listará Algo y PasaAlgo (mostrando que lo que mencioné en el mensaje anterior no es cierto) pero no listará HazAlgo. HazAlgo es un método mientras que PasaAlgo es un propiedad.

// Saludos
Responder Con Cita
  #14  
Antiguo 09-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por Román
GetPropList te listará Algo y PasaAlgo (mostrando que lo que mencioné en el mensaje anterior no es cierto) pero no listará HazAlgo. HazAlgo es un método mientras que PasaAlgo es un propiedad.
Correcto. Llevas toda la razón. Ése es el quid del asunto, pues. Efectivamente ahora consigo que se liste "PasaAlgo", discriminando por el "TypeKind" "tkMethod".

Pues entonces la cosa parece más o menos clara. La cuestión es que debo haber soñado que era posible conseguir también los métodos que no fueran precisamente propiedades...

O lo he soñado, o es que en C# sí que es posible hacer esto, es decir, que puedo estar confundiendo lo que es posible en C# (en este caso) y lo que es posible en Delphi.

Bueno. La cosa queda más o menos clara, pues. Gracias Román. Lo que no sé yo es que pensará el compañero que inició este Hilo, ya nos contará algo, digo yo.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #15  
Antiguo 09-06-2006
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
En principio es possible obtener los "published" metodos de una clase.
Pero no es possible obtener la lista de argumentos.
(Eso es possible, por ejemplo, para metodos de seccion "automated").

Código Delphi [-]
unit main;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,
  PubMeth;
type
  TForm1 = class(TForm)
    BShowMethods: TButton;
    ListBox1: TListBox;
    procedure BShowMethodsClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  {$M+}
  TTest1 = class
  published
    procedure Test1; virtual; abstract;
  end;
  TTest2 = class(TTest1)
  published
    procedure Test2; virtual; abstract;
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.BShowMethodsClick(Sender: TObject);
var
  MethodIterator: TPublishedMethodIterator;
  Cls: TClass;
begin
  ListBox1.Clear;
  MethodIterator := TPublishedMethodIterator.Create;
  Cls := TTest2; //ClassType;
  try
    with MethodIterator do
    begin
       while Cls <> nil do
       begin
        Init(Cls);
        ListBox1.Items.Add(Format('%s, %d methods',[TClass(VMT).ClassName, GetMethodCount]));
        First;
        while (Current <> nil) do
        begin
          ListBox1.Items.Add(Format('     %s: $%p',[Current^.Name, Current^.Address]));
          Next;
        end;
         Cls := Cls.ClassParent;
       end;
    end;
  finally
    MethodIterator.Free;
  end;
end;
end.
 
{-----------------------------------------------------------------------}
 
unit PubMeth; 
interface
uses
 Classes, TypInfo;
type
 PVmtMethod = ^TVmtMethod;
 TVmtMethod = packed record
   Size: Word;
   Address: Pointer;
   Name: ShortString;
 end;
 PVmtMethodTable = ^TVmtMethodTable;
 TVmtMethodTable = packed record
   Count: Word;
   Methods: array [0..MaxListSize] of byte;
   {    Methods : array [0..Count] of TVmtMethod;}
 end;
 TPublishedMethodIterator = class
 private
   FVMT: Pointer;
   FMethodTable: PVmtMethodTable;
   FCurrent: PVmtMethod;
   FCurrentIndex: Integer;
   function CurrentLength: Integer;
 public
   property VMT: Pointer read FVMT;
   property Current: PVmtMethod read FCurrent;
   function GetMethodCount: Integer;
   procedure Init(AClass: TClass);
   function First: PVmtMethod;
   function Next: PVmtMethod;
 end;
function OffsetPtr(P: Pointer; Offset: Integer): Pointer;
implementation
function OffsetPtr(P: Pointer; Offset: Integer): Pointer;
begin
  Integer(Result) := Integer(P) + OffSet;
end;
{ TPublishedMethodIterator }
function TPublishedMethodIterator.GetMethodCount: Integer;
begin
  Result := 0;
  if not Assigned(FMethodTable) then Exit;
  Result := FMethodTable^.Count;
end;
procedure TPublishedMethodIterator.Init(AClass: TClass);
begin
  FMethodTable := nil;
  FVMT := Pointer(AClass);
  FMethodTable := Pointer( OffsetPtr(FVMT, vmtMethodTable)^ );
  FCurrent := nil;
end;
function TPublishedMethodIterator.First: PVmtMethod;
begin
  Result := nil;
  FCurrentIndex := 0;
  if not Assigned(FMethodTable) then Exit;
  FCurrent := Pointer(@FMethodTable.Methods[0]);
  Result := FCurrent;
end;
function TPublishedMethodIterator.CurrentLength: Integer;
begin
  Result := 0;
  if not Assigned(FCurrent) then Exit;
  Result := Current^.Size; // SizeOf(Word) + SizeOf(Pointer) + Length(Current^.Name) + 1;
end;
function TPublishedMethodIterator.Next: PVmtMethod;
begin
  Result := nil;
  if not Assigned(FMethodTable) then Exit;
  if FCurrentIndex + 1 >= GetMethodCount then
  begin
    FCurrent := nil;
  end
  else
  begin
    FCurrent := OffsetPtr(FCurrent, CurrentLength);
    Inc(FCurrentIndex);
  end;
  Result := FCurrent;
end;
end.
Responder Con Cita
  #16  
Antiguo 09-06-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Muchas gracias por tu código fuente Rounin.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como Obtener la lista de alias quetzal Conexión con bases de datos 13 09-06-2015 20:16:57
Obtener lista de ocx registrados rsantosr API de Windows 0 08-10-2005 17:50:47
Obtener la lista de canciones de un Cd mp3 Diana Varios 1 30-11-2004 02:45:26
Obtener Handle de un objeto senpiterno Varios 6 22-04-2004 15:21:40
Obtener lista default charactes set mosorio Conexión con bases de datos 0 17-12-2003 13:49:07


La franja horaria es GMT +2. Ahora son las 11:12:37.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi