Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 24.02.2014, 04:17
Toxa16 Toxa16 вне форума
Прохожий
 
Регистрация: 24.02.2009
Сообщения: 2
Репутация: 10
По умолчанию Сохранение данных TreeView

Есть TreeView, к узлам привязаны данные.
Такая вот структура:
Код:
1
2
3
4
5
6
7
8
type
  PNodeOptions = ^NodeOptions;
  NodeOptions=record
   Name: String[255];
   Surname: String[255];
   Address: String[255];
   EMail: String[255];
  end;

Пожалуйста, помогите эти данные записывать и считывать из файла! Чтобы и дерево, и эти привязанные данные были в одном файле. Я обыскал все, ничего путного не нашел(((
Очень нужна помощь!
Ответить с цитированием
  #2  
Старый 24.02.2014, 04:35
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Ну так и сериализуй.
Тут надо знать как узлы в дереве расположены (сколько корневых).
Можно просто в xml сериализовать, тогда меньше мороки с корневыми узлами, но больше потом мороки с чтением всего этого добра обратно.
Ответить с цитированием
  #3  
Старый 24.02.2014, 08:18
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

А что если радикально, пользуя сам компонет, через файловый поток
Код:
1
2
3
4
5
6
7
8
9
10
11
12
var
  fs: TFileStream;
  ...
{Сохранить} fs:= TFileStream.Create('tv.sav', fmCreate or fmShareCompat);
{Загрузить} fs:= TFileStream.Create('tv.sav', fmOpenRead or fmShareDenyWrite);
  try
{Сохранить} fs.WriteComponent(TreeView1);
{Загрузить}  fs.ReadComponent(TreeView1);
   finally
    fs.Free;
  end;
  ...
Ответить с цитированием
  #4  
Старый 24.02.2014, 09:24
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от Alegun
А что если радикально, пользуя сам компонет, через файловый поток

Не, если я правильно помню, то он привязанные данные не сохраняет, просто в силу того, что не знает как это делать.
Ответить с цитированием
  #5  
Старый 24.02.2014, 12:27
Toxa16 Toxa16 вне форума
Прохожий
 
Регистрация: 24.02.2009
Сообщения: 2
Репутация: 10
По умолчанию

Не работает, файловый поток сохраняет только само дерево, без данных!( еще варианты?
Ответить с цитированием
  #6  
Старый 24.02.2014, 15:12
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Следуя вот этим рекомендациям вырисовывается лишь связка из сохранения структуры дерева в отдельном файле (см. код выше) и данных из нод, но так же в отдельном файле
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
...
type
 PNodeOptions = ^TNodeOptions;
 TNodeOptions = record
  Name:    string[255];
  Surname: string[255];
  Address: string[255];
  EMail:   string[255];
 end;
 
procedure NodeSaveDataProc(Writer: TWriter; Data: Pointer);
begin
 Writer.WriteListBegin;
 with TNodeOptions(Data^) do
 begin
  Writer.WriteString(Name);
  Writer.WriteString(Surname);
  Writer.WriteString(Address);
  Writer.WriteString(EMail);
 end;
 Writer.WriteListEnd;
end;
 
function NodeLoadDataProc(Reader: TReader): Pointer;
var
 P: PNodeOptions;
begin
 New(P);
 try
   Reader.ReadListBegin;
   with P^ do
   begin
    Name:=    Reader.ReadString;
    Surname:= Reader.ReadString;
    Address:= Reader.ReadString;
    EMail:=   Reader.ReadString;
   end;
   Reader.ReadListEnd;
 except
  Dispose(P);
  raise;
 end;
 Result:= P;
end;
 
type
TNodeSaveDataProc = procedure(Writer: TWriter; data: Pointer);
TNodeLoadDataProc = function(Reader: TReader): Pointer;
 
procedure SaveTreeviewToStream(tv: TTreeview; S: TStream;
saveProc: TNodeSaveDataProc);
var
  Writer: TWriter;
  Node:   TTreeNode;
begin
  Assert(Assigned(tv));
  Assert(Assigned(S));
  Assert(Assigned(saveProc));
  Writer:= TWriter.Create(S, 4096);
  try
    Node:= tv.Items[0];
    Writer.WriteListBegin;
    while Node <> nil do
    begin
     Writer.WriteInteger(Node.Level);
     Writer.WriteString(Node.Text);
     Writer.WriteInteger(Node.ImageIndex);
     saveProc(Writer, Node.Data);
     Node:= Node.GetNext;
    end; { While }
    Writer.WriteListEnd;
    Writer.FlushBuffer;
  finally
    Writer.Free;
  end;
end; { SaveTreeviewToStream }
 
procedure LoadTreeviewFromStream(tv: TTreeview; S: TStream;
                  loadProc: TNodeLoadDataProc);
var
  Reader: TReader;
  Node:   TTreeNode;
  Level:  integer;
begin
  Assert(Assigned(tv));
  Assert(Assigned(S));
  Assert(Assigned(loadProc));
  tv.Items.BeginUpdate;
  try
    tv.Items.Clear;
    Reader:= TReader.Create(S, 4096);
    try
      Node:= nil;
      Reader.ReadListBegin;
      while not Reader.EndOfList do begin
        Level := Reader.ReadInteger;
        if Node = nil then
        // create root node, ignore its level
          Node:= tv.Items.Add(nil, '')
        else
        begin
          if Level = Node.Level then
            Node:= tv.Items.Add(node, '')
          else if Level > Node.Level then
            Node:= tv.Items.AddChild(Node, '')
          else begin
            while Assigned(Node) and (Level < Node.Level) do
            Node:= Node.Parent;
            Node:= tv.Items.Add(node, '');
          end; { Else }
        end; { Else }
        Node.Text:= Reader.ReadString;
        Node.ImageIndex:= Reader.ReadInteger;
        Node.Data:= loadProc(Reader);
      end; { While }
      Reader.ReadListEnd;
    finally
      Reader.Free;
    end;
  finally
    tv.items.Endupdate;
  end;
end; { LoadTreeviewFromStream }
 
procedure TForm1.Button1Click(Sender: TObject);
var
 S: TFileStream;
begin
 S := TFileStream.Create('Data.sav', fmCreate or fmShareCompat);
 try
   SaveTreeViewToStream(TreeView1, S, NodeSaveDataProc);
 finally
   S.Free;
 end;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var
 S: TFileStream;
begin
 S := TFileStream.Create('Data.sav', fmOpenRead);
 try
   LoadTreeViewFromStream(TreeView1, S, NodeLoadDataProc);
 finally
   S.Free;
 end;
end;
с последующей загрузкой. Если необходим один файл, то можно попробовать сливать их вместе, а затем резать в памяти на два куска, но есть ли в этом смысл, загадка
Ответить с цитированием
  #7  
Старый 24.02.2014, 20:47
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Думаю, что смысла нет. Скорее всего, дерево обеспечивает только структуру (хотя я не знаю, какая информация "сидит" в заголовке самих нод, если просто объединение тех же данных, что и в прикрепленной записи, то смысла сохранения дерева нет вообще). В этом случае достаточно просто писать все ноды в отдельный файл (поток), а при чтении восстанавливать структуту по файлу.

ЗЫ. Писать код просто влом, там все достаточно просто. Сначала пишется кол-во корневых узлов, потом сами узлы и, рекурсивно, все их подузлы. При чтении - в обратном порядке. Вот псевдокод:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
procedure SaveTree(Stream : TStream);
var
  I : Integer;
begin
  WriteToStream(Stream,RootTreeCount);
  For I := 0 To RootTreeCount-1 Do
    SaveNode(Stream,Nodes[i]);
end;
 
procedure SaveNode(Stream : TStream; Node : TTreeNode);
var
  I : Integer;
begin
  WriteToStream(Stream,Node.Data);
  WriteToStream(Stream,Node.Items.Count);
  For I := 0 To Node.Items.Count-1 Do
    SaveNode(Stream,Node.Items[i]);
end;
Чтение, соотв. наоборот, с созданием нужных узлов.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 19:33.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025