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

Вниз

Проблема с компонентой 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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.013 c
3-18770
Вика
2002-01-14 08:02
2002.02.07
IB 5.6 , как сделать экпорт/импорт части таблицы через дискету?


3-18708
13-ый
2002-01-09 23:43
2002.02.07
Подскажите хорошую книжку по Oracle !


1-18911
kserg@ukr.net
2002-01-23 15:19
2002.02.07
Вопрос по ActionList


3-18758
Артём
2002-01-11 12:25
2002.02.07
Подскажите какой компонент использовать!


3-18784
Стас
2002-01-14 13:54
2002.02.07
Чирканите подсказку