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

Вниз

Вызов процедур из TList   Найти похожие ветки 

 
Nikolai_S ©   (2003-07-14 15:07) [0]

Мне нужно записать в TList несколько процедур и потом в цикле все их выполнить. Как это реализовать?

Я могу объявить новый тип
TMyProc = procedure of object;

Затем добавляю в список

var
MyProc: TMyProc;
...
MyProc := RealProcedure;
List.Add(@MyProc);

Но как потом вызвать процедуру?


 
Palladin ©   (2003-07-14 15:09) [1]

в обратной последовательности


 
Семен Сорокин ©   (2003-07-14 15:13) [2]

type
PMyProc = ^TmyProc;
TMyProc = procedure of object;

...
PMyProc(List[0])^;


 
Nikolai_S ©   (2003-07-14 15:47) [3]

Ничего не вышло. При вызове выдается ошибка Access Violation.
Еще раз по порядку как я все делаю:

type
PMyProc = ^TMyProc;
TMyProc = procedure of object;


procedure TForm1.RealProc;
begin
// Procedure body
end;


procedure AddProcToList(MyProc: TMyProc);
begin
List.Add(@MyProc);
end;


// заполнение списка
....
AddProcToList(RealProc);
....


// вызов процедур из списка
...
for i := 0 to List.Count - 1 do
PMyProc(List[i])^;
...


При вызове выдается ошибка.


 
Семен Сорокин ©   (2003-07-14 15:55) [4]

procedure TForm1.RealProc;
procedure RealProc;


 
Skier ©   (2003-07-14 15:56) [5]

>Nikolai_S © (14.07.03 15:47)
Неправильно делаешь !
Память под элемент списка должна выделятся
динамически см. New(...)


 
Skier ©   (2003-07-14 15:58) [6]

Я не прав ! Поспешил ! Мои извинения...


 
Nikolai_S ©   (2003-07-14 16:01) [7]

>Семен Сорокин
Спасибо. С этим понятно. А возможно ли теоретически записать в список не статические процедуры, а процедуры, которые являются частью класса, как например, TForm1.RealProc?


 
Толик ©   (2003-07-14 16:02) [8]

А в чём проблема-то?

procedure MyProc1();
begin
ShowMessage("MyProc1");
end;

procedure MyProc2();
begin
ShowMessage("MyProc2");
end;

procedure TForm1.Button5Click(Sender: TObject);
var
i: longint;
begin
with TList.Create do
try
Add(@MyProc1);
Add(@MyProc2);
for i := 0 to Count - 1 do
TProcedure(Items[i])();
finally
Free();
end;
end;


 
Семен Сорокин ©   (2003-07-14 16:04) [9]

Nikolai_S © (14.07.03 16:01)
проще тогда записать в TList объект класса


 
Nikolai_S ©   (2003-07-14 16:10) [10]

>Толик ©
Спасибо. Наконец-то хоть один вариант, который работает. Вопрос закрыт


 
Толик ©   (2003-07-14 16:12) [11]

Для записи процедур-членов-класса следует помнить, что указатель на них занимает 8 байт вместо 4-х, которые помещаются в TList. В этом случае надо использовать указатели на TMethod;


 
Юрий Зотов ©   (2003-07-14 16:12) [12]

Во-первых, тип PMyProc не нужен. Адрес метода уже и так хранится в списке, поэтому при вызове надо только сообщить компилятору, что это именно адрес метода, а не просто указатель:

TMyProc(List[i])

То есть, вызываем так же, как сохраняли (потому что @MyProc уже запишет сам адрес, а не адрес адреса).

И это один возможный источник Access Violation

Во-вторых, как Вы полагаете, что будет передано таким механизмом в RealProc в качестве неявного параметра Self? Я полагаю - что угодно, но только не ссылка на экземпляр TForm1. Поэтому, если в RealProc будет явное или неявное обращение к полям TForm1, то тут же возникнет ошибка. И это второй возможный источник Access Violation.

var
M: TMethod
...
for i := 0 to List.Count - 1 do
begin
M.Code := List[i];
M.Data := Form1;
TMyProc(M);
end;





 
Serginio   (2003-07-14 16:16) [13]

procedure AddProcToList(Var MyProc: TMyProc);
begin
List.Add(@MyProc);
end;


Так как MyProc это переменная типа TMethod.



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

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

Наверх




Память: 0.49 MB
Время: 0.015 c
1-91740
Salvator
2003-07-15 09:53
2003.07.28
Работа с Dll


7-91925
slex
2003-05-19 14:40
2003.07.28
Поиск имён классов


14-91819
mi
2003-07-10 12:11
2003.07.28
Delphi


1-91748
Boroda
2003-07-14 13:39
2003.07.28
FastReport


14-91896
Igor_thief
2003-07-12 13:03
2003.07.28
Component