Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.31;
Скачать: CL | DM;

Вниз

Как достать список методов объекта ?   Найти похожие ветки 

 
ANB ©   (2005-07-12 17:04) [0]

Или хотя бы проверить, что метод существует, а потом вызвать его (например, если он без параметров) ? Для свойств все сделал. И вообще, возможно ли это ?


 
begin...end ©   (2005-07-12 17:06) [1]

> ANB ©   (12.07.05 17:04)
> И вообще, возможно ли это ?

Это возможно, но только для published-методов.


 
oldman ©   (2005-07-12 17:08) [2]

Имхо, если ты хочешь вызвать метод, то знаешь зачем.
Объект у тебя есть.
F1 тоже есть.
В хелпе есть вкладка "методы объекта"...
Там все перечислено.


 
MBo ©   (2005-07-12 17:09) [3]

Я так понимаю, что требуется по имени - тогда для published - возможно. GetMethodProp, MethodAddress, TMethod


 
MBo ©   (2005-07-12 17:13) [4]

а получить список - GetPropList


 
ANB ©   (2005-07-12 17:18) [5]

MethodAddress - не достает (возвращает nil). Может потому что я класс не привожу ? (вызываю как для TComponent, а реально там TToolButton, метод Click,строка = "Click").
Ща попробую GetMethodProp.
И поищу в хелпе TMethod.


> oldman ©   (12.07.05 17:08) [2]
- я не знаю заранее, какой будет объект и есть ли у него данный метод, так как возможны ошибки пользователя, при этом надо не заваливаться, а возвращать корректную ошибку.

А кто нибудь может привести пример какого нибудь published метода из VCL ?


 
DiamondShark ©   (2005-07-12 17:20) [6]


> TToolButton, метод Click

А он не published.


 
oldman ©   (2005-07-12 17:21) [7]


> я не знаю заранее, какой будет объект


Как это? (опупеваю)


 
Ega23 ©   (2005-07-12 17:24) [8]

Clear


 
ANB ©   (2005-07-12 17:26) [9]


> Как это? (опупеваю)
- подкладку пишу под базовые формы. Чтобы тестировочный робот мог из другого приложения через VCL работать. Самые важные вещи жестко зашил, а кое что на универсал хочу повесить, чтобы код не сильно разбухал.


 
DiamondShark ©   (2005-07-12 17:28) [10]


> А кто нибудь может привести пример какого нибудь published
> метода из VCL ?

Их нет ни одного.


> я не знаю заранее, какой будет объект

А я знаю.
Он стопудово будет TObject.
Если это какая-то байда, кидаемая на форму, то оно стопудово будет TComponent.
Многие компоненты порождены от не очень большого количества абстракных классов, которые содержат большое число заранее известных методов.
Принадлежность объекта к нужному уровню иерархии определяется оператором is.


 
ANB ©   (2005-07-12 17:34) [11]


> А я знаю.
> Он стопудово будет TObject.
> Если это какая-то байда, кидаемая на форму, то оно стопудово
> будет TComponent.
- дык и я знаю. А как до метода то по имени в строке тогда достучаться ? Не жрет и Clear. Через is я уже сделал специфические методы. Методы с параметрами универсально вызвать у меня вряд ли получится, так как там нужно параметры правильно передавать. А вот без параметров хотелось бы вызывать просто по имени.


 
reonid ©   (2005-07-12 20:14) [12]

// Poluchenie spiska published metodov
// (napisal sto let nazad)

procedure TMainForm.BShowMethodsClick(Sender: TObject);
var
MethodIterator: TPublishedMethodIterator;
Cls: TClass;
begin
ListBox.Clear;
MethodIterator := TPublishedMethodIterator.Create;
Cls := ClassType;

try
  with MethodIterator do
  begin
//      while Cls <> nil do
//      begin
      Init(Cls);
      ListBox.Items.Add(Format("%s, %d methods",[TClass(VMT).ClassName, GetMethodCount]));
      First;
      while (Current <> nil) do
      begin
        ListBox.Items.Add(Format("     %s: $%p",[Current^.Name, Current^.Address]));
        Next;
      end;
//        Cls := Cls.ClassParent;
//      end;
  end;
finally
  MethodIterator.Free;
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.


 
ANB ©   (2005-07-13 09:41) [13]


> reonid ©   (12.07.05 20:14) [12]
- спасибо, но паблишед методов то практически не бывает. Обычно, это обработчики событий, а они мне не нужны. Таки придется ставить case и is и использовать честное приведение типов. Соответственно, универсальности не будет.


 
Ega23 ©   (2005-07-13 09:44) [14]

В общем случае, боюсь, не получится. Я как-то пытался создать универсальную функцию логгирования исключений. Ну там, чтобы ClassName, InstanseName и MethodName в лог отписывала на exception. Помучился, да и забил на это дело. В published всё не вынесешь, а как правило, основная работа в private идёт...


 
ANB ©   (2005-07-13 10:03) [15]


> Ega23 ©   (13.07.05 09:44) [14]
- вот этого я, в принципе, и ждал. Я нашел решение - вытереть этот кусок кода и не мучится. Нужные методы для нужных классов можно и ручками обработать. Все равно для большинства из них нужно параметры передавать.



Страницы: 1 вся ветка

Текущий архив: 2005.07.31;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.026 c
1-1120999072
B-S-G
2005-07-10 16:37
2005.07.31
Изменить исполняемый файл


14-1120707744
X9
2005-07-07 07:42
2005.07.31
Бесплатный домен 2-го уровня


1-1121338623
BANick
2005-07-14 14:57
2005.07.31
обясните как переопределить interface (IBindStatusCallback)


1-1121327926
Ascana
2005-07-14 11:58
2005.07.31
Тормозит компонент TListView


1-1121330036
AGGRESSOR
2005-07-14 12:33
2005.07.31
PAGE FAULT IN NONPAGED AREA