![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
List из TNotifyEvent'ов
StriderMan © (2007-04-26 10:42:00)необходимо набить TList ссылками на обработчики типа TNotifyEvent.
Добавляю так
fEventList.Add(@AEvent),где AEvent: TNotifyEvent;
при попытке вызвать процедуру из этого списка валится AV. вызываю так (необходимо дернуть последний в списке ивент):
if fEventList.Count > 0 then
TNotifyEvent(fEventList.Items[fEventList.Count - 1]^)(Sender);
Сергей М. (2007-04-26 12:33:00) [1]
> StriderMan © (26.04.07 12:30) [21]
>
>
> если передать как var или const по-идее должно работать
Как var - да, будет работать.
А как const - нет, не будет.
StriderMan (2007-04-26 12:30:00) [2]
> Сергей М. © (26.04.07 12:27) [20]
> Ну тогда понятно, почему у тебя "не прокатило".
я уже и сам понял :)
кстати если передать как varили constпо-идее должно работать.
В любом случае, огромное спасибо за помощь! про TMethod я право совсем забыл.
Сергей М. (2007-04-26 12:27:00) [3]
> StriderMan © (26.04.07 12:17) [19]
> параметр ф-ии
Ну тогда понятно, почему у тебя "не прокатило".
Я привел код для случая, когда AEvent есть либо поле класса либо статическая переменная - только в этом случае адрес будет не изменен.
StriderMan (2007-04-26 12:17:00) [4]
> Сергей М. © (26.04.07 12:15) [18]
>
> > вылазит какой-то мусор
>
>
> AEvent: TNotifyEvent - это что, поле класса или лок.переменная
> ?
параметр ф-ии
procedure TScaner.SetOnDataEvent(AValue: TNotifyEvent);
begin
if not Assigned(AValue) then
begin
if fEventList.Count > 0 then
fEventList.Delete(fEventList.Count - 1);
end
else
fEventList.Add(AValue);
end;
Сергей М. (2007-04-26 12:15:00) [5]
> вылазит какой-то мусор
AEvent: TNotifyEvent - это что, поле класса или лок.переменная ?
StriderMan (2007-04-26 12:04:00) [6]
> Сергей М. © (26.04.07 11:51) [15]
> Ну тогда вот так:
> EventList.Add(@AEvent);
так не прокатило. похоже структура TMethod разрушается где-то и при восстановлении в .Code и .Data вылазит какой-то мусор.
выкрутился так:
type
PMethod = ^TMethod;
procedure TEventList.Add(AItem: TNotifyEvent);
var
p: PMethod;
begin
new(p);
p^ := TMethod(AItem);
inherited Add(p);
end;
function TEventList.GetItems(AIndex: integer): TNotifyEvent;
begin
Result := TNotifyEvent(PMethod(inherited Items[AIndex])^);
end;
> Игорь Шевченко © (26.04.07 11:52) [16]
> Сделать свой List ?
уже
Игорь Шевченко (2007-04-26 11:52:00) [7]
> тогда открытым остается вопрос куда его в List'е сохранить
> :)
Сделать свой List ?
Сергей М. (2007-04-26 11:51:00) [8]Ну тогда вот так:
AEvent: TNotifyEvent;
..
EventList.Add(@AEvent);
..
type
PMethod = ^TMethod;
var
Method: TMethod;
..
Method.Code := PMethod(EventList.Items[..]).Code;
Method.Data := PMethod(EventList.Items[..]).Data;
TNotifyEvent(Method)(SomeSender);
StriderMan (2007-04-26 11:45:00) [9]
> Сергей М. © (26.04.07 11:37) [13]
> А зачем его хранить ?
> Ну, предположим, сохранишь ты его, а потом возьмешь да и
> уничтожишь объект, из которого ты скопировал в список эту
> структуру. Спрашивается, к какому объекту ты обратишься
> при вызове сохраненного тобой "обработчика" ?
такого не должно произойти. Классы в которых расположены методы-обработчики при разрушении удаляют ссылку на свой обработчик из fEventList. коряво конечно, согласен. Но переделывать сейчас все на сообщения - нет возможности.
Сергей М. (2007-04-26 11:37:00) [10]
> StriderMan © (26.04.07 11:31) [12]
А зачем его хранить ?
Ну, предположим, сохранишь ты его, а потом возьмешь да и уничтожишь объект, из которого ты скопировал в список эту структуру. Спрашивается, к какому объекту ты обратишься при вызове сохраненного тобой "обработчика" ?
StriderMan (2007-04-26 11:31:00) [11]
> Сергей М. © (26.04.07 11:30) [11]
> А, ну дык конечно !
> поле Method.Data трогать нельзя
тогда открытым остается вопрос куда его в List'е сохранить :)
Сергей М. (2007-04-26 11:30:00) [12]
> StriderMan © (26.04.07 11:26) [10]
А, ну дык конечно !
Ты же в обработчике обращаешься к св-вам/методам конкретного экз-ра конкретного объекта. Значит в этомслучае поле Method.Data трогать нельзя - оно как раз и хранит адрес этого экз-ра, тот самый который в теле обработчика будет фигурировать как Self.
StriderMan (2007-04-26 11:26:00) [13]
procedure TfrmTuneData.OnScanerEvent(Sender: TObject);
begin
if Active and (pcMain.ActivePage = TSWare) then //на эту строку попадаем, дальше AV
begin
edtBarcode.Text := ScanerListAdm.ScanerAX.Ole.ScanData;
ScanerListAdm.ScanerAX.Ole.DeleteEvent;
end;
end;
Сергей М. (2007-04-26 11:21:00) [14]Показывай обработчик ...
StriderMan (2007-04-26 11:21:00) [15]
> TMethod(AEvent).Data := nil; //если не обнулить, self в
> теле обработчика в общем случае м.б. неопределен
А если мы обнулили, то в Self что попадет?
просто опять AV. В обработчик уже попадает, но на первой же строчке сваливается.
Сергей М. (2007-04-26 11:09:00) [16]
> StriderMan © (26.04.07 11:01) [6]
Ну, скажем, вот так:
AEvent: TNotifyEvent;
..
EventList.Add(TMethod(AEvent).Code);
TMethod(AEvent).Code := EventList.Items[..];
TMethod(AEvent).Data := nil; //если не обнулить, self в теле обработчика в общем случае м.б. неопределен
AEvent(SomeSender); //собственно вызов
StriderMan (2007-04-26 11:01:00) [17]
> Сергей М. © (26.04.07 10:59) [5]
и как посоветуете выкрутиться?
Сергей М. (2007-04-26 10:59:00) [18]
> StriderMan © (26.04.07 10:56) [4]
Ты берешь адрес структуры TMethod, а не адрес обработчика, на который ссылается поле Code этой структуры.
StriderMan (2007-04-26 10:56:00) [19]
> Сергей М. © (26.04.07 10:55) [3]
> У TNotifyEvent, разумеется, у кого же еще ?
так я же адрес его беру а не его сам
Сергей М. (2007-04-26 10:55:00) [20]
> у кого?
>
У TNotifyEvent, разумеется, у кого же еще ?