Форум: "Начинающим";
Текущий архив: 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