TTreeView и XML

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

TTreeView и XML

Сообщение vada » 16.09.2016 16:32:24

Добрый день форумчане!
Столкнулся с такой проблемой: Есть в лазарусе такой класс TXMLConfig. С его помощью можно записать свойства объекта в XML файл, и загрузить его от туда.
В поставке лазаруса есть даже пример d:\lazarus\examples\xmlstreaming\. Все зашибись работает в примере, но! Попробовал я упрятать в XML экземпляр класса TTreeView, и очень огорчился, т.к. TTreeView умудряется писать в XML двоичные данные!!!!
Код: Выделить всё
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
  <TreeViewMainMenu>
    <component name="TreeViewMainMenu" class="TTreeView">
      <properties>
        <integer name="Left" value="0"/>
        <integer name="Height" value="654"/>
        <integer name="Top" value="26"/>
        <integer name="Width" value="208"/>
        <ident name="Align" value="alLeft"/>
        <boolean name="AutoExpand" value="true"/>
        <integer name="DefaultItemHeight" value="16"/>
        <integer name="TabOrder" value="2"/>
        <set name="Options" value="tvoAutoExpand,tvoAutoItemHeight,tvoHideSelection,tvoKeepCollapsedNodes,tvoShowButtons,tvoShowLines,tvoShowRoot,tvoToolTips,tvoThemedDraw"/>
        <binary name="Items.Data" value="тут дальше идут двоичные данные. Их, естественно, я не могу вставить в данный раздел"/>
      </properties>
    </component>
  </TreeViewMainMenu>
</CONFIG>


Ну и дальше все как и ожидалось, распарсить такой XML никто не может, даже сам TXMLConfig. Ругается, типа, #0 встретился в XML.
В исходниках TTreeView есть методы для записи и чтения свойств экземпляра класса. И, таки, да! Пишутся двоичные данные.
Код: Выделить всё
procedure TTreeNode.WriteData(Stream: TStream);
var
  i: integer;
  Info: TTreeNodeInfo;
begin
  Info.ImageIndex := ImageIndex;
  Info.SelectedIndex := SelectedIndex;
  Info.OverlayIndex := OverlayIndex;
  Info.StateIndex := StateIndex;
  Info.Height := FHeight;
  Info.Count := Count;
  Info.Expanded := Expanded;
  Info.TextLen := Length(Text);
  Stream.WriteBuffer(Info, SizeOf(TTreeNodeInfo));
  if Text<>'' then
    Stream.Write(FText[1],length(Text));
  for i := 0 to Count - 1 do
    Items[i].WriteData(Stream);
end;


Код: Выделить всё
procedure TTreeNode.ReadData(Stream: TStream; StreamVersion: integer);
var
  I, ItemCount: Integer;
  NewExpanded: boolean;
  OldInfo: TOldTreeNodeInfo;
  Info: TTreeNodeInfo;
  Node: TTreeNode;
  lSelfAX: TLazAccessibleObject;
begin
  if Owner<>nil then Owner.ClearCache;
  if StreamVersion=TTreeNodeWithPointerStreamVersion then
  begin
    Stream.ReadBuffer(OldInfo, SizeOf(TOldTreeNodeInfo));
    ImageIndex := OldInfo.ImageIndex;
    SelectedIndex := OldInfo.SelectedIndex;
    StateIndex := OldInfo.StateIndex;
    OverlayIndex := OldInfo.OverlayIndex;
    Data := OldInfo.Data;
    Height := OldInfo.Height;
    NewExpanded := OldInfo.Expanded;
    ItemCount := OldInfo.Count;
    SetLength(FText,OldInfo.TextLen)
  end
  else
  begin
    Stream.ReadBuffer(Info, SizeOf(TTreeNodeInfo));
    ImageIndex := Info.ImageIndex;
    SelectedIndex := Info.SelectedIndex;
    StateIndex := Info.StateIndex;
    OverlayIndex := Info.OverlayIndex;
    Height := Info.Height;
    NewExpanded := Info.Expanded;
    ItemCount := Info.Count;
    SetLength(FText,Info.TextLen);
  end;
  if FText<>'' then
  begin
    Stream.Read(FText[1],length(FText));
    // Update accessibility information
    if TreeView<>nil then
    begin
     lSelfAX := TreeView.GetAccessibleObject.GetChildAccessibleObjectWithDataObject(Self);
     if lSelfAX <> nil then
       lSelfAX.AccessibleValue := FText;
    end;
  end;
  if Owner<>nil then begin
    for I := 0 to ItemCount - 1 do begin
      Node:=Owner.AddChild(Self, '');
      Node.ReadData(Stream, StreamVersion);
      Owner.Owner.Added(Node);
    end;
  end;
  Expanded := NewExpanded;
end;


Чё за нафиг? Такой тайный смысл заложили разработчики в TTreeView ? Ведь в XML нету двоичного типа данных. Что хотели сказать?
И ведь поправить этот косяк весьма не просто. Закопано все очень так глубоко. Вот это ключевое слово в XML <binary ... очень так серьезно мешает.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: TTreeView и XML

Сообщение sts » 16.09.2016 17:17:03

не важно что хотели разработчики TTreeView, важно что TXMLConfig ущербен раз не может серелизовать бинарные данные, например через BASE64 или BinToHex на крайняк.
кароче надо по исходникам поискать 'binary' и в case для него добавить, на запись BinToHex, на чтение HexToBin и вуаля.
sts
постоялец
 
Сообщения: 415
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Re: TTreeView и XML

Сообщение vada » 16.09.2016 17:35:21

Я уже это попробовал. :( Не так все просто. При чтении binary, если находит текст, то ридер тупо его пропускает. Надо избежать тега <binary.
Там все надо переделать, и запись и чтение.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: TTreeView и XML

Сообщение sts » 16.09.2016 17:38:02

ну дык я так и написал, добавить вызов промежуточных функций в два места в исходниках, должно быть все просто
sts
постоялец
 
Сообщения: 415
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Re: TTreeView и XML

Сообщение Лекс Айрин » 17.09.2016 11:01:42

А там реально бинарные данные? Или это просто ошибка преобразования PChar to String?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: TTreeView и XML

Сообщение vada » 19.09.2016 11:59:56

Лекс Айрин Там в первом посте исходники приведены. Разумно пишутся бинарные значения.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16

Рейтинг@Mail.ru
cron