Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.52 MB
Время: 0.019 c
15-1180041493
sat
2007-05-25 01:18
2007.06.24
bat file


15-1180096285
oldman
2007-05-25 16:31
2007.06.24
У кого есть "КонсультантПлюс" ???


9-1154586671
vladimirg88
2006-08-03 10:31
2007.06.24
картинка внлубь монитора


2-1180594297
Dimonnnmn
2007-05-31 10:51
2007.06.24
База данных


9-1154442100
nuf
2006-08-01 18:21
2007.06.24
как нарисовать прицел на экране?