gpt4 book ai didi

Delphi流面板到文件

转载 作者:行者123 更新时间:2023-12-03 15:53:54 27 4
gpt4 key购买 nike

今天我有一个关于将表单的一部分流式传输到文件的问题。在此示例中,我使用 Tmemo 而不是文件来查看流。

这是我的表格:

enter image description here

表单右上角的面板有一些控件,如标签、编辑等。使用“保存面板”按钮将面板保存在 TStream 上:

代码如下:

procedure TfrmMain.btnSaveClick(Sender: TObject);
var
idx: Integer;
MemStr: TStream;
begin
MemStr := TMemoryStream.Create;
PanelStr := TMemoryStream.Create;
try
for idx := 0 to pnlSource.ControlCount - 1 do begin
MemStr.Position := 0;
MemStr.WriteComponent(pnlSource.Controls[idx]);
StreamConvert(MemStr);
end;
PanelStr.Position := 0;
mmoStream.Lines.LoadFromStream(PanelStr);
finally
MemStr.Free;
end;
end;

这里是 StreamConvert:

{ Conversione stream in formato testo }
procedure TfrmMain.StreamConvert(aStream: TStream);
var
ConvStream: TStream;
begin
aStream.Position := 0;
ConvStream := TMemoryStream.Create;
try
ObjectBinaryToText(aStream, ConvStream);
ConvStream.Position := 0;
PanelStr.CopyFrom(ConvStream, ConvStream.Size);
lblStreamSize.Caption := IntToStr(ConvStream.Size);
finally
ConvStream.Free;
end;
end;

PanelStr 是在表单的私有(private)部分中声明并在表单创建期间创建的 TStream 对象。这部分效果很好,正如您在图像的右侧部分看到的那样,表单上存在的元素已正确注册。

现在我的问题是将此元素恢复到表单左下角的面板中。我已经尝试过这个例程:

{ Carica i controlli presenti nel pannello pnlSource in uno stream }
procedure TfrmMain.btnLoadClick(Sender: TObject);
var
idx: Integer;
MemStr: TStream;
begin
pnlSource.Free;
MemStr := TMemoryStream.Create;
try
PanelStr.Position := 0;
ObjectTextToBinary(PanelStr, MemStr);
MemStr.Position := 0;
MemStr.ReadComponent(pnlTarget);
finally
MemStr.Free;
end;
end;

但是它不起作用,在下图中您可以看到结果:

enter image description here

我的例程出了什么问题,如何读取流中存在的所有元素而不仅仅是第一个元素?

有人可以帮我解决这个头痛问题吗?

最佳答案

您当前运行的代码有效地将源面板转换为标签。这是因为第一个流式传输的对象是标签,并且代码仅读取一个组件。 IOW,当读取器到达第一个 end 时,读取已完成,因为流中没有 sub 控件。

所以,首先,您必须编写面板 - 并且只编写面板。该面板是应该传输其子项的面板。为了让它这样做,它必须拥有它的控件。

var
idx: Integer;
MemStr: TStream;
begin
MemStr := TMemoryStream.Create;
PanelStr := TMemoryStream.Create;
try
// transfer ownership of controls to the panel
for idx := 0 to pnlSource.ControlCount - 1 do
pnlSource.InsertComponent(pnlSource.Controls[idx]);
// write the panel
MemStr.WriteComponent(pnlSource);

StreamConvert(MemStr);
PanelStr.Position := 0;
mmoStream.Lines.LoadFromStream(PanelStr);
finally
MemStr.Free;
end;

这会产生如下所示的备忘录输出:

object pnlSource: TPanel
Left = 8
Top = 8
Width = 201
Height = 265
Caption = 'pnlSource'
TabOrder = 0
object Label1: TLabel
Left = 48
Top = 208
Width = 31
Height = 13
Caption = 'Label1'
end
object Label2: TLabel
...

请注意标签定义的缩进以及所属面板缺少的“结尾”(位于末尾)。

您需要为流媒体注册类,以便在加载时能够找到它们:

var
idx: Integer;
MemStr: TStream;
begin
pnlSource.Free;

RegisterClasses([TLabel, TEdit, TCheckBox, TRadioButton]);

MemStr := TMemoryStream.Create;
try
PanelStr.Position := 0;
ObjectTextToBinary(PanelStr, MemStr);
MemStr.Position := 0;
MemStr.ReadComponent(pnlTarget);
finally
MemStr.Free;
end;

注册当然可以转移到其他地方,例如表单创建或单元初始化。

如果需要,您还可以将控件的所有权转移回表单,例如保存代码。

关于Delphi流面板到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41021756/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com