AFAIK (happy to be proved wrong) WriteComponentAsTextToStream() does not have the power to recognise that a TComponent property will contain subproperties, unfurl those class properties and write such class property data to the stream. The only property it sees is the component name.
You have to add this capability yourself by overriding TPersistent's virtual DefineProperties() method, and add appropriate TReaderProc and TWriterProc methods (where you see they are needed) to stream the TComponent property's 'subproperties'. In your case you can leave the Demo1 class and the initialization block unchanged. You have to extend the Demo2 class as follows:
...
TDemo2 = class(TComponent)
private
FDemo1: TDemo1;
FSomeText: string;
procedure ReadInt(Reader: TReader);
procedure WriteInt(Writer: TWriter);
procedure ReadStr(Reader: TReader);
procedure WriteStr(Writer: TWriter);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure SaveToTextFile(FileName: string);
procedure DefineProperties(Filer: TFiler); override;
published
property Demo1: TDemo1 read FDemo1 write FDemo1;
property SomeText: string read FSomeText write FSomeText;
end;
implementation
var
demo2: TDemo2;
{ TDemo2 }
procedure TDemo2.ReadInt(Reader: TReader);
begin
Demo1.ID:=Reader.ReadInteger;
end;
procedure TDemo2.WriteInt(Writer: TWriter);
begin
Writer.WriteInteger(Demo1.ID);
end;
procedure TDemo2.ReadStr(Reader: TReader);
begin
Demo1.Str:=Reader.ReadString;
end;
procedure TDemo2.WriteStr(Writer: TWriter);
begin
Writer.WriteString(Demo1.Str);
end;
constructor TDemo2.Create(AOwner: TComponent);
begin
FDemo1 := TDemo1.Create(Self);
inherited Create(AOwner);
end;
destructor TDemo2.Destroy;
begin
inherited Destroy;
end;
procedure TDemo2.SaveToTextFile(FileName: string);
var
AStream: TMemoryStream;
begin
AStream := TMemoryStream.Create;
try
WriteComponentAsTextToStream(AStream, Self);
AStream.SaveToFile(FileName);
finally
AStream.Free;
end;
end;
procedure TDemo2.DefineProperties(Filer: TFiler);
begin
Filer.DefineProperty('Demo1.ID', @ReadInt, @WriteInt, True);
Filer.DefineProperty('Demo1.Str', @ReadStr, @WriteStr, (Demo1.Str<>''));
end;
...