Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.07.31;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.033 c
1-1121334287
Caridi
2005-07-14 13:44
2005.07.31
"Поймать" и обработать Enter


1-1120944230
MAVr
2005-07-10 01:23
2005.07.31
Как достать свойства файла?


4-1117790647
GrayFace
2005-06-03 13:24
2005.07.31
По поводу "запуздыривания" иконки в Tray


14-1121252270
SecCenter
2005-07-13 14:57
2005.07.31
Умирает сайт.


3-1118912565
Лиса
2005-06-16 13:02
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
Английский Французский Немецкий Итальянский Португальский Русский Испанский