Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как удалить компонент его обработчиком? [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) сообщение форме, по которому она удалит компонент


Наверх

Титульная страница Поиск, карта сайта Написать письмо