Столкнулся с такой проблемой: Есть в лазарусе такой класс 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 ... очень так серьезно мешает.