![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как удалить компонент его обработчиком? [D5, Win95/98]
eLVik © (2002-09-12 18:36:00)У меня ламерский вопрос. На форме имеется компонент, созданный в run-time.
К нему прицеплен обработчик события OnClick. Можно ли в этом обработчике уничтожить данный компонент, чтобы не вылетал EAbstract Error? Прочитал в FAQ нечто похожее, но там не написано как разрешить эту проблему или это в принципе невозможно?
Заранее спасибо за помощь!
eLVik (2002-09-13 15:54:00) [1]Всё! Всем спасибо за участие! Тема закрыта, вопросов больше не имею!
Старый Паскалист (2002-09-13 15:27:00) [2]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)
то оно было бы обработано сразу же)
Song (2002-09-13 15:04:00) [3]Посылай сообщение, WM_USER например. А в форме его лови и делай Free для нужного тебе компонента. По-моему, MBo всё популярно рассказал...
eLVik (2002-09-13 14:40:00) [4]Спасибо за старания, но можно ли по подробнее про PostMessage?
Song (2002-09-13 08:41:00) [5]Free делать нельзя. Можно Release, если он доступен.
KSergey (2002-09-13 08:12:00) [6]Удалить компонент в его же обработчике нельзя.
Как делать - написал MBo © (12.09.02 18:38)
[Стоит, пожалуй, заметить, что была как-то здесь дискуссия про удаление формы, так вот там я приводил пример из VCL, где форма сама себя нагло же и уничтожает вызовом Free, но этот Free стоит последним оператором в методе! Впрочем, возможно именно для формы борланд как-нибудь хитро извернулась, т.е. в общем случае так делать явно не стоит]
MBo (2002-09-12 18:38:00) [7]послать ( PostMessage) сообщение форме, по которому она удалит компонент