Главная страница
    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.49 MB
Время: 0.056 c
1-1121157299
webpauk
2005-07-12 12:34
2005.07.31
ToolButton и DropDownMenu


14-1120916014
Desam
2005-07-09 17:33
2005.07.31
Системы платежа


1-1121090924
webpauk
2005-07-11 18:08
2005.07.31
Глюки с закрытием приложения


6-1113825040
Roman001
2005-04-18 15:50
2005.07.31
Коннект к веб серверу


1-1121348616
SS
2005-07-14 17:43
2005.07.31
Анализ текстового файла





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский