DELPHI 动态创建的控件以及其上包含的子控件,用什么方式可以保存到文件中.....
解决方案 »
- 浮点数的存储
- jpg图片添加文字???
- 图象的Transparent的效果处理--万分火急,超值送分啊!!!在线等!
- 关于ADO的注册
- 从ini文件中读出来的“HKEY_LOCAL_MACHINE“是string ,怎样转化使其变为hkey啊
- 哪里有<<Delphi6从入门到精通>>的电子图书下载?
- ComponentCount问题,帮忙看看(在线)!!
- 怎样将一台计算机备份的数据库文件(SQL Server d:\)恢复到另一台计算机上(SQL Server c:\)
- 这是不是Delphi 6.0的bug? (关于ADO)
- 如何改变InfoPower3000控件包中的wwDataInspector控件的字体大小???
- dbexpress
- Sock5 通信问题 delphi
begin
end;
通过遍历倥件的方法 把符合要求的控件保存即可
fs: TFileStream;
begin
fs := TFileStream.Create('C:\test.dat', fmOpenWrite);
fs.WriteComponent(Self);
fs.Free;
end;
这个就是把dfm文件记录的内容以二进制方法保存,保存的原则是以Self为根,递归写入它所有Component的属性及事件值。var
fs: TFileStream;
begin
fs := TFileStream.Create('C:\test.dat', fmOpenRead);
fs.ReadComponent(Self);
fs.Free;
end;
这个就是把它读出来,原则跟上面一样。
在用READComponent时是不是也要动态创建这些控件,然后把保存的属性重新读进去?
在用READComponent时是不是也要动态创建这些控件,然后把保存的属性重新读进去?
i:integer;
begin
for i:=0 to controlcount-1 do
begin
controls[i].name
controls[i].left
controls[i].top
controls[i].width
controls[i].heigth
controls[i].parent //这个非常重要
(**存的时候,存以上几个属性或更多创建的时候要注意parent的问题!**)
end;
end;
procedure TForm1.Button3Click(Sender: TObject); var
S: TStream;
i,j: Integer;
Map: TImage;
PanelM: TPanel;
panel:Tpanel; buttona:tbutton;
{buttonb:tbutton;
buttonc:tbutton;
buttond:tbutton;
buttone:tbutton;} tmpStrList, btnStrList: TStrings;
tmpStr, tmpLeft, tmpTop, tmpWidth, tmpHeight, tmpFileName: String;
btnStr, btnLeft, btnTop, btnWidth, btnHeight, bntFileName: string;
bLeft,bTop,bWidth,bHeight:String;
begin
for i := 0 to RichEditNew.ControlCount - 1 do
begin
RichEditNew.Controls[0].Free;
end;
if OpenDialog1.Execute then
begin
tmpFileName := OpenDialog1.FileName;
bntFileName:=tmpFileName+'bnt';
tmpStrList := TStringList.Create;
btnStrList:=TStringList.Create;
S := TFileStream.Create(tmpFileName, fmOpenRead);
S.ReadComponent(RichEditNew);
tmpStrList.LoadFromFile(ExtractFilePath(tmpFileName) + ExtractFileName(tmpFileName)+'.info');
for i := 0 to tmpStrList.Count - 1 do
try
tmpStr := tmpStrList.Strings[i];
tmpLeft := ListValue(tmpStr, 2);
tmpTop := ListValue(tmpStr, 3);
tmpWidth := ListValue(tmpStr, 4);
tmpHeight := ListValue(tmpStr, 5); Panel := TPanel.Create(Self);
Panel.Parent := RichEditNew;
Panel.Name := 'myPanel' + IntToStr(i+1); Map := TImage.Create(Self);
Map.Parent := Panel;
Map.Name := 'myMap' + IntToStr(i+1); S.ReadComponent(Panel);
S.ReadComponent(Map); Panel.Parent := RichEditNew;
Panel.Left := StrToInt(tmpLeft);
Panel.Top := StrToInt(tmpTop);
Panel.Width := StrToInt(tmpWidth);
Panel.Height := StrToInt(tmpHeight); Map.OnMouseMove := FMouseMove;
Map.Parent := Panel;
except
Map.Free;
Panel.Free;
end;btnStrList.LoadFromFile(ExtractFilePath(bntFileName) + ExtractFileName(bntFileName)+'.info');
for j := 0 to btnStrList.Count - 1 do
try
btnStr := btnStrList.Strings[j];
btnLeft := ListValue(btnStr, 2);
btnTop := ListValue(btnStr, 3);
btnWidth := ListValue(btnStr, 4);
btnHeight := ListValue(btnStr, 5);
bLeft:=ListValue(btnStr,6);
bTop:=ListValue(btnStr,7);
bWidth:=ListValue(btnStr,8);
bHeight:=ListValue(btnStr,9); PanelM := TPanel.Create(Self);
PanelM.Parent := RichEditNew;
// PanelM.Name := 'myPanelm' + IntToStr(j+1);
panelM.onMouseDown:=PanelMMouseDown; buttona:=Tbutton.Create(self);
buttona.parent:=panelm;
// buttona.Name :='mybuttona'+inttostr(j+1); S.ReadComponent(Panelm);
S.ReadComponent(buttona); PanelM.Parent := RichEditNew;
Panelm.Left := StrToInt(btnLeft);
Panelm.Top := StrToInt(btnTop);
Panelm.Width := StrToInt(btnWidth);
Panelm.Height := StrToInt(btnHeight); buttona.Parent:=panelm;
buttona.Left:=StrToInt(bLeft);
buttona.Top:=strtoint(btop);
buttona.width:=strtoint(bwidth);
buttona.height:=strtoint(bheight); except
buttona.Free;
{buttonb.Free;
buttonc.Free;
buttond.Free;
buttone.Free; }
Panelm.Free;
end;
S.Free;
end;
// end;
end;procedure TForm1.Button4Click(Sender: TObject);//保存
var
S: TStream;
i,j: Integer;
tmpStrList: TStrings;//记录图片的位置
btnStrList: TStrings;//记录PANEL上BUTTON的位置
tmpFileName,bntFileName: String;
begin
if SaveDialog1.Execute then
begin
tmpFileName := SaveDialog1.FileName;
bntFileName:=tmpFileName+'bnt';
// 保存元件到文件
tmpStrList := TStringList.Create;
btnstrList:=TStringList.Create;
S := TFileStream.Create(tmpFileName, fmCreate);
try
S.WriteComponent(RichEditNew);
for i := 0 to RichEditNew.ControlCount - 1 do
begin
if RichEditNew.Controls[i] is TPanel then
begin
S.WriteComponent(TPanel(RichEditNew.Controls[i]));
if TPanel(RichEditNew.Controls[i]).Controls[0] is TImage then
begin
S.WriteComponent(TImage(TPanel(RichEditNew.Controls[i]).Controls[0]));
tmpStrList.Add('myPanel'+IntToStr(i + 1)+','+'myImage'+IntToStr(i + 1)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Left)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Top)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Width)+','
+IntToStr(TPanel(RichEditNew.Controls[i]).Height));
end;
end;
end;
tmpStrList.SaveToFile(ExtractFilePath(tmpFileName) + ExtractFileName
(tmpFileName)+'.info');
for j := 0 to RichEditNew.ControlCount - 1 do
begin
if RichEditNew.Controls[j] is TPanel then
begin
// S.WriteComponent(TPanel(RichEditNew.Controls[j]));
//for j:= 0 to Tpanel(RichEditNew.controls[i]).controlcount -1 do
//begin
if TPanel(RichEditNew.Controls[j]).Controls[0] is Tbutton then
begin
S.WriteComponent(Tbutton(TPanel(RichEditNew.Controls[j]).Controls[0]));
btnStrList.Add('myPanelM'+IntToStr(j + 1)+','+'mybuttona'+IntToStr(j + 1)+','
+IntToStr(TPanel(RichEditNew.Controls[j]).Left)+','
+IntToStr(TPanel(RichEditNew.Controls[j]).Top)+','
+IntToStr(TPanel(RichEditNew.Controls[j]).Width)+','
+IntToStr(TPanel(RichEditNew.Controls[j]).Height)+','
+IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Left)+','
+IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Top)+','
+IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Width)+','
+IntToStr(Tbutton(TPanel(RichEditNew.Controls[j]).controls[0]).Height));
end;
end;
end;
btnStrList.SaveToFile(ExtractFilePath(bntFileName) + ExtractFileName
(bntFileName)+'.info');
//end;
finally
S.Free;
tmpStrList.Free;
btnStrList.Free;
end;
end;
end;
直接用XML节点表示这些控件就行了
如:
<?xml version="1.0" encoding="UTF-8">
<Control ClassName="RichEditNew">
<Control ClassName="Image">
<Left>100<Left>
<Top>12<Top>
<Width>200<Width>
<Height>400<Height>
</Control>
<Control ClassName="Button">
<Left>20<Left>
<Top>12<Top>
<Width>20<Width>
<Height>40<Height>
</Control>
</Control>
保存的时候递归遍历RichEditNew的所有子控件,写入到XML,读的时候就递归遍历XML节点,创建控件设置属性即可
WriteComponent(Panel1)就可以了
而你要还原Panel的控件,只要ReadComponent(Panel1)就可以了
但是前提是你要保存的控件的Owner是Panel1。
例如:
btn1 := TButton.Create(Panel1);
btn1.Parent := Panel1;
Img1 := TImage.Create(Panel1);
Img1.Parent := Panel1;
这样你调用WriteComponent(Panel1)就会把btn1和Img1写入流。
而使用ReadComponent(Panel1)就会创建btn1和Img1,并把它的Parent设置为Panel1
procedure TForm1.Button1Click(Sender: TObject);
var
img: TImage;
btn: TButton;
fs: TFileStream;
begin
img := TImage.Create(Panel1);
img.Parent := Panel1;
img.SetBounds(0, 0, 100, 100);
btn := TButton.Create(Panel1);
btn.Parent := Panel1;
btn.SetBounds(100, 100, 80, 20);
fs := TFileStream.Create('C:\a.dat', fmCreate or fmOpenWrite);
fs.WriteComponent(Panel1);
fs.Free;
end;procedure TForm1.Button2Click(Sender: TObject);
var
fs: TFileStream;
begin
RegisterClasses([TImage, TButton]);
fs := TFileStream.Create('C:\a.dat', fmOpenRead);
fs.ReadComponent(Panel1);
fs.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
img: TImage;
btn: TButton;
fs: TFileStream;
begin
img := TImage.Create(Panel1);
img.Parent := Panel1;
img.SetBounds(0, 0, 100, 100);
btn := TButton.Create(Panel1);
btn.Parent := Panel1;
btn.SetBounds(100, 100, 80, 20);
fs := TFileStream.Create('C:\a.dat', fmCreate or fmOpenWrite);
fs.WriteComponent(Panel1);
fs.Free;
end;procedure TForm1.Button2Click(Sender: TObject);
var
fs: TFileStream;
pnl: TPanel;
begin
RegisterClasses([TImage, TButton, TPanel]);
fs := TFileStream.Create('C:\a.dat', fmOpenRead);
pnl := fs.ReadComponent(nil) as TPanel;
pnl.Parent := Self;
fs.Free;
end;
你自己写个Demo来试,试不出来再贴出来,你原来那代码太乱了
function ComponentToString(Component: TComponent): string;var
BinStream:TMemoryStream;
StrStream: TStringStream;
s: string;
begin
BinStream := TMemoryStream.Create;
try
StrStream := TStringStream.Create(s);
try
BinStream.WriteComponent(Component);
BinStream.Seek(0, soFromBeginning);
ObjectBinaryToText(BinStream, StrStream);
StrStream.Seek(0, soFromBeginning);
Result:= StrStream.DataString;
finally
StrStream.Free; end;
finally
BinStream.Free
end;
end;function StringToComponent(Value: string): TComponent;
var
StrStream:TStringStream;
BinStream: TMemoryStream;
begin
StrStream := TStringStream.Create(Value);
try
BinStream := TMemoryStream.Create;
try
ObjectTextToBinary(StrStream, BinStream);
BinStream.Seek(0, soFromBeginning);
Result := BinStream.ReadComponent(nil); finally
BinStream.Free;
end;
finally
StrStream.Free;
end;
end;