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

Вниз

Простой вопрос по указателю на метод   Найти похожие ветки 

 
Igorek ©   (2003-05-09 16:43) [0]


type
TA = class
procedure f;
end;
var
A: TA;
M: Pointer;
begin
M := A.MethodAddress("f");

//... где то в другом месте
Как вызвать метод по указателю M в контексте обьекта A (Self = A)?


 
Igorek ©   (2003-05-09 17:20) [1]

Никто не знает или все празднуют? :-)


 
default ©   (2003-05-09 17:26) [2]

вот как надо делать:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TMyClass = class
S: String;
procedure P;
end;

var
Form1: TForm1;
O: TMyClass;
PO: procedure of object;

implementation

{$R *.dfm}

procedure TMyClass.P;
begin

Randomize;
S := IntToStr(Random(1000));
Form1.Caption := S

end;

procedure TForm1.Button1Click(Sender: TObject);
begin

O := TMyClass.Create;
PO := O.P;
PO

end;

end.


 
Юрий Зотов ©   (2003-05-09 17:47) [3]

Ну, в таком контексте, можно обойтись и без присваивания PO:=O.P, а просто сразу вызвать метод P. Вопрос же, насколько я понял, сводится к вызову метода по его строковому имени.

type
TA = class
published // Иначе не сработает MethodAddress
procedure F(...);
end;

var
A: TA;
M: TMethod;

type
TF: procedure(...) of object;
// Тип процедуры F

...
M.Code := A.MethodAddress("F");
if M.Code <> nil then
begin
M.Data := A; // Это и будет Self"ом при вызове
TF(M)(...)
end;



 
default ©   (2003-05-09 18:10) [4]

немного дополню пост Юрия Зотова
чтоб не было потом вопросов
(всё таки MethodAddress - метод класса - и его можно вызвать и без объекта,
а "M.Data := A" - без объекта "не потянет")

...
A := TA.Create;
M.Code := A.MethodAddress("F");
if M.Code <> nil then
begin
M.Data := A; // Это и будет Self"ом при вызове
TF(M)(...)
end;


 
Юрий Зотов ©   (2003-05-09 20:24) [5]

Естественно. Подразумевалось, что объект должен быть создан. Но можно и немного хитрее:

M.Code := TA.MethodAddress("F");
if M.Code <> nil then
begin
M.Data := TA.Create; // Это и будет Self"ом при вызове
try
...
TF(M)(...)
...
finally
TObject(M.Data).Free
end
end;



 
_Igorek   (2003-05-11 11:14) [6]

Уже сам разобрался, но все равно всем большое спасибо.
Вопрос вдогонку. Не published методы как вызывать?
Контекст такой: есть TreeView и соотв. TreeNode.Data. В этот Data я запихиваю указатели на методы, что бы потом в OnChange их вызывать. Хотелось бы решение и для "более приватных" методов.


 
_Igorek   (2003-05-12 10:03) [7]

Вопрос интересный. На всякий случай Up.


 
_Igorek   (2003-05-12 11:04) [8]

Как все просто и какой я ленивый.
type
TP = procedure of object;
var
P: TP;
begin
P := PrivateProc
TreeNode.Data := TMethod(P).Code;
...
var
p: TP;
begin
TMethod(p).Data := Pointer(Self);
TMethod(p).Code := TreeView1.Selected.Data;



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

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

Наверх




Память: 0.48 MB
Время: 0.013 c
7-70531
Tolyan
2003-03-24 11:10
2003.05.22
Вход звуковой карты.


7-70529
Tiil
2003-03-23 11:33
2003.05.22
Интерфейс приложений


7-70549
Umar
2003-03-21 18:31
2003.05.22
Функция DeviceloControl


3-70139
AlexA
2003-04-29 16:08
2003.05.22
Как текущию запись в DBGrid е сделать вверхей?


7-70554
Yurique
2003-03-24 13:56
2003.05.22
rundll32 в XP