我通过序列化和反序列化表单及其内容到Delphi编写了以下代码
unit SerAndDeser;
interface
uses Classes,MainForm,ListOfTables,DataOfTable,SerialForms,sysutils,ActiveX, DatabaseClasses, UnloadProcs;
procedure Ser();
procedure Deser();
function GetGUID(): string;
function DeleteSymbols(inputstr : string) : string;
implementation
function GetGUID(): string;
var
GUID : TGUID;
begin
Result := '';
if CoCreateGuid(GUID) = 0 then
Result := GUIDToString(GUID);
Result := StringReplace(Result, '{', '', []);
Result := StringReplace(Result, '}', '', []);
Result := StringReplace(Result, '-', '', [rfReplaceAll]);
end;
function DeleteSymbols(inputstr : string): string;
begin
Result := '';
Result := StringReplace(inputstr, '-', '', [rfReplaceAll]);
Result := StringReplace(Result, ' ', '', [rfReplaceAll]);
Result := StringReplace(Result, '\', '', [rfReplaceAll]);
Result := StringReplace(Result, '/', '', [rfReplaceAll]);
end;
procedure Ser();
var mForm : MainFormInfo;
tForm : TableFormInfo;
lForm : ListFormInfo;
tempFmtable : TfmTableData;
i,j : integer;
MyFileStream : TFileStream;
MyMemoryStream : TMemoryStream;
field : TableFieldInfo;
begin
try
mForm := nil;
mForm := MainFormInfo.Create(
nil,
MainWindow.Left,
MainWindow.Top,
MainWindow.Height,
MainWindow.Width,
MainWindow.partofconnectstring,
MainWindow.dbname,
MainWindow.dbfilename);
mForm.Name := 'MainWindow';
//table forms
try
tForm := nil;
field := nil;
for i := 0 to MainWindow.ComponentCount - 1 do
if (MainWindow.Components[i] is TfmTableData) then
begin
tempFmtable := MainWindow.Components[i] as TfmTableData;
tForm := TableFormInfo.Create(
mForm,
tempFmtable.Left,
tempFmtable.Top,
tempFmtable.Height,
tempFmtable.Width,
tempFmtable.tname);
tForm.Name := tempFmtable.Name;
//fields
for j := 0 to tempFmtable.DBGrid1.Columns.Count - 1 do
begin
field := nil;
field := TableFieldInfo.Create(
tForm,
tempFmtable.DBGrid1.Columns[j].FieldName,
tempFmtable.DBGrid1.Columns[j].Title.Caption,
tempFmtable.DBGrid1.Columns[j].Index,
tempFmtable.DBGrid1.Columns[j].Visible);
field.Name := DeleteSymbols(tempFmtable.DBGrid1.Columns[j].FieldName);{tempFmtable.DBGrid1.Columns[j].FieldName} {+ GetGUID;}
end;
//
end;
except
field.Free;
tForm.Free;
end;
//
//List form
try
lForm := nil;
lForm := ListFormInfo.Create(
mForm,
fmListOfTables.Left,
fmListOfTables.Top,
fmListOfTables.Height,
fmListOfTables.Width);
lForm.Name := 'fmListOfTables';
except
lForm.Free;
end;
//
//save
MyFileStream := nil;
MyMemoryStream := nil;
MyFileStream := TFileStream.Create('test.txt', fmCreate);
MyMemoryStream := TMemoryStream.Create;
MyMemoryStream.WriteComponent(mForm);
MyMemoryStream.Position := 0;
ObjectBinaryToText(MyMemoryStream,MyFileStream);
MainWindow.Panel1.DockManager.SaveToStream(MyFileStream);
//
finally
mForm.Free;
MyFileStream.Free;
MyMemoryStream.Free;
end;
end;
procedure Deser();
var mForm : MainFormInfo;
tForm : TableFormInfo;
lForm : ListFormInfo;
tempFmtable : TfmTableData;
i,j : integer;
MyFileStream : TFileStream;
MyMemoryStream : TMemoryStream;
table : TTableSpec;
descr : string;
field : TableFieldInfo;
begin
try
//destroy environment
i := 0;
while (i <= MainWindow.ComponentCount - 1) do
begin
if MainWindow.Components[i] is TfmTableData then
try
tempFmTable := nil;
tempFmTable := MainWindow.Components[i] as TfmTableData;
tempFmTable.IBQuery1.Close;
tempFmtable.Free;
except
tempFmTable.Free;
end
else
inc(i);
end;
fmListOfTables.Free;
DBSchema.Free;
//
//read
mForm := nil;
MyFileStream := nil;
MyMemoryStream := nil;
mForm := MainFormInfo.Create(nil, -1, -1, -1, -1, MainWindow.partofconnectstring, MainWindow.dbname, MainWindow.dbfilename);
MyFileStream := TFileStream.Create('test.txt', fmOpenRead);
MyMemoryStream := TMemoryStream.Create;
ObjectTextToBinary(MyFileStream,MyMemoryStream);
MyMemoryStream.Position := 0;
MyMemoryStream.ReadComponent(mForm);
//
//go
UnloadProcs.ConnectToDatabase(MainWindow.partofconnectstring, MainWindow.SQLConnection1);
//UnloadProcs.CreateObjs(MainWindow.SQLConnection1, MainForm.DBSchema);
//fmListOfTables.Show;
MainWindow.Left := mForm.LeftValue;
MainWindow.Top := mForm.TopValue;
MainWindow.Height := mForm.HeightValue;
MainWindow.Width := mForm.WidthValue;
//list
i := 0;
while i <= mForm.ComponentCount - 1 do
begin
if mForm.Components[i] is ListFormInfo then
try
lForm := nil;
lForm := mForm.Components[i] as ListFormInfo;
fmListOfTables.Left := lForm.LeftValue;
fmListOfTables.Top := lForm.TopValue;
fmListOfTables.Height := lForm.HeightValue;
fmListOfTables.Width := lForm.WidthValue;
fmListOfTables.Show;
inc(i);
finally
lForm.Free;
end
else
inc(i);
end;
//
//fmListOfTables.Show;
//tables
for j := 0 to mForm.ComponentCount - 1 do
if mForm.Components[j] is TableFormInfo then
try
table := nil;
tempFmtable := nil;
tForm := nil;
tForm := mForm.Components[j] as TableFormInfo;
table := TTableSpec(DBSchema.Tables.FindComponent(tForm.Table));
tempFmtable := TfmTableData.Create(MainWindow);
tempFmtable.Name := tForm.Name;
tempFmtable.tname := tForm.Table;
//tempFmtable.Caption := Utf8ToAnsi(table.Description);
tempFmtable.Left := tForm.LeftValue;
tempFmtable.Top := tForm.TopValue;
tempFmtable.Height := tForm.HeightValue;
tempFmtable.Width := tForm.WidthValue;
tempFmTable.IBQuery1.SQL.Clear;
tempFmtable.IBQuery1.SQL.Add('select * from ' + table.Name);
tempFmtable.IBQuery1.Open;
i := 0;
while i <= tForm.ComponentCount - 1 do
if tForm.Components[i] is TableFieldInfo then
begin
field := nil;
field := tForm.Components[i] as TableFieldInfo;
tempFmtable.DBGrid1.Columns[i].FieldName := field.FieldNameValue;
tempFmtable.DBGrid1.Columns[i].Title.Caption := field.DescriptionValue;
tempFmtable.DBGrid1.Columns[i].Index := field.IndexValue;
tempFmtable.DBGrid1.Columns[i].Visible := field.VisibleValue;
//tempFmtable.CheckListBox1.Items.Add(field.Description);
//tempFmtable.CheckListBox1.Checked[i] := field.Visible;
inc(i);
end
else
inc(i);
{for i := 0 to table.Fields.ComponentCount - 1 do
begin
descr := Utf8ToAnsi(((table.Fields.Components[i]) as TFieldSpec).Description);
tempFmtable.CheckListBox1.Items.Add(descr);
tempFmtable.DBGrid1.Columns[i].Title.Caption := descr;
tempFmtable.CheckListBox1.Checked[i] := true;
end; }
tempFmtable.Show;
except
tempFmtable.Free;
tForm.Free;
table.Free;
end;
//
//dock
MainWindow.Panel1.DockManager.BeginUpdate;
MainWindow.Panel1.DockManager.LoadFromStream(MyFileStream);
MainWindow.Panel1.DockManager.ResetBounds(TRUE);
MainWindow.Panel1.DockManager.EndUpdate;
//
finally
MyFileStream.Free;
MyMemoryStream.Free;
end;
end;
end.
调试时我发现给出了
'Project GUI.exe raised exception class $C0000005 with message 'access violation at 0x00821dae: read of address 0x00000044'.
线上异常
tempFmtable.IBQuery1.SQL.Add('select * from ' + table.Name);
在以下代码块中的代码更高
//tables
for j := 0 to mForm.ComponentCount - 1 do
if mForm.Components[j] is TableFormInfo then
try
table := nil;
tempFmtable := nil;
tForm := nil;
tForm := mForm.Components[j] as TableFormInfo;
table := TTableSpec(DBSchema.Tables.FindComponent(tForm.Table));
tempFmtable := TfmTableData.Create(MainWindow);
tempFmtable.Name := tForm.Name;
tempFmtable.tname := tForm.Table;
//tempFmtable.Caption := Utf8ToAnsi(table.Description);
tempFmtable.Left := tForm.LeftValue;
tempFmtable.Top := tForm.TopValue;
tempFmtable.Height := tForm.HeightValue;
tempFmtable.Width := tForm.WidthValue;
tempFmTable.IBQuery1.SQL.Clear;
tempFmtable.IBQuery1.SQL.Add('select * from ' + table.Name);
tempFmtable.IBQuery1.Open;
i := 0;
while i <= tForm.ComponentCount - 1 do
if tForm.Components[i] is TableFieldInfo then
begin
field := nil;
//tempFmtable.Show;
field := tForm.Components[i] as TableFieldInfo;
tempFmtable.DBGrid1.Columns[i].FieldName := field.FieldNameValue;
tempFmtable.DBGrid1.Columns[i].Title.Caption := field.DescriptionValue;
tempFmtable.DBGrid1.Columns[i].Index := field.IndexValue;
tempFmtable.DBGrid1.Columns[i].Visible := field.VisibleValue;
//tempFmtable.CheckListBox1.Items.Add(field.Description);
//tempFmtable.CheckListBox1.Checked[i] := field.Visible;
//tempFmtable.Show;
inc(i);
end
else
inc(i);
{for i := 0 to table.Fields.ComponentCount - 1 do
begin
descr := Utf8ToAnsi(((table.Fields.Components[i]) as TFieldSpec).Description);
tempFmtable.CheckListBox1.Items.Add(descr);
tempFmtable.DBGrid1.Columns[i].Title.Caption := descr;
tempFmtable.CheckListBox1.Checked[i] := true;
end; }
tempFmtable.Show;
except
tempFmtable.Free;
tForm.Free;
table.Free;
end;