Текущий архив: 2007.06.24;
Скачать: CL | DM;
Вниз
List из TNotifyEvent ов Найти похожие ветки
← →
StriderMan © (2007-04-26 10:42) [0]необходимо набить TList ссылками на обработчики типа TNotifyEvent.
Добавляю так
fEventList.Add(@AEvent),
где AEvent: TNotifyEvent;
при попытке вызвать процедуру из этого списка валится AV. вызываю так (необходимо дернуть последний в списке ивент):if fEventList.Count > 0 then
TNotifyEvent(fEventList.Items[fEventList.Count - 1]^)(Sender);
← →
_Аноним © (2007-04-26 10:50) [1]У него размер - 8
← →
StriderMan © (2007-04-26 10:53) [2]
> _Аноним © (26.04.07 10:50) [1]
> У него размер - 8
пардон, у кого?
← →
Сергей М. © (2007-04-26 10:55) [3]
> у кого?
>
У TNotifyEvent, разумеется, у кого же еще ?
← →
StriderMan © (2007-04-26 10:56) [4]
> Сергей М. © (26.04.07 10:55) [3]
> У TNotifyEvent, разумеется, у кого же еще ?
так я же адрес его беру а не его сам
← →
Сергей М. © (2007-04-26 10:59) [5]
> StriderMan © (26.04.07 10:56) [4]
Ты берешь адрес структуры TMethod, а не адрес обработчика, на который ссылается поле Code этой структуры.
← →
StriderMan © (2007-04-26 11:01) [6]
> Сергей М. © (26.04.07 10:59) [5]
и как посоветуете выкрутиться?
← →
Сергей М. © (2007-04-26 11:09) [7]
> 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:21) [8]
> TMethod(AEvent).Data := nil; //если не обнулить, self в
> теле обработчика в общем случае м.б. неопределен
А если мы обнулили, то в Self что попадет?
просто опять AV. В обработчик уже попадает, но на первой же строчке сваливается.
← →
Сергей М. © (2007-04-26 11:21) [9]Показывай обработчик ...
← →
StriderMan © (2007-04-26 11:26) [10]
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:30) [11]
> StriderMan © (26.04.07 11:26) [10]
А, ну дык конечно !
Ты же в обработчике обращаешься к св-вам/методам конкретного экз-ра конкретного объекта. Значит в этом случае поле Method.Data трогать нельзя - оно как раз и хранит адрес этого экз-ра, тот самый который в теле обработчика будет фигурировать как Self.
← →
StriderMan © (2007-04-26 11:31) [12]
> Сергей М. © (26.04.07 11:30) [11]
> А, ну дык конечно !
> поле Method.Data трогать нельзя
тогда открытым остается вопрос куда его в List"е сохранить :)
← →
Сергей М. © (2007-04-26 11:37) [13]
> StriderMan © (26.04.07 11:31) [12]
А зачем его хранить ?
Ну, предположим, сохранишь ты его, а потом возьмешь да и уничтожишь объект, из которого ты скопировал в список эту структуру. Спрашивается, к какому объекту ты обратишься при вызове сохраненного тобой "обработчика" ?
← →
StriderMan © (2007-04-26 11:45) [14]
> Сергей М. © (26.04.07 11:37) [13]
> А зачем его хранить ?
> Ну, предположим, сохранишь ты его, а потом возьмешь да и
> уничтожишь объект, из которого ты скопировал в список эту
> структуру. Спрашивается, к какому объекту ты обратишься
> при вызове сохраненного тобой "обработчика" ?
такого не должно произойти. Классы в которых расположены методы-обработчики при разрушении удаляют ссылку на свой обработчик из fEventList. коряво конечно, согласен. Но переделывать сейчас все на сообщения - нет возможности.
← →
Сергей М. © (2007-04-26 11:51) [15]Ну тогда вот так:
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);
← →
Игорь Шевченко © (2007-04-26 11:52) [16]
> тогда открытым остается вопрос куда его в List"е сохранить
> :)
Сделать свой List ?
← →
StriderMan © (2007-04-26 12:04) [17]
> Сергей М. © (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 12:15) [18]
> вылазит какой-то мусор
AEvent: TNotifyEvent - это что, поле класса или лок.переменная ?
← →
StriderMan © (2007-04-26 12:17) [19]
> Сергей М. © (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:27) [20]
> StriderMan © (26.04.07 12:17) [19]
> параметр ф-ии
Ну тогда понятно, почему у тебя "не прокатило".
Я привел код для случая, когда AEvent есть либо поле класса либо статическая переменная - только в этом случае адрес будет не изменен.
← →
StriderMan © (2007-04-26 12:30) [21]
> Сергей М. © (26.04.07 12:27) [20]
> Ну тогда понятно, почему у тебя "не прокатило".
я уже и сам понял :)
кстати если передать как var или const по-идее должно работать.
В любом случае, огромное спасибо за помощь! про TMethod я право совсем забыл.
← →
Сергей М. © (2007-04-26 12:33) [22]
> StriderMan © (26.04.07 12:30) [21]
>
>
> если передать как var или const по-идее должно работать
Как var - да, будет работать.
А как const - нет, не будет.
Страницы: 1 вся ветка
Текущий архив: 2007.06.24;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.045 c