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

Вниз

Как корректно уничтожить из дестрактора компоненты ScrollBar   Найти похожие ветки 

 
Aleksandr   (2001-12-21 14:33) [0]

Компонента имеет ScrollBar, создающийся при ее создании:
constructor TWayTree.Create(AOwner : TComponent);
begin
Inherited;
FScrollBar:=TScrollBar.Create(AOwner);
FScrollBar.Parent:=Parent;
FScrollBar.OnScroll:=FWayTreeScroll;
...
end;
Parent ScrollBar"у я назначаю, чтобы он не мигал и не дергался при перерисовке компоненты (и вообще ей жить не мешал). То есть фактически он не принадлежит компоненте, просто скроллирует ее.
Все прекрасно, но при вызове дестрактора компоненты в этом месте:
if Assigned(FScrollBar) then
FScrollBar.Free
появляется Access Violation at 00000000...
Чего я не так делаю?


 
Alx2   (2001-12-21 14:39) [1]

Может, его кто-то уже перед этим прибил?


 
Aleksandr   (2001-12-21 14:41) [2]

Не знаю... Только если этот самый Parent раньше не вышибает СкроллБар, а уж потом компоненту... Только как проверить, если Assigned всего лишь сверяет с nil?


 
Alx2   (2001-12-21 14:44) [3]

Вот-вот...
Тогда просто его не грохай. Это сделает Owner, когда помирать будет (или Parent? - не помню. Но ведь позаботился кто-то уже?).


 
Alx2   (2001-12-21 14:46) [4]

Вдогонку: в конструктор скроллу попробую передавать себя (т.е TWay).


 
Alx2   (2001-12-21 14:49) [5]

Точно!
Вот из help:
property Owner : TComponent;
Indicates the component that is responsible for freeing this component.


 
Aleksandr   (2001-12-21 15:06) [6]

Спасибо!


 
Aleksandr   (2001-12-21 15:16) [7]

Млин... усе равно Access Violation...


 
Alx2   (2001-12-21 15:23) [8]

Как выглядит код сейчас?


 
Alx2   (2001-12-21 15:27) [9]

Петрушка может сидеть, наверное, в том, что в TWay.Destroy сначала идет inherited, который и грохает скролл. Т.е. заботится уже не о ком.
Можно попробовать для чистоты inherited воткнуть последним, после FScrollBar.Free; FScrollBar:=Nil. И посмотреть где будет AV.


 
Aleksandr   (2001-12-21 15:51) [10]

Полностью дестрактор выглядит так:

destructor TWayTree.Destroy;
var
W : TWayItem;
begin
try
if FDestroyItems then begin
while FPoints.Count>0 do begin
W:=TWayItem(FPoints.Items[0]);
FPoints.Delete(0);
W.Free
end
end;
finally
FPoints.Free;
FFont.Free;
if Assigned(FScrollBar) then
FScrollBar.Free;
inherited Destroy
end
end;

Естественно, inherited Destroy вызываю последним...


 
DieHard   (2001-12-21 15:58) [11]

Зачем вообще разрушаешь FScrollBar, предоставь это AOwner, кому и положено...


 
Alx2   (2001-12-21 16:05) [12]

Попробуй проверить у TWay свойство ComponentCount
Если 0, то все где-то прибито уже.


 
Юрий Зотов   (2001-12-21 16:06) [13]

Происходит следующее. Scrollbar Вы создаете с тем же владельцем, что и владелец Вашего компонента:

FScrollBar:=TScrollBar.Create(AOwner);

Значит, этот AOwner при своем уничтожении будет убивать сначала Ваш компонент, а потом созданный Вами Scrollbar. Но Ваш компонент убивает его в своем деструкторе и поэтому Aowner пытается убить уже убитый Scrollbar. Вот и ошибка.

Создавайте Scrollbar так:

FScrollBar:=TScrollBar.Create(Self);

И после этого можете убивать его в своем деструкторе (а можете и не убивать - он будет убит автоматически).


 
Alx2   (2001-12-21 16:08) [14]

>DieHard
Оно-то понятно. Просто интересно где этот скролл помереть успевает до TWayTree.Destroy, так как Owner у него TWayTree...


 
Alx2   (2001-12-21 16:11) [15]

>Юрий Зотов
Процитирую себя (см. выше):
Вдогонку: в конструктор скроллу попробуй передавать себя (т.е TWaytree).
Сейчас вся беда в выяснении где этот скролл помереть успевает до TWayTree.Destroy, так как Owner у него TWayTree...


 
Freezer   (2001-12-21 16:20) [16]


if not (csDestroying in ComponentState) then
if Assigned(FScrollBar) then
FScrollBar.Free;
inherited Destroy;


 
Юрий Зотов   (2001-12-21 16:22) [17]

> Alx2

> где этот скролл помереть успевает до TWayTree.Destroy

Нигде. До TWayTree.Destroy он не умирает. Он умирает именно в TWayTree.Destroy.


> так как Owner у него TWayTree...

Нет. Owner у него ТОТ ЖЕ, что и у TWayTree. В этом и есть ошибка. Сначала его убивает TWayTree, а потом еще и Owner - и вот здесь-то возникает AV. То есть, НЕ в TWayTree.Destroy, а уже ПОСЛЕ.


 
Alx2   (2001-12-21 16:29) [18]

>Юрий Зотов
Ну ладно. Александр нас рассудит. В своих ответах ранее я сделал акцент именно на то, чтобы у скролла Owner был именно TWayTree. Как оно у него стало на самом деле - не знаю. То есть вызов должен быть именно такой, какой написали Вы: FScrollBar:=TScrollBar.Create(Self);
Но то, что ошибка не исчезла - странно. Хотя без исходников сказать мало что можно.


 
Юрий Зотов   (2001-12-21 16:49) [19]

> Alx2 © (21.12.01 16:29)
Согласен, нужен код конструктора - тот, который сейчас, а не тот, который уже приводился. Впрочем, подозреваю, что он не изменился, иначе ошибка должна была исчезнуть. Странно, что Aleksandr молчит. Ау-у-у!


 
Aleksandr   (2001-12-21 17:01) [20]

Перепробовал варианты в констракторе:

FScrollBar:=TScrollBar.Create(Self);
FScrollBar:=TScrollBar.Create(Owner);

При любом из них в Destroy происходит AV.


 
Aleksandr   (2001-12-21 17:06) [21]

Да, кстати, в дестракторе я FScrollBar.Free заменил на FreeAndNil(FScrollBar) - на случай, если AV генерирует Owner.


 
Юрий Зотов   (2001-12-21 17:08) [22]

Тогда, видимо, Alx2 прав - надо искать, где убивается Scrollbar. Сделайте так.

1. Проверьте, чтобы в путь отладки были включены исходники VCL.
2. В деструкторе TScrollbar поставьте BreakPoint и запустите программу.
3. Когда придете на BreakPoint, вызовите окно Call Stack и посмотрите, откуда Вы туда пришли. Скорее всего, там и будет причина ошибки.


 
Aleksandr   (2001-12-21 17:34) [23]

ОК. А если его вообще не уничтожать в дестракторе, он так и будет память загаживать? Просто формой с этой компонентой юзверы будут пользоваться с такой же частотой, с какой бухгалтер юзает калькулятор...


 
Юрий Зотов   (2001-12-21 20:57) [24]

Если его Owner - не nil, то он будет уничтожен вместе с Owner"ом. Но лично я предпочитаю удалять ручками, в деструкторе - как у Вас. Хотя бы потому, что это позволяет вылавливать ситуации, подобные Вашей и указывающие на то, что в программе явно что-то не так. Поэтому очень советую Вам все же раскопать, в чем там дело.



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

Форум: "Основная";
Текущий архив: 2002.01.10;
Скачать: [xml.tar.bz2];

Наверх









Память: 0.89 MB
Время: 0.043 c
1-28488
ilysha
2001-12-20 10:00
2002.01.10
В дочерних окнах из DLL не работают


14-28544
Abajun
2001-11-16 09:38
2002.01.10
Шифровка


1-28502
Серега
2001-12-16 19:01
2002.01.10
I/O Error 103 и подавление системного сообщения.


1-28495
dimonf
2001-12-22 21:49
2002.01.10
Ноаод, у меня вопрос как не выводит TPanel на ScrollBox?


4-28564
YUS
2001-11-09 08:04
2002.01.10
Создание Dll.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский