Форум: "Основная";
Текущий архив: 2003.07.28;
Скачать: [xml.tar.bz2];
ВнизВызов процедур из 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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.005 c