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

Вниз

Уничтожение TWinControl.Controls   Найти похожие ветки 

 
StriderMan   (2009-03-24 13:18) [0]

Возник такой теоретический вопрос: зачем TWinControl обходит список своих контролов Controls и вызывает им деструкторы? Ведь эти же контролы должные быть разрушены своими Owner"ами, которые в общем случае не совпадают с Parent"ами.

Собственно наступил на грабли, что контрол уже разрушен мною а его Parent пытается это сделать еще раз и получает AV.

Как решается эта проблема в самом VCL пока не нашел


 
Palladin ©   (2009-03-24 13:31) [1]


> StriderMan   (24.03.09 13:18) 

Года три назад я тоже так считал. Пока меня LVT носом не ткнул в справку по Parent.


 
Palladin ©   (2009-03-24 13:33) [2]


> Как решается эта проблема в самом VCL пока не нашел

Не ищи решения того чего нет )


 
StriderMan   (2009-03-24 14:14) [3]


> Года три назад я тоже так считал

Я никак не считаю, мне интересно почему сделано именно так


 
StriderMan   (2009-03-24 14:18) [4]

Чтобы не быть голословным:

destructor TWinControl.Destroy;
var
 I: Integer;
 Instance: TControl;
begin
......
 I := ControlCount;
 while I <> 0 do
 begin
   Instance := Controls[I - 1];
   Remove(Instance);
   Instance.Destroy;
   I := ControlCount;
 end;
....
end;


 
Palladin ©   (2009-03-24 14:19) [5]

Ну мое мнение - это экономия на системных объектах.


 
StriderMan   (2009-03-24 14:20) [6]

собственно хэлп не проливает свет на вопрос почему именно так:

The Parent property declared in TControl is similar to the Owner property declared in TComponent, in that the Parent of a control frees the control just as the Owner of a component frees that Component. However, the Parent of a control is always a windowed control that visually contains the control, and is responsible for writing the control to a stream when the form is saved. The Owner of a component is the component that was passed as a parameter in the constructor and, if assigned, initiates the process of saving all objects (including the control and its parent) when the form is saved.


 
StriderMan   (2009-03-24 14:26) [7]


> Ну мое мнение - это экономия на системных объектах

Мне кажется это защита от тех, кому лень отслеживать время жизни своих объектов. Своеобразная перестраховка от утечки памяти


 
Palladin ©   (2009-03-24 14:28) [8]

Взять посмотреть на это со стороны IDE, ты накидал на панель контролов, потом взял и удалил панель, контролы должны остаться? Во времени исполнения тоже самое, не устанешь реализовывать слежку за  контролами?


 
StriderMan   (2009-03-24 14:29) [9]


> Как решается эта проблема в самом VCL пока не нашел

все, нашел. В деструкторе TControl "отвязывается" от Parent"а

destructor TControl.Destroy;
begin
...
   SetParent(nil);
...
end;


где-то видимо в иерархии у меня потерялся inherited destructor....


 
Palladin ©   (2009-03-24 14:30) [10]


> кому лень отслеживать время жизни своих объектов.

Хренасе лень, действительно, нафиг нужно было TStringList создавать, разве что для тех кому лень свой написать...


 
StriderMan   (2009-03-24 14:35) [11]


> Взять посмотреть на это со стороны IDE, ты накидал на панель
> контролов, потом взял и удалил панель, контролы должны остаться?
>

так передавай им в конструктор Owner"ом эту же панель. нафига дублировать механизмы? для надежности?


 
Юрий Зотов ©   (2009-03-24 14:37) [12]

> StriderMan   (24.03.09 13:18)  

Контрол без парента бесполезен и потому на фиг никому не нужен - поэтому при уничтожении парента нет никакого смысла сохранять его дочерние контролы. Только ресурсы зазря гробятся.

Поэтому дочерние контролы уничтожаются автоматически. При этом их Owner"ы получают уведомление (см. Notification) и удаляют уничтожаемые контролы их своих списков Components - то есть, Owner"ами быть перестают.

> контрол уже разрушен мною а его Parent пытается это сделать еще раз и
> получает AV.

Что-то Вы не так делаете, похоже. При правильном уничтожении контрола он автоматически исключается из списка Parent.Controls - то есть, Parent его теряет из виду (перестает быть парентом) и повторно уничтожать не должен.

Кидаем на форму панель, а на панель - кнопку. В обработчике Form.OnClick пишем Кнопка.Free. Запускаем программу, щелкаем по форме - кнопка исчезает. Закрываем программу - и панель не пытается удалить уже удаленную кнопку. Никаких AV.


 
StriderMan   (2009-03-24 14:43) [13]


> Что-то Вы не так делаете, похоже

да я уж понял что неправильно. Про Notification забыл.


 
StriderMan   (2009-03-24 14:44) [14]


> Контрол без парента бесполезен и потому на фиг никому не нужен

вопрос спорный вобщем-то. Кто-то может иметь на него ссылки, даже не зная что он TControl.


 
Юрий Зотов ©   (2009-03-24 14:53) [15]

> StriderMan   (24.03.09 14:44) [14]

> вопрос спорный вобщем-то.

Вряд ли. Если контрол не имеет парента, то  возникают проблемы с его видимостью, перерисовкой, да и вообще с обработкой его сообщений.

> Кто-то может иметь на него ссылки, даже не зная что он TControl.

Так для этого и существует Notification.


 
StriderMan   (2009-03-26 18:14) [16]


> Так для этого и существует Notification.

Да, только в нем уже нас ставят перед фактом, дескать все, хана вашему контрольчику. Как избавиться от этого произвола ума не приложу.

Ну вот нужен мне ВинКонтрол который и отдельно и на форме может существовать.


 
StriderMan   (2009-03-26 18:19) [17]

Все, придумал.
вместо .Parent использовал .ParentWindow


 
Игорь Шевченко ©   (2009-03-26 18:45) [18]


> Ну вот нужен мне ВинКонтрол который и отдельно и на форме
> может существовать.


WinControl отдельно не может существовать - у него в style WS_CHILD по умолчанию.


 
StriderMan   (2009-03-26 18:59) [19]


> WinControl отдельно не может существовать - у него в style  WS_CHILD по умолчанию.

имеется ввиду существует как объект а не как виндовая форма.


 
Игорь Шевченко ©   (2009-03-26 19:25) [20]


> имеется ввиду существует как объект а не как виндовая форма.


вполне может существовать:

unit Unit1;

interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   FControl: TWinControl;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 FControl := TWinControl.Create(Self);
end;

end.


Только нафиг он нужен ?


 
Palladin ©   (2009-03-26 19:29) [21]


> Игорь Шевченко ©   (26.03.09 19:25) [20]

Он имеет ввиду, что если подцепить этот контрол к панели, а потом уничтожить эту панель - контрол должен остаться жить :)


 
Игорь Шевченко ©   (2009-03-26 19:53) [22]


> Он имеет ввиду, что если подцепить этот контрол к панели,
>  а потом уничтожить эту панель - контрол должен остаться
> жить :)


если перед уничтожением панели сменить парент у контрола, то вполне себе останется жить.

Только разве ж это жизнь - без панели-то ?


 
StriderMan   (2009-03-26 23:23) [23]


> если перед уничтожением панели сменить парент у контрола,
>  то вполне себе останется жить.
>
> Только разве ж это жизнь - без панели-то ?

Так а мы ему другую панельку подсунем :)

Как вот только отследить что эту панельку сейчас кто-то прихлопнет? к моменту Notification она все свои контролы уже убила :(


 
Германн ©   (2009-03-27 00:39) [24]


> StriderMan   (26.03.09 23:23) [23]
>
> Как вот только отследить что эту панельку сейчас кто-то
> прихлопнет? к моменту Notification она все свои контролы
> уже убила :(

А зачем?


 
Игорь Шевченко ©   (2009-03-27 01:49) [25]

StriderMan   (26.03.09 23:23) [23]


> Как вот только отследить что эту панельку сейчас кто-то
> прихлопнет?


TObject.BeforeDestruction - в смысле надписываешь панель, перекрываешь этот метод, и вперед, меняешь парент у wincontrol-ов на ней.

Но сдается мне, ты странного хочешь - иметь контрол, который при уничтожении родительского окна остается висеть в воздухе.
В древнем Китае желающим странного отрубали голову - очень полезная, надо сказать, практика.


 
StriderMan   (2009-03-27 11:16) [26]


> TObject.BeforeDestruction - в смысле надписываешь панель, перекрываешь этот метод, и вперед, меняешь парент у wincontrol-ов на ней.

знать бы еще у на какой панели мой контрол окажется в данный момент времени... :))))


> Но сдается мне, ты странного хочешь - иметь контрол, который  при уничтожении родительского окна остается висеть в воздухе. В древнем Китае желающим странного отрубали голову - очень полезная, надо сказать, практика.

почему в воздухе? в светлой памяти :)

А потом в военное время живем, господа мастера, даже значение синуса четырех-пяти порой достигает :)

Ясное дело, такая проблема возникла из-за некоторых архитектурных просчетов, допущенных в прошлом. Осталось решить, что дешевле - рефакторинг или попытка обмануть vcl малой кровью.


 
StriderMan   (2009-03-27 11:18) [27]


> А зачем?

зачем отлседить - читай выше. Зачем убивает - не знаю, вот и интересуюсь, нафига задублирован механизм убивания компонентов механизмом убивания контролов.


 
Игорь Шевченко ©   (2009-03-27 12:19) [28]


> зачем отлседить - читай выше. Зачем убивает - не знаю, вот
> и интересуюсь, нафига задублирован механизм убивания компонентов
> механизмом убивания контролов.


Он незадублирован. Читай выше :)



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

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

Наверх




Память: 0.54 MB
Время: 0.009 c
15-1236237557
{RASkov}
2009-03-05 10:19
2009.05.10
Когда драйвер "не нужен", а ОСь его требует


15-1236146985
SteepeWolf
2009-03-04 09:09
2009.05.10
Изменения оклада


2-1238473883
Lexus315
2009-03-31 08:31
2009.05.10
Перевод величин углов


4-1209369334
Dmitry_177
2008-04-28 11:55
2009.05.10
Теуцщая позиция в файле


15-1236674398
zzzzzz
2009-03-10 11:39
2009.05.10
in в VBScript