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
Solved

Compound component and properties

Posted on 2000-04-11
19
297 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
  • 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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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 shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

809 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