Вниз
Скачать: CL | DM;

Как удалить компонент его обработчиком?   Найти похожие ветки 

← →
eLVik   (2002-09-12 18:36) [0]

У меня ламерский вопрос. На форме имеется компонент, созданный в run-time.
К нему прицеплен обработчик события OnClick. Можно ли в этом обработчике уничтожить данный компонент, чтобы не вылетал EAbstract Error? Прочитал в FAQ нечто похожее, но там не написано как разрешить эту проблему или это в принципе невозможно?
Заранее спасибо за помощь!


← →
MBo ©   (2002-09-12 18:38) [1]

послать ( PostMessage) сообщение форме, по которому она удалит компонент


← →
KSergey ©   (2002-09-13 08:12) [2]

Удалить компонент в его же обработчике нельзя.
Как делать - написал MBo © (12.09.02 18:38)

[Стоит, пожалуй, заметить, что была как-то здесь дискуссия про удаление формы, так вот там я приводил пример из VCL, где форма сама себя нагло же и уничтожает вызовом Free, но этот Free стоит последним оператором в методе! Впрочем, возможно именно для формы борланд как-нибудь хитро извернулась, т.е. в общем случае так делать явно не стоит]


← →
Song ©   (2002-09-13 08:41) [3]

Free делать нельзя. Можно Release, если он доступен.


← →
eLVik   (2002-09-13 14:40) [4]

Спасибо за старания, но можно ли по подробнее про PostMessage?


← →
Song ©   (2002-09-13 15:04) [5]

Посылай сообщение, WM_USER например. А в форме его лови и делай Free для нужного тебе компонента. По-моему, MBo всё популярно рассказал...


← →
Старый Паскалист   (2002-09-13 15:27) [6]

2eLVik

В чём тут вообще проблема?
В том, что обработчики событий вызываются в основном по такой схеме:

procedure TSomething.DoEvent; // диспетчерский метод.
begin
SomeCodeBefore;
if Assigned(FOnEvent) then FOnEvent(Self); // вызывается обработчик события (если он назначен)
SomeCodeAfter;
end;

Т.е. обработчик события может быть окружён каким-либо кодом.
Причём DoEvent сама вызывается из какой-нибудь ф-и,
обычно из обработчика сообщения, и тоже может быть окружена кодом:

procedure WMEvent(var Msg: TMessage); // message WM_EVENT;
begin
SomeCodeBeforeDoEvent;
DoEvent;
SomeCodeAfterDoEvent;
end;

Если в FOnEvent будет вызван Free,
то SomeCodeAfter при попытке обратиться к полям объекта
или вызвать виртуальную ф-ю
обратится к уже несуществующему объекту со всеми вытекающими последствиями.

Обойти это можно вызвав в обработчике
PostMessage(Handle, CM_RELEASE, 0, 0)
Так мы помещаем в очередь сообщений потока, в котором создана форма, сообщение CM_RELEASE для нашей формы.

Выполнение кода в одном потоке линейно, поэтому это сообщение будет достано из очереди и передано форме уже после того, как отработает DoEvent (и WMEvent).

В обработчике этого сообщения форма просто вызовет Free. И всё.

(Если бы ты попытался передать сообщение через
SendMessage(Handle, CM_RELEASE, 0, 0), (или Perform)
то оно было бы обработано сразу же)


← →
eLVik   (2002-09-13 15:54) [7]

Всё! Всем спасибо за участие! Тема закрыта, вопросов больше не имею!



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.46 MB
Время: 0.013 c
3-85412
kavlad
2002-09-05 20:25
2002.09.26
BLOB Stream возвращает 0 размер.


6-85642
HEugene
2002-07-25 08:50
2002.09.26
генератор пакетов


1-85556
Skywalker
2002-09-12 12:14
2002.09.26
Debugger


1-85609
bedny
2002-09-14 20:02
2002.09.26
sc_data.txt --> TreeWiev


1-85547
NVladimir
2002-09-12 14:27
2002.09.26
Объем программы в ОЗУ




   Наверх