我想用 TMemoryStream 保存并且读取窗体的所有内容。因为一旦控件多了,用INI文件会很麻烦。
可是就是这么简单的程序还时出错,当写入文件时没有任何问题。
可是读取以前保存的文件会出现下面的问题:
1、当用 ReadComponent 读取内容到控件后,窗体的名字会在原来的基础上加 _1 ,比如原来的窗体名称 Form1 ,那么读取后变成了 Form1_1 。如果再次调用 WriteComponent ,那么依此类推,后面会添加无数个 _1 。
这个问题不通过改变窗体名能解决吗?能分析一下怎么回事吗?2、多次调用 ReadComponent 读取内容到控件后会出现错误。其他想要实现的功能:
1、在用 TMemoryStream 保存窗体内容时,是否能修改 TMemoryStream 中已经保存的窗体属性然后再写入到文件。
如果大家还有什么其他保存窗体完整内容方法,请不吝赐教。谢谢!这是我试验的代码。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses
Unit2;
{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
ms: TMemoryStream;
begin
ms:=TMemoryStream.Create;
try
ms.WriteComponent(Self);
ms.SaveToFile('d:\a.txt');
finally
ms.Free;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
var
ms: TMemoryStream;
i: Integer;
begin
ms:=TMemoryStream.Create;
try
ms.LoadFromFile('d:\a.txt');
for i := Self.ComponentCount - 1 downto 0 do
Self.Components[i].Free; ShowMessage(Self.Name); ms.ReadComponent(Self); ShowMessage(Self.Name);
finally
ms.Free;
end;
end;
end.
可是就是这么简单的程序还时出错,当写入文件时没有任何问题。
可是读取以前保存的文件会出现下面的问题:
1、当用 ReadComponent 读取内容到控件后,窗体的名字会在原来的基础上加 _1 ,比如原来的窗体名称 Form1 ,那么读取后变成了 Form1_1 。如果再次调用 WriteComponent ,那么依此类推,后面会添加无数个 _1 。
这个问题不通过改变窗体名能解决吗?能分析一下怎么回事吗?2、多次调用 ReadComponent 读取内容到控件后会出现错误。其他想要实现的功能:
1、在用 TMemoryStream 保存窗体内容时,是否能修改 TMemoryStream 中已经保存的窗体属性然后再写入到文件。
如果大家还有什么其他保存窗体完整内容方法,请不吝赐教。谢谢!这是我试验的代码。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses
Unit2;
{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
ms: TMemoryStream;
begin
ms:=TMemoryStream.Create;
try
ms.WriteComponent(Self);
ms.SaveToFile('d:\a.txt');
finally
ms.Free;
end;
end;procedure TForm1.Button2Click(Sender: TObject);
var
ms: TMemoryStream;
i: Integer;
begin
ms:=TMemoryStream.Create;
try
ms.LoadFromFile('d:\a.txt');
for i := Self.ComponentCount - 1 downto 0 do
Self.Components[i].Free; ShowMessage(Self.Name); ms.ReadComponent(Self); ShowMessage(Self.Name);
finally
ms.Free;
end;
end;
end.
解决方案 »
- 如果在DBGRID的标题点击事件里面写东西
- 如何动态的设定RemoteDataModule中的ADOConnection属性
- 打印的问题,太奇怪了
- 散分200祝日本捧得亚洲杯手球冠军
- 非常急,最后点分了,可以送钱的
- 揭露这种公司的恶行。。。南京的朋友要小心。。。大家来看看,南京公司的丑恶。
- 如何在dbgrid中直接修改数据?
- 急,一个关于stringlist的问题
- 我想用RegisterHotKey设置系统热键,但用THotKey控件来由用户自己定义要设置的热键,请问应该怎么办
- 大家是怎样糟蹋自己的?
- 请教高手一个问题:在win98下面可以使用ADO对象方法访问一个Access数据库吗?(Delphi 7开发)
- 求助一个用StringGrid做的单据(例如出库单,入库单)示例
Self.Components[i].Free;
self.Name := '';//把name置空,就不会变成_1了
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls;type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
btnCreateCheckBox: TButton;
btnLoadCheckBox: TButton;
btnSaveCheckBox: TButton;
BitBtn1: TBitBtn;
procedure btnCreateCheckBoxClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnSaveCheckBoxClick(Sender: TObject);
procedure btnLoadCheckBoxClick(Sender: TObject);
private
{ Private declarations }
aList : TList; procedure DeleteCheckBoxes;
procedure RegisterCheckBoxClass;
procedure LoadCheckBoxes;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}const
OFFSET = 40;
CMPFILENAME = 'custommizedComponents.cks';procedure TForm1.btnCreateCheckBoxClick(Sender: TObject);
var
iCount , iYPos : Integer;
aCB : TCheckBox;
begin
iYPos := 30; for iCount := 1 to 5 do
begin
aCB := TCheckBox.Create(Self);
aCB.Parent := Self.GroupBox1;
aCB.Left := 10;
aCB.Top := iYPos;
aCB.Width := 300;
aCB.Caption := 'CheckBox控件' + IntToStr(iCount);
Inc(iYPos, OFFSET);
aList.Add(aCB);
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
aList := TList.Create;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(aList);
end;procedure TForm1.btnSaveCheckBoxClick(Sender: TObject);
var
fss : TMemoryStream;
iCount : Integer;
begin
try
fss := TMemoryStream.Create;
for iCount := 0 to aList.Count - 1 do
fss.WriteComponent(TCheckBox(aList.Items[iCount])); fss.SaveToFile(CMPFILENAME);
finally
FreeAndNil(fss);
end;
end;procedure TForm1.btnLoadCheckBoxClick(Sender: TObject);
begin
if (FileExists(CMPFILENAME)) then
begin
DeleteCheckBoxes;
RegisterCheckBoxClass;
LoadCheckBoxes;
end;
end;procedure TForm1.DeleteCheckBoxes;
var
iCount : Integer;
begin
for iCount := aList.Count - 1 downto 0 do
begin
TCheckBox(aList.Items[iCount]).Free;
aList.Delete(iCount);
end;
end;procedure TForm1.LoadCheckBoxes;
var
fss : TMemoryStream;
iCount : Integer;
acb : TCheckBox;
begin
try
fss := TMemoryStream.Create;
fss.LoadFromFile(CMPFILENAME);
for iCount := 1 to 5 do
begin
acb := TCheckBox(fss.ReadComponent(nil));
acb.Parent := Self.GroupBox1;
acb.Font.Color := clRed;
aList.Add(acb);
end;
finally
FreeAndNil(fss);
end;
end;procedure TForm1.RegisterCheckBoxClass;
begin
try
Classes.FindClass('TCheckBox');
except
on Exception do
Classes.RegisterClass(TCheckBox);
end;
end;end.
http://blog.csdn.net/linzhengqun/archive/2005/10/15/504406.aspx
不好意思。我初学Delphi ,没能看出那个类怎么解决我的问题呢?
那个类把控件变成流和MemoryStream 的 WriteComponent 方法有什么区别吗?
你可以改变的FORM或其它的控件的属性, 但需要CREATE后再ASSIGN.
1,首先你保存的是整个Form. FREE的是Form上的Button, Form并没有FREE.所以恢复的时候会有问题.
2,ReadComponent返回的是TComponent. 至少需要TCheckBox(fss.ReadComponent(nil));这样转换一下.并设置Parent,(最好读取控件时,要用RegisterClass注册一下类的。)
3.Read保存的控件时,最后ReadComponent(nil);为空的话,要自动调用构造函数来创建实例.不需要再手动create方法了.
DELPHI帮助上:
If Instance is nil (Delphi) or NULL (C++), ReadComponent constructs a component based on the type information in the stream and returns the newly-constructed component.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
checkbox1: TCheckBox;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormDestroy(Sender: TObject);
var
ms: TMemoryStream;
begin
try
ms:= TMemoryStream.Create;
ms.WriteComponent(checkbox1);
ms.SaveToFile('e:\cb.ck');
finally
FreeAndNil(ms);
end;
end;procedure TForm1.FormCreate(Sender: TObject);
var
ms: TMemoryStream;
begin
try
ms:= TMemoryStream.Create;
if FileExists('e:\cb.ck') then
begin
ms.LoadFromFile('e:\cb.ck');
checkbox1:= TCheckBox(ms.ReadComponent(checkbox1));
end;
finally
FreeAndNil(ms);
end;
end;end.