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

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

Удаление ссылок на удаленные компоненты [D7]


far ©   (2004-08-16 18:08:00) 

Доброго времени суток!

Возникла задача:
Компонент A содержит ссылку на компонент B (published свойство типа B). При удалении компонента B с формы возникает опасная ситуация.
Посоветуйте, пожалуйста, как наилучшим образом обнулить битую ссылку. Компоненты A и B могут находиться на разных формах.

Я посмотрел похожие ситуации в VCL:
(TDataSource.DataSet, TDataSet.Connection) -
DataSet хранит набор DataSources, ссылающихся на него,
Connection хранит набор DataSets, ссылающихся на него.

Можно ли обойти подобную практику? (Естественно, не хочется заводить лишний массив в каждом таком случае)


far   (2004-08-17 12:32:00) [1]


> Юрий Зотов ©   (17.08.04 09:38) [5]

Очень благодарен за внимание. Желаю удачи.


Юрий Зотов   (2004-08-17 09:38:00) [2]

> far ©   (16.08.04 20:05) [4]

Вопрос действительно совсем не общий, но вполне нормальный вопрос. Но "с ходу" на него не ответить, надо копаться в недрах VCL, ходить по ним отдадчиком и смотреть, что это за странная фича такая, и как с ней подружиться можно. Ясно, что никто, кроме Вас, заниматься этим не станет.

Включите птичку "Use febug DCUs", перебилдите пакет, набросайте тестовую программку, в ней добавляйте поля нажатием кнопки - и вперед, в отладчик.


far   (2004-08-16 20:05:00) [3]

Super! Спасибо :)

Юрий, а как насчет
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1092222402&n=12
?

Это слишком специальный вопрос, или слишком глупый? :(


Юрий Зотов   (2004-08-16 19:48:00) [4]

А между тем, в VCL предусмотрен механизм разрешения таких ситуаций. Не обхода, а именно корректного разрешения, причем без всяких дополнительных массивов. Реализуется он замещением метода TA.Notification (а если A и B имеют разных Owner'ов, то еще нужно добавить метод TA.SetB - метод записи свойства B).

Вот схема:

procedure TA.Notification(AComponent: TComponent; Operation: TOperation);
begin
 inherited;
 if (Operation = opRemove) and (AComponent = B) then
   B := nil
end;

procedure TA.SetB(const Value: TB);
begin
 if B <> Value then
 begin
   if B <> nil then
     RemoveFreeNotification(B);
   B := Value;
   if B <> nil then
     FreeNotification(B)
 end
end;


Этот механизм гарантирует, что при любом удалении компонента B свойство A.B автоматически выставится в nil и компонент A перед обращением к B может легко это проверить.

Для примера посмотрите свойство TCustomLabel.FocusControl.


far   (2004-08-16 19:01:00) [5]

Хм... прикольно :)


афвуд   (2004-08-16 18:32:00) [6]

Я обходил это более геморройным способом.
Создавал пустой класс от TComponent(далее "простой класс"). ОН умел только при удалении предупредить обьект основного класса, "меня удаляют".
И делал B.InsertComponent(<обьект этого простого класса>).

При удалении того обьекта(B) вызовется деструктор моего простого
класса(ведь каждый TComponent при удалении себя будет сначала удалять своих Components), а он скажет что меня удаляют - и обьект основного класса будет знать, что по этой ссылке удалили компонент.


Наверх

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