![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Access Violations в TTreeView [D7, XP]
mfender © (2006-07-01 13:51:00)Здравствуйте.
Всю голову сломал - не пойму в чём тут беда:
type
TForm1 = class(TForm)
public
TV: ThsTreeView;
end;
ThsTreeView = class(TTreeView)
private
procedure CreateNodeClass(Sender: TCustomTreeView;
var NodeClass: TTreeNodeClass);
end;
ThsNode = class(TTreeNode)
private
FConnect: TZConnection;
FDataSet: TZQuery;
FBookmark: TBookmark;
function GetConnect: TZConnection;
function GetBookmark: TBookmark;
procedure SetBookmark(const Value: TBookmark);
function GetDataSet: TZQuery;
procedure SetDataSet(const Value: TZQuery);
protected
function GetQuery(Query: string; var DataSet: TZQuery): TZQuery;
procedure SetConnect(const Value: TZConnection); virtual;
public
constructor Create(AOwner: TTreeNodes);
property Connect: TZConnection read GetConnect write SetConnect;
property Bookmark: TBookmark read GetBookmark write SetBookmark;
property DataSet: TZQuery read GetDataSet write SetDataSet;
end;
ThsDomainNode = class(ThsNode)
private
protected
procedure SetConnect(const Value: TZConnection); override;
public
constructor Create(AOwner: TTreeNodes);
function GetNode(Connection: TZConnection; DS: TZQuery;
Bkmrk: TBookmark): ThsDomainNode;
end;
implementation
{Здесь всё создаётся и showmessage() показывает то, что от него и требуется. Дубуггер сообщает, что DataSet, Connect и Bookmark создаются и есть}
function ThsDomainNode.GetNode(Connection: TZConnection; DS: TZQuery;
Bkmrk: TBookmark): ThsDomainNode;
begin
Connect := Connection;
DataSet := DS;
Bookmark := Bkmrk;
showmessage(DataSet.FieldValues['domain_title']);
Result := Self;
end;
{Вся беда начинается потом...}
procedure TForm1.TVDblClick(Sender: TObject);
var
MessageStr: string;
begin
showmessage(TV.Selected.ClassName); {Здесь всё нормально - ThsDomainNode}
if TV.Selected is ThsDomainNode then
begin
showmessage(ThsDomainNode(TTreeView(Sender).Selected).Text); {И здесь всё нормально}
showmessage(ThsDomainNode(TTreeView(Sender).Selected).DataSet.ClassName); {А вот здесь - Access Violations}
end;
end;
Ну почему?! Что за наказание мне такое?
mfender (2006-07-01 16:02:00) [1]Поставил рядом TDBGrid и связал его с создаваемым DataSet... Удивительное рядом - у него ничего не отмирает. DataSet есть. not nil. В то же время дебуггер его описывает как nilи всё заканчивается на "Access Violations"... Мистика!
mfender (2006-07-01 15:31:00) [2]
> больше похоже на то, что не уничтожается, а не был создан
Он создаётся. В методе ThsDomainNode.GetNode он работает, дебуггер и showmessage() показывают правильное значение (т.е., то, чего я от них и жду). Кстати, создаётся он раньше, ещё до создания узла, а туда только передаётся. Я уже попробовал передать его и просто, и как const- результат тот же - после TV.Add() он внезапно пропадает, равно как и ThsDomainNode.Connect и ThsDomainNode.Bookmark.
> Либо все же уничтожается, но не просто через Free, а через
> FreeAndNil (или с "ручным" обнулением).
А вот это для меня - тёмный лес... :( Это как?
Кстати, по случаю вопрос: "Variable "<тут бывает либо Sender, либо Self>" inaccessible here due to optimization" - что это обозначает? Я старательно вчитывался в help, но ни-че-го не понял... Обычно понимаю, но этого не понял.
Юрий Зотов (2006-07-01 15:01:00) [3]Если равно nil, а не случайному "мусорному" значению, то больше похоже на то, что не уничтожается,а не был создан. Либо все же уничтожается, но не просто через Free, а через FreeAndNil (или с "ручным" обнулением).
mfender (2006-07-01 14:54:00) [4]
> Юрий Зотов © (01.07.06 14:14) [1]
> Похоже, где-то между вызовами этих двух методов DataSet
> уничтожается.
Спасибо, Юрий.
в DblClick получается (если верить дебуггеру) ThsDomainNode(TTreeView(Sender).Selected).DataSet = nil. Загадка природы.
Действительно, уничтожается сразу после создания нода. Вот только где - не пойму. Буду разбираться...
Юрий Зотов (2006-07-01 14:14:00) [5]Похоже, где-то между вызовами этих двух методов DataSet уничтожается.
Поставьте брейкпойнты в 2-х местах: в TForm1.TVDblClick и в деструкторе DataSet'. Если в деструктор Вы придете раньше, чем TForm1.TVDblClick - значит, предположение верное. Тогда останется лишь пройти обратно по стеку вызовов и найти причину, по которой уничтожается DataSet.