[fpc-pascal] WriteComponent not outputting a hierarchy of components?
Graeme Geldenhuys
graemeg.lists at gmail.com
Thu Jun 3 17:09:14 CEST 2010
I'm using FPC 2.4.1
I'm experimenting with streaming (read & write) components to build a form
and runtime from an external file (something like GTK2 has with Glade). I
have a ReadForm() method very similar to the SaveForm below, and it works
pretty well. All components placed directly on the form are loaded and
displayed correctly, except if you have nested components. eg: a Panel on
the Form and then components inside the Panel.
I thought that maybe I am creating the *.frm files (text object format of
form) incorrectly, so wrote the code below to see what the RTL does
automatically for me.
procedure SaveForm(AForm: TComponent);
var
f, f2: TStream;
Filename: string;
TextStream, BinStream: TStream;
begin
Filename := LowerCase(Copy(AForm.ClassName, 2, 255)) + '.frm';
BinStream := TMemoryStream.Create;
TextStream := TFileStream.Create(Filename, fmCreate);
BinStream.WriteComponent(AForm);
BinStream.Position := 0;
ObjectBinaryToText(BinStream, TextStream);
TextStream.Free;
BinStream.Free;
end;
For some reason a call: SaveForm(self)
... in a button click, creates the *.frm file, but in only writes the
TfpgForm published properties. It doesn't write any information about the
other components on the form, or nested components.
-------[ actual content of *.frm file ]-----------------------
object CheckBoxForm: TCheckBoxForm
Height = 400
Left = 520
MaxHeight = 0
MaxWidth = 0
MinHeight = 32
MinWidth = 32
ModalResult = mrNone
Sizeable = True
Top = 166
Width = 400
WindowPosition = wpOneThirdDown
WindowTitle = 'Check box test'
end
----------------[ end ]----------------------
What is WriteComponent() looking for to traverse a Form?
I quickly put together the code shown below. It traverses components on the
form and writes each components name width indentation to show
relationships to the console. I also use ComponentCount and Components[],
and the output looks fine (output also shown below). So I really don't know
what WriteComponent() is struggling with. Any clues?
------------------------------------
procedure TTestForm.Button1Click(Sender: TObject);
var
ind: string;
procedure TraverseComponents(AComponent: TComponent);
var
p: string;
i: integer;
begin
p := ind;
for i := 0 to AComponent.ComponentCount-1 do
begin
writeln(ind + AComponent.Components[i].Name);
if AComponent.Components[i].ComponentCount > 0 then
begin
ind := ind + ' ';
TraverseComponents(AComponent.Components[i]);
ind := p;
end;
end;
end;
begin
// SaveForm(self);
ind := '';
TraverseComponents(self);
end;
------------------------------------
-------[ output of above code ]-----------
CheckBox1
CheckBox2
CheckBox3
GroupBox1
Label1
Edit1
Button1
--------------------
Regards,
- Graeme -
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://opensoft.homeip.net/fpgui/
More information about the fpc-pascal
mailing list