Динамически создаю дерево VirtualTreeView внутри CategoryPanel:
Код:
...
type
PPhoneNode = ^TPhoneNode;
TPhoneNode = record
Name: String;
end;
TForm1 = class(TForm)
...
procedure FormCreate(Sender: TObject);
procedure PanelCreate(title: String; numRec: Integer);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
procedure VTFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex);
procedure VirtualStringTree1FreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
activeVT : TVirtualStringTree;
k: Integer;
implementation
{$R *.dfm}
//Создание панели с деревом----------------------------------
procedure TForm1.PanelCreate(title: String; numRec: Integer);
var
i,j: Integer;
Panel: TCategoryPanel;
Tree: TVirtualStringTree;
NewNode, NewNode1 : PVirtualNode;
NewPhone: PPhoneNode;
begin
Panel:=PanelGroup.CreatePanel(Self) as TCategoryPanel;
Panel.Caption:=title;
PanelGroup.CollapseAll;
Tree := TVirtualStringTree.Create(Panel);
Tree.OnGetText := VTGetText; //метод для вывода текста
Tree.OnFocusChanged := VTFocusChanged;
Tree.OnFreeNode := VirtualStringTree1FreeNode;
Tree.Name := 'Name';
Tree.Parent := Panel;
Tree.Align := alClient;
Tree.NodeDataSize := SizeOf(TPhoneNode);
for i := 1 to numRec do
begin
NewNode := Tree.AddChild(Tree.RootNode);
NewPhone := Tree.GetNodeData(NewNode);
if Assigned(NewPhone) then
with NewPhone^ do
begin
Name := Query1.Fields.FieldByNumber(1).Value;
//Заполнение типов расчета -----------------------------------------------------
Query2.SQL.Clear;
Query2.SQL.Add('select [Тип] from ['+title+'] group by [Тип]');
Query2.ExecSQL;
Query2.Active := true;
if Query2.RecordCount > 0 then
begin
for j := 1 to Query2.RecordCount do
begin
NewNode1 := Tree.AddChild(NewNode);
NewPhone := Tree.GetNodeData(NewNode1);
if Assigned(NewPhone) then
with NewPhone^ do
begin
Name := Query2.Fields.FieldByNumber(1).Value;
end;
if j <> Query2.RecordCount then Query2.FindNext;
end;
end;
//------------------------------------------------------------------------------
if i <> numRec then Query1.FindNext;
end;
end;
Panel.InsertControl(Tree);
k:=k+1;
end;
//-----------------------------------------------------------------------------
//Определяем активное дерево
procedure TForm1.VirtualStringTree1FreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode);
var
Data: PPhoneNode;
begin
Data := Sender.GetNodeData(Node);
if Assigned(Data) then
Finalize(Data^);
end;
procedure TForm1.VTFocusChanged(Sender: TBaseVirtualTree;
Node: PVirtualNode; Column: TColumnIndex);
begin
activeVT := Sender as TVirtualStringTree;
Label1.Caption := activeVT.Text[activeVT.FocusedNode,0];
end;
//-----------------------------------------------------------------------------
procedure TForm1.VTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
PhoneNode: PPhoneNode;
begin
PhoneNode := Sender.GetNodeData(Node);
if Assigned(PhoneNode) then
CellText := PhoneNode.Name;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
//activeVT.DeleteNode(activeVT.FocusedNode);
activeVT.DeleteSelectedNodes;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
NewNode: PVirtualNode;
NewPhone: PPhoneNode;
begin
NewNode := activeVT.AddChild(activeVT.FocusedNode);
NewPhone := activeVT.GetNodeData(NewNode);
if Assigned(NewPhone) then
with NewPhone^ do
begin
Name := 'b';
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
name: string;
begin
k:=0;
Query.SQL.Clear;
Query.SQL.Add('select [Name] from [Организации]');
Query.ExecSQL;
Query.Active := true;
if Query.RecordCount > 0 then
begin
Query.First;
for i := 1 to Query.RecordCount do
begin
name := Query.Fields.FieldByNumber(1).Value;
Query1.SQL.Clear;
Query1.SQL.Add('select [Год] from ['+name+'] group by [Год]');
Query1.ExecSQL;
Query1.Active := true;
PanelCreate(name,Query1.RecordCount);
if i <> Query.RecordCount then Query.FindNext;
end;
end;
end;
end.
все создается как надо, но при закрытии формы, выходит ошибка :
Invalid Pointer Operation
не могу никак понять, где ошибка? может где-то надо освободить память?