Solved

Compound component and properties

Posted on 2000-04-11
19
301 Views
Last Modified: 2013-11-23
I created a component assembled from different other components.
Where some components have again childcomponents.
Now my problem is: How can I stream all properties from those components and subcomponents to a *.dfm .
0
Comment
Question by:gipa
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 8
19 Comments
 
LVL 1

Expert Comment

by:DonBartholomew
ID: 2703367
If you want to tell Luc about EE, he already knows.
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2703588
Hi gipa,

all published properties and classes are automatically saved into the DFM file. If you have classes which are only public then you need to override DefineProperties in the particular container and stream out explicitely the classes in question.

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2703713
Mike,

If I understand you well, I should stream out every property from a class I use.
But can’t I stream the whole subcomponent out, I don’t want to write a Read and a write for each property.

Patrick.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:Lischke
ID: 2703759
No no, you don't need to stream all properties of all subcomponents. Depending on what you want to have saved you can either make the particular property/class published or you save them yourself. Can you give us a snippet of the container class with some of the properties to be saved? Then we can discuss this on the "living" example...

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2703862
Mike,

Type
 MyBrowser = class(TCustomPanel)
 private
   FOutBar: TDCOutBar;
   FGrid: TDbGrid;
 public
    property OutLookBar: TDCOutBar
      read   GetOutLookBar
      write SetOutLookBar;
 published
 end;


 One of the props of FOutBar is
 FOutBar.Groups[i] //(TDCOutBarGroup)  

//   this could be
// DCOutBarGroup.Caption
// DCOutBarGroup.Align and ……

So I want to stream every Group from FOutbar.
If there are 5 groups then I want per group all the props in the *.dfm.
Is this possible?

// Dream OutBar
// This is Something like a Outlookbar and has subcomponents like Groups, Listviews and ...
// http://www.dream- com.com

Patrick.
0
 

Author Comment

by:gipa
ID: 2703864
Mike,

Type
 MyBrowser = class(TCustomPanel)
 private
   FOutBar: TDCOutBar;
   FGrid: TDbGrid;
 public
    property OutLookBar: TDCOutBar
      read   GetOutLookBar
      write SetOutLookBar;
 published
 end;


 One of the props of FOutBar is
 FOutBar.Groups[i] //(TDCOutBarGroup)  

//   this could be
// DCOutBarGroup.Caption
// DCOutBarGroup.Align and ……

So I want to stream every Group from FOutbar.
If there are 5 groups then I want per group all the props in the *.dfm.
Is this possible?

// Dream OutBar
// This is Something like a Outlookbar and has subcomponents like Groups, Listviews and ...
// http://www.dream- com.com

Patrick.
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2703934
Patrick,

well, I don't see why this should not be possible. You have not published the Outlookbar class. Is there a reason why you want to have it only public? I ask because this way you cannot modify it at design time. If you publish it then all problems should be gone, because it's published properties are automatically saved.

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2704269
Mike,

I Edit the properties with a ComponentEditor at design-time.
If I publish this component all what I can see in the object Inspector is the name of the component.

So if you can tell me how to stream this component, that would be very nice.

Patrick.
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2706966
Patrick, for non-standard components published as properties of other components you need to write a property editor (for the property being a component) and override the GetAttributes method. There you need to return the flag paSubProperties (among others if appropriate). This is the way to make it working in the object inspector saving you work to stream your component.

The other way is to override DefineProperties in your container component.

  TMyBrowser = class(TCustomPanel)
  protected
    procedure DefineProperties(Filer: TFiler); override;
  end;


procedure TMyBrowser.DefineProperties(Filer: TFiler);

  function DoWrite: Boolean;
  begin
    Result := determine somehow whether there is to write something or not;
  end;

begin
  Filer.DefineProperty('OutlookBar', ReadData, WriteData, DoWrite);
end;

This method will be called by the streaming system of the VCL when loading or storing your browser component. There's a good example in the online help which shows all you need. Look in the index for DefineProperties. The first entry in the sublist is the example.

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2707109
Mike,

Something is written to the dfm file.
But it is unreadable, and i got a stream read error.

// this is the code i used

procedure TBrowser32.LoadCompProperty(Reader: TReader);
begin
  if Reader.ReadBoolean then
    FOutBar:= TDCOutBar(Reader.ReadComponent(nil));
end;

procedure TBrowser32.StoreCompProperty(Writer: TWriter);

begin
  Writer.WriteBoolean(FOutBar <> nil);
  if FOutBar <> nil then
    Writer.WriteComponent(FOutBar);
end;

procedure TBrowser32.DefineProperties(Filer: TFiler);

  function DoWrite: Boolean;
  begin
    if Filer.Ancestor <> nil then { check Ancestor for an inherited value }
    begin
      if TBrowser32(Filer.Ancestor).FOutBar = nil then
        Result := FOutBar <> nil
      else if (FOutBar = nil) or
         (TBrowser32(Filer.Ancestor).FOutBar.Name <> FOutBar.Name) then
        Result := True

      else Result := False;
    end
    else { no inherited value -- check for default (nil) value }
      Result := FOutBar <> nil;
  end;
begin
  inherited; { allow base classes to define properties }
  Filer.DefineProperty('MyCompProperty', LoadCompProperty, StoreCompProperty, DoWrite);
end;
0
 

Author Comment

by:gipa
ID: 2707118
Adjusted points from 200 to 500
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2707259
Mmmh, strange. Your code looks ok. Are you using D5? I ask because with D5 you have to possibility to save a DFM in text form, not only binary. From what I can see in Classes.pas all TWriter methods write binary data only. Perhaps this is your problem? See, if your form is saved as text DFM and switch it if so...

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2707272
Mike,

Yes it is saved as Text.

Patrick.
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2707293
Aha, then switch the flag so that the DFM is saved in binary form (right click, switch off "text DFM"). Then change something in the form and save it. Does this work?

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2707358
Mike,

Yes it works partly.
But now there is an other problem my outlookbar changed is parent, the component isn’t the parent anymore but the form is.

Patrick.
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2707484
Well, I would change the read procedure so:

procedure TBrowser32.LoadCompProperty(Reader: TReader);
begin
  if Reader.ReadBoolean then
  begin
    FOutBar:= TDCOutBar(Reader.ReadComponent(nil));
    FOutBar.Parent := Self;
  end;
end;

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2707501
Mike,

I tried that already, bot its not solving the whole problem because now then outlookbar lay’s on top of the component and I can delete it from my component.

Patrick.
0
 
LVL 10

Accepted Solution

by:
Lischke earned 500 total points
ID: 2707560
I'm a bit confused now. When you create the bar in the browser then you set its parent property also being the browser, don't you? Why should this be different to the Parent assignment above?

Btw: You can avoid that the VCL creates the component for you. I assume you create the bar in the browser's constructor. There you can set all needed properties (Owner, Parent). Then pass this component reference so:

  FOutBar:= Reader.ReadComponent(FOutBar);

Perhaps this solves the other problem too.

Ciao, Mike
0
 

Author Comment

by:gipa
ID: 2707606
Thanks for helping me sorting this problem out.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question