Здравствуйте, в этой статье я хотел бы рассказать как можно сохранить узлы в Stream. Данную переменную можно хранить где угодно, в файле, БД. Мы остановимся на БД, так как чаще всего для отображения узлов используют именно БД, а там мы и будем хранить Stream, а добраться до БД и удалить, например эти узлы будет очень сложно, если например БД стоит на сервере, так, что Вы полностью в данном случае контролируете эти данные и пользователь как говорится не сделает так, что программа будет работать не корректно. Я выбрал БД MS Access, ну во-первых она наверное у всех под рукой, а во-вторых в Delphi предусмотрены стандартные компоненты для работы с данной БД. Я расскажу как я делал на данной БД, а это можно переделать под любую, под тот же самый MySQL. По поводу сохранения узлов в файл я рассказывал, тут принцип такой же, только вместо файла мы используем БД. На события OnLoadNode и OnSaveNode нам прописывать ничего не надо, так как там уже все написано (мы писали в прошлой статье, когда сохраняли в файл) и оно будет работать и с помощью файлов и с помощью Stream.
Давайте подготовим наш проект, нам потребуются следующие дополнительные компоненты
- TADOCOnnection
- TADOQuery
- TButton — 2 шт
Настроим TADOConnection к нашей БД. БД я создал с 2 полями, 1 поле — это идентификатор (который символизирует уникальности), 2 поле — это поле типа объект OLE. Как я ним работать я ранее рассказывал. Смысл в сохранении то, что мы будем сохранять и если в БД есть уже наши узлы, то мы их будем заменять, если нету, то вставляем новые, в итоге у нас получится то, что все время в нашей таблице будет одна запись с нашими узлами. Давайте теперь сохраним наши узлы, для этого на событие OnClick нашей кнопки сохранить я написал следующий код
procedure TForm1.Button5Click(Sender: TObject);
var
AdoStream:TMemoryStream;
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM TableStream');
ADOQuery1.Active:=True;
if ADOQuery1.RecordCount>0 then
begin
ADOQuery1.First;
ADOQuery1.Edit;
AdoStream:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName('stream')),bmWrite);
VirtualStringTree1.SaveToStream(AdoStream);
AdoStream.Free;
ADOQuery1.Post;
end
else
begin
ADOQuery1.Insert;
AdoStream:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName('stream')),bmWrite);
VirtualStringTree1.SaveToStream(AdoStream);
AdoStream.Free;
ADOQuery1.Post;
end;
finally
end;
end;
То есть здесь все понятно я думаю, проверяем если есть что в БД, то редактируем, если нету, то вставляем новую запись с нашими узлами. Как работать с БД и в частности с Blob-полями я рассказывал раньше, сможете найти информацию в разделе Базы данных. Если открыть нашу БД, то мы сможем увидеть, что добавилось новая запись, в данной записи написано, что в ней есть какие-то двоичные данные, значит можно спокойно говорить о том, что туда что-то записалось и будем надеется, что наши узлы =).
Теперь давайте откроем и отобразим эти узлы в нашем дереве. Для этого на кнопку, на событие OnClick я написал следующий код
procedure TForm1.Button6Click(Sender: TObject);
var
AdoStream:TMemoryStream;
begin
try
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM TableStream');
ADOQuery1.Active:=True;
if ADOQuery1.RecordCount=0 then
begin
ShowMessage('Not Stream in Table');
exit;
end;
ADOQuery1.First;
AdoStream:=TADOBlobStream.Create(TBlobField(ADOQuery1.Fields[1]),bmRead);
VirtualStringTree1.LoadFromStream(AdoStream);
AdoStream.Free;
finally
end;
end;
Как считывать из Blob-полей я также говорил, просто делаем перед этим проверку, что в нашей таблице что-то есть, если есть, то считываем наши двоичные данные в Stream, а затем с помощью LoadFromStream загружаем, а событие OnLoadNode отображается за нас узлы в дерево, на это событие мы раньше записывали код, который сохраняли узлы в файл. Про это можете почитать в статье — про сохранение узлов в файл.
В следующей статье про TVirtualStringTree поговорим как можно рядом с узлами отображать картинки