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

Вниз

Проблема с компонентой TTreeView и с указателями в частности.   Найти похожие ветки 

 
Lipskiy   (2002-01-22 00:32) [0]

Господа! Есть проблема с компонентой TTreeView и с указателями в частности.
Возникает эксепшен, причем не всегда. Что я делаю неправильно?
Смысл кода таков.
Хочу реализовать событие по деселекту ноды (когда снимается выделение с нее).
Унаследовался от TTreeView.
Объявил указатель на запись с различными свойствами для каждой ноды в дереве (PntRec).
Одно из свойств - указатель на событие по деселекту (EOnDeSelect).
Есть еще много других свойств, их я здесь опускаю.
Внутри объекта объявил переменные SelNode (выбранная нода), PrevNode (предыдущая нода).
При добавлении ноды в дерево (sAddItem) назначаю обработчик.
Теперь, по событию Change (которое override) я обновляю SelNode и PrevNode и хочу вызвать обработчик на PrevNode.
Возникает ошибка (нарушение доступа...), причем не всегда, чаще всего срабатывает верно.
Sender эксепшена - TTimer, тот, что делат задержку вызова обработчика селекта новой ноды.
По всему видимо обращаюсь не в ту область памяти, но как это отловить?
И почему эта область уже не содержит нужного мне объекта?
М.б. что здесь некорректно или вообще неверно?
Буду признателен, а то затрахался уже ловить.

Вот код:

type
PntRec = ^TRec;
TRec = record
...
EOnDeSelect: TTVChangedEvent;
...
end;

var
RecPtr: PntRec;

TSTreeView = class (TTreeView)
private
...
SelNode,PrevNode:TTreeNode;
...
end;

implementation

function TSTreeView.sAddItem...
begin
New(RecPtr);
RecPtr^.EOnDeSelect:= OnDeSelect;
...
end;

procedure TSTreeView.Change(Node:TTreeNode);
begin
PrevNode:= SelNode;
SelNode:= Node;
...
if PrevNode <> nil then
if PrevNode.Data <> nil then
if Assigned(PntRec(PrevNode.Data)^.EOnDeSelect) then <-- здесь возникает ошибка
PntRec(PrevNode.Data)^.EOnDeSelect(Self,PrevNode);
...
end;


 
Digitman   (2002-01-22 08:29) [1]

Ставь breakpoint на строчку
if Assigned(PntRec(PrevNode.Data)^.EOnDeSelect)
при останове на строчке вызывай контекстное меню "Evaluate/Modyfy.." и контролируй значения :
1.PrevNode
2.PrevNode.Data
3.PntRec(PrevNode.Data)^.EOnDeSelect

Одно из них будет равно nil, что и вызывает твой AV


 
lipskiy   (2002-01-22 09:33) [2]

Если б все было так просто, то я б и не заморачивался писать. О том, как контролировать, я в курсе. Но вся фигня в том и состоит, что ни одно из них не nil. Да и условия стоят уже, они бы не пропустили...


 
lipskiy   (2002-01-23 21:22) [3]

Так никто не подскажет?


 
DMN   (2002-01-24 11:53) [4]

У объекта TTreeView кроме события OnChange есть событие OnChanging. Внутри обработчика данного события Node - тот узел, который пытаются выбрать, а TTreeView(Sender).Selected - тот узел, с которого выделение снимается. Можно запретить смену узла, сказав AllowChange := False...



 
Digitman   (2002-01-24 12:13) [5]

Если не nil, значит, ссылка на то , что объектом не является. Попросту - "мусор". Где-то ты упустил момент, в который указательнужно было сбросить в nil после уничтожения объекта, ссылка на который и хранилась в указателе. Эта ссылка и стала "мусором", и ты на ней в результате "спотыкаешься" эпизодически. Выясняется - "мусор" это или не "мусор" - точно также : в отладчике при останове на строке, содержащей обращение по ссылке с подозрением на ее неактуальность - просто запросив в диалоге "ССЫЛКА Is TObject"


 
Алексей Петров   (2002-01-24 12:17) [6]

Возможно причина такая:
TTreeView периодически перестраивает список Nodes полностью. С чем это связано - не знаю, но при этом, если ты сохранил указатель на некий TTreeNode - он становится не действительным и при обращении по нему естественный AV.

Для решения это проблемы нужно вместо указателей на Delphi-йские TTreeNode хранить Windows-ные идентификаторы этих узлов - они не меняются. Точного названия поля TTreeNode не помню - поищи в его описаннии.

Я сам налетел на эти грабли, делая FullScreen режим для формы, на которой лежал TreeView - при переходе туда-сюда начиналось...


 
DMN   (2002-01-24 12:29) [7]

Точное название - Handle.
Но зачем так мучаться, когда всю эту обработку проще сделать в OnChanging?



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

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

Наверх





Память: 0.46 MB
Время: 0.005 c
1-18893
VladimirL
2002-01-23 14:29
2002.02.07
Как отправить StringGrid на печать целиком?


1-18811
Марина
2002-01-25 09:03
2002.02.07
Динамическая память


1-18896
Song
2002-01-23 21:15
2002.02.07
Распечатать StringGrid!!!!


14-18982
smuggler
2001-12-19 13:23
2002.02.07
Вирус!


1-18903
Ольга
2002-01-22 17:18
2002.02.07
Delphi 6





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