Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.14;
Скачать: CL | DM;

Вниз

Удаление ссылок на удаленные компоненты   Найти похожие ветки 

 
far ©   (2004-08-16 18:08) [0]

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

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

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

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


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

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

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


 
far ©   (2004-08-16 19:01) [2]

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


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

А между тем, в 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 20:05) [4]

Super! Спасибо :)

Юрий, а как насчет
http://delphimaster.net/view/5-1092222402/
?

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


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

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

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

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


 
far ©   (2004-08-17 12:32) [6]


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

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



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

Текущий архив: 2005.08.14;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.024 c
11-1104254184
miek
2004-12-28 20:16
2005.08.14
KOL: свежие глюки


1-1122377695
Term
2005-07-26 15:34
2005.08.14
Как отобразить не главные окна своей программы в панели задач Win


3-1120885666
lelik
2005-07-09 09:07
2005.08.14
вопрос по IB DataSet


14-1122088462
Comrade
2005-07-23 07:14
2005.08.14
Copy в C++


1-1122397415
vrem
2005-07-26 21:03
2005.08.14
Richedit или Memo c фоном из рисунка