[101012218]
Name=Уровень 1
Parent=
[432049328]
Name=Уровень 1
Parent=
[3238323280]
Name=Уровень 2
Parent=101012218
[271972121]
Name=Уровень 2
Parent=432049328
[362763262111]
Name=Уровень 3
Parent=3238323280
Treeview + INI файл
Имеем файл test.ini
Числовое значение = идентификатор
Name=имя параметра
Parent=кому принадлежит параметр (идентификатор)
Код:
Нужно загрузить их в Treview, результат должен быть таким, как указано в файле во вложении.
Использую код:
Код:
var
F:TIniFile;
List:TStringList;
i,j:integer;
Name,Parent:string;
begin
Treeview1.Items.Clear;
F:=TIniFile.Create('f:\test.ini');
List:=TStringList.Create;
F.ReadSections(List);
for i:=0 to List.Count-1 do
begin
Application.ProcessMessages;
Name:=F.ReadString(List.Strings, 'Name', Name);
Parent:=F.ReadString(List.Strings, 'Parent', Parent);
if Parent='' then
begin
TreeView1.Items.Add(nil, Name);
Treeview1.items[Treeview1.Items.Count-1].Data:=Pointer(List.Strings);
end
else
begin
for j:=0 to Treeview1.Items.Count-1 do
begin
Application.ProcessMessages;
if Treeview1.Items[j].Data=Pointer(Parent) then
begin
TreeView1.Items.AddChild(Treeview1.Items[j], Name);
end;
end;
end;
end;
List.Free;
F.Free;
F:TIniFile;
List:TStringList;
i,j:integer;
Name,Parent:string;
begin
Treeview1.Items.Clear;
F:=TIniFile.Create('f:\test.ini');
List:=TStringList.Create;
F.ReadSections(List);
for i:=0 to List.Count-1 do
begin
Application.ProcessMessages;
Name:=F.ReadString(List.Strings, 'Name', Name);
Parent:=F.ReadString(List.Strings, 'Parent', Parent);
if Parent='' then
begin
TreeView1.Items.Add(nil, Name);
Treeview1.items[Treeview1.Items.Count-1].Data:=Pointer(List.Strings);
end
else
begin
for j:=0 to Treeview1.Items.Count-1 do
begin
Application.ProcessMessages;
if Treeview1.Items[j].Data=Pointer(Parent) then
begin
TreeView1.Items.AddChild(Treeview1.Items[j], Name);
end;
end;
end;
end;
List.Free;
F.Free;
Pointer не const, лучше просто при сохранении тупо нумеруй их и всё.
То есть? как нумеровать по какому принципу?
по порядку, начиная с parent/root узла
не совсем понял, покажи пожалуйста на примере изображения, вложенного в мой пост выше
Код:
...
var F: TFileStream;// Сохраняем
begin
F:= TFileStream.Create('c:\test.ini', fmCreate or fmShareCompat);
try
F.WriteComponent(TreeView1);
finally
F.Free;
end;
...
_____________________________
...
var F: TFileStream;// Загружаем
begin
F := TFileStream.Create('c:\test.ini', fmOpenRead or fmShareDenyWrite);
try
F.ReadComponent(TreeView1);
finally
F.Free;
end;
...
©Drkb::01125
var F: TFileStream;// Сохраняем
begin
F:= TFileStream.Create('c:\test.ini', fmCreate or fmShareCompat);
try
F.WriteComponent(TreeView1);
finally
F.Free;
end;
...
_____________________________
...
var F: TFileStream;// Загружаем
begin
F := TFileStream.Create('c:\test.ini', fmOpenRead or fmShareDenyWrite);
try
F.ReadComponent(TreeView1);
finally
F.Free;
end;
...
©Drkb::01125
А насчёт загрузки ини-файла в TreView, то его можно загрузить и так (весь принцип в комментах):
Код:
procedure LoadIniToTree(const FName: string; Tree: TTreeView);
var LS, LV: TStrings;
i, j: integer;
root: TTreeNode;
n: string;
p: PString;
begin
Tree.Items.Clear; // очищаем дерево
with TIniFile.Create(FName) do // пытаемся открыть файл FName
try
LS := TStringList.Create; // список названий секций
try
ReadSections(LS); // читаем все секции в список
LV := TStringList.Create; // список пар "имя=значение"
try
for i := 0 to LS.Count-1 do // для всех секций...
begin
LV.Clear; // подготовим список
ReadSectionValues(LS, LV); // читаем список пар "имя=значение" для текущей секции
root := Tree.Items.Add(nil, LS); // добавляем корневой узел (имя текущей секции)
for j := 0 to LV.Count-1 do // для всех пар "имя=значение"...
begin
n := LV.Names[j]; // выделяем "имя"
// добавляем дочерний по отношению к root узел,
// в качестве текста исп. "имя"
// в качестве значения поля Data = "значение"
New(p);
p^ := LV.Values[n];
Tree.Items.AddChildObject(root, n, p);
end;
end;
finally
LV.Free;
end;
finally
LS.Free;
end;
finally
Free; // корректно уничтожаем объект TIniFile
end;
end;
// Применение:
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
if (TreeView1.Selected <> nil) and (TreeView1.Selected.Parent <> nil) then
begin
Edit1.Text := TreeView1.Selected.Text;
Edit2.Text := String(TreeView1.Selected.Data^);
end else
begin
Edit1.Text := '';
Edit2.Text := '';
end;
end;
// После использования не забыть освободить память, напр. так:
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
if Node.Data <> nil then
Dispose(PString(Node.Data));
end;
//Автор: Dynamic
var LS, LV: TStrings;
i, j: integer;
root: TTreeNode;
n: string;
p: PString;
begin
Tree.Items.Clear; // очищаем дерево
with TIniFile.Create(FName) do // пытаемся открыть файл FName
try
LS := TStringList.Create; // список названий секций
try
ReadSections(LS); // читаем все секции в список
LV := TStringList.Create; // список пар "имя=значение"
try
for i := 0 to LS.Count-1 do // для всех секций...
begin
LV.Clear; // подготовим список
ReadSectionValues(LS, LV); // читаем список пар "имя=значение" для текущей секции
root := Tree.Items.Add(nil, LS); // добавляем корневой узел (имя текущей секции)
for j := 0 to LV.Count-1 do // для всех пар "имя=значение"...
begin
n := LV.Names[j]; // выделяем "имя"
// добавляем дочерний по отношению к root узел,
// в качестве текста исп. "имя"
// в качестве значения поля Data = "значение"
New(p);
p^ := LV.Values[n];
Tree.Items.AddChildObject(root, n, p);
end;
end;
finally
LV.Free;
end;
finally
LS.Free;
end;
finally
Free; // корректно уничтожаем объект TIniFile
end;
end;
// Применение:
procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
if (TreeView1.Selected <> nil) and (TreeView1.Selected.Parent <> nil) then
begin
Edit1.Text := TreeView1.Selected.Text;
Edit2.Text := String(TreeView1.Selected.Data^);
end else
begin
Edit1.Text := '';
Edit2.Text := '';
end;
end;
// После использования не забыть освободить память, напр. так:
procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
if Node.Data <> nil then
Dispose(PString(Node.Data));
end;
//Автор: Dynamic