Главная страница
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.013 c
3-91622
Step[B.M.]
2003-07-04 08:57
2003.07.28
Триггер InterBase


3-91649
здесь был Вася
2003-07-05 11:02
2003.07.28
Access


3-91635
Вит
2003-07-04 15:35
2003.07.28
Как в FreeReport увидеть кирилицу в


3-91626
Яндекс2
2003-07-04 11:39
2003.07.28
Как реализовать на FB выдачу р-тов порциями?


14-91886
neuro
2003-07-11 21:03
2003.07.28
Как башкир по-английски?