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

Вниз

"Правильное" уничтожение фреймов при работе с TTreeView   Найти похожие ветки 

 
Loginov Dmitry ©   (2006-07-29 21:23) [0]

Вот наткнулся сегодня на проблему "правильного" уничтожения фреймов.
На фрейме у меня лежит TTreeView, и элементы добавляются динамически. У фрейма есть деструктор. Вот его код:

destructor TFrame2.Destroy;
begin
 MessageBox(0, PChar(IntToStr(TreeView1.Items.Count)),"",0);
 inherited;
end;

И что вы думаете? MessageBox показывает, что количество элементов дерева равно нулю (не важно, сколько их там было фактически). Фрейм кладется на форму в Design-Time (к слову). Похоже, что элементы дерева удаляются каким-то образом еще до вызова Destroy.
Баг этот я считаю достаточно серьезным, и он может привести к ощутимым утечкам памяти. Например, вы в TTreeNode храните ссылки на динамически создаваемые данные. И надеетесь, что они удаляются в Destroy. А фигушки!

Я предлагаю следующий выход:
destructor TForm1.Destroy;
var
 I: Integer;
begin
 for I := 0 to ComponentCount - 1 do
   if Components[I] is TFrame then
     Components[I].Free;
 inherited;
end;


где TForm1 - форма, на которой лежит фрейм.


 
Piter ©   (2006-07-29 21:27) [1]

я не понял. Если я храню элементы в TTreeNode - то я буду удалять их при TTreeView.OnDeletion.

С чего ты взял, что к моменту TForm.OnDestroy ее дочерние компоненты НЕ должны быть уничтожены?

Не засчитывается, я видал баги и посерьезнее :)


 
Loginov Dmitry ©   (2006-07-29 21:30) [2]

> то я буду удалять их при TTreeView.OnDeletion


Не самый удобное место для этого.


> С чего ты взял, что к моменту TForm.OnDestroy ее дочерние
> компоненты НЕ должны быть уничтожены


А где было написано, что я что-то с чего-то взял?


 
Loginov Dmitry ©   (2006-07-29 21:33) [3]

> Не самой удобное место для этого.


Это я к тому, что возникнут проблемы с Drag & Drop.


 
DiamondShark ©   (2006-07-29 23:36) [4]

TFrame2 = class(TFrame)
   TreeView1: TTreeView;
   procedure TreeView1Deletion(Sender: TObject; Node: TTreeNode);
 private
   procedure WMDestroy(var M: TMessage); message WM_DESTROY;
 public
   destructor Destroy; override;
 end;

destructor TFrame2.Destroy;
begin
 inherited;
end;

procedure TFrame2.WMDestroy(var M: TMessage);
begin
 inherited;
end;

ставим брякпоинты в деструкторе и обработчике.
запускаем.
закрываем форму "крестиком".
попадаем сначала в WMDestroy, потом в destructor.

Запускаем ещё раз.
Выполняем
 Frame21.Free;
попадаем сначала в destructor, потом в WMDestroy.

Вообще-то, как и ожидалось.

Ну а уж то, что в ответ на WM_DESTROY тривью удаляет итемы -- не баг, а фича.
;)


 
Loginov Dmitry ©   (2006-07-30 09:49) [5]

> Ну а уж то, что в ответ на WM_DESTROY тривью удаляет итемы
> -- не баг, а фича


Да за такие фичи да голову бы оторвать. Два часа убил на то, чтобы отыскать, где же источник утечки памяти. А это фича. Вот как!
;)


 
Юрий Зотов ©   (2006-07-30 12:02) [6]

Осталось только выяснить, чья это фича - Win32 или VCL.


 
jack128 ©   (2006-07-30 14:16) [7]

Юрий Зотов ©   (30.07.06 12:02) [6]
Осталось только выяснить, чья это фича - Win32 или VCL.

VCL"евская, очевидно.  Автоматом следует из разделения понятий TWinControl и окно Windows.


 
DiamondShark ©   (2006-07-30 14:40) [8]


> Автоматом следует из разделения понятий TWinControl и окно
> Windows.

Вовсе даже не автоматом.
"Плотность прилегания" компонентной обёртки и системных объектов обеспечить можно, вопрос в затратах. В худшем случае -- вплоть до полного дублирования.



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

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

Наверх




Память: 0.49 MB
Время: 0.058 c
6-1144412093
Квэнди
2006-04-07 16:14
2006.08.27
Добавить Ip на интерфейс


6-1144618623
Nikolas
2006-04-10 01:37
2006.08.27
Сетевой движок


15-1154290719
ronyn
2006-07-31 00:18
2006.08.27
HTML


15-1154351795
Сатир
2006-07-31 17:16
2006.08.27
mp3 to midi converter


1-1152823459
01
2006-07-14 00:44
2006.08.27
PopupMenu сейчас на экране или убралось