Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.05.10;
Скачать: [xml.tar.bz2];

Вниз

Уничтожение 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.006 c
15-1236501285
Юрий
2009-03-08 11:34
2009.05.10
С днем рождения ! 7 марта 2009 суббота


2-1238143029
igorntk
2009-03-27 11:37
2009.05.10
Поиск в БД


2-1238248106
SP
2009-03-28 16:48
2009.05.10
Обязательно ли писать свой деструктор в таком случае?


2-1238085741
bmw09121985
2009-03-26 19:42
2009.05.10
Функции, используемые диалоговыми окнами


2-1238403850
Apachi
2009-03-30 13:04
2009.05.10
Идентифицировать объекты





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский