Форум: "Основная";
Текущий архив: 2002.09.26;
Скачать: [xml.tar.bz2];
ВнизКак удалить компонент его обработчиком? Найти похожие ветки
← →
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 вся ветка
Форум: "Основная";
Текущий архив: 2002.09.26;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.007 c