Solved

Create a VCL property with 3 sub-properties

Posted on 2000-05-16
11
240 Views
Last Modified: 2013-11-23
How can I create a property into my component that can be displayed in
ObjectInspector with +MyProperty ?
When I click on it to roll down some new properties .
Alike Anchors or Font or ....

I need to add a property named MyColors with 3 sub-properties :
ColorHight
ColorLow
ColorBetween .

A code sample for do that ?

Regards,
Nick
0
Comment
Question by:ginsonic
  • 5
  • 2
  • 2
  • +1
11 Comments
 
LVL 10

Expert Comment

by:Lischke
ID: 2814027
Hi Nick,

usually subcomponents use an already defined property editor class, like TFont for which automatically necessary properties for the object inspector are declared. For new subcomponents you need to write an own property editor. The easiest way to do that is to derive it from TClassProperty:

  TGLTextureProperty = class(TClassProperty)
  protected
    function GetAttributes: TPropertyAttributes; override;
  end;

The GetAttributes function returns some flags which describe how the object inspector should handle the property:

function TGLTextureProperty.GetAttributes: TPropertyAttributes;

begin
  Result := [paSubProperties];
end;

You could also include paDialog to create the little button with the 2 points (like the one for TFont).

Finally you must register your new property editor with the particular property:

RegisterPropertyEditor(TypeInfo(TGLTexture), TGLMaterial, '', TGLTextureProperty);

The example TGLMaterial is here to limit the use of the new editor to all TGLTexture properties of the class TGLMaterial. If this would be nil then the editor could be used for any class where a property is of type TGLTexture. This way you can redefine a property editor for already existing classes (I did it with wide strings and have now for ever wide string property (even for already existing components) my new editor.

Ciao, Mike
0
 
LVL 10

Accepted Solution

by:
ptmcomp earned 50 total points
ID: 2814974
That's one solution.

Another solution:

TMyClass= class(TPersistent);
private
  FColorHight: TMyType;
  ...
published
  property ColorHight: Integer read FColorHight write FColorHight;
  property ...
end;

TMyComponent
private
  FColors: TMyClass;
public
  constructor Create(aOwner: TComponent); override; // create here the Colors object (FColors:= TMyClass.Create)
  destructor; override; // and destroy it here
publish
  property Colors: TMyClass read FColors;
end;

Regards, ptm.
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 2814984
Lischke's solution works if MyColors is a component...
0
 
LVL 3

Expert Comment

by:Stefaan
ID: 2816034
Hi,

IMHO the best way is to make a component of it, which descends from TPersistent like ptmcomp said.

Most of the time I do it that way, and it works perfectly.

Stefaan
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2816264
My solution works also with TPersistent. The point, though, is that no special property editor is needed if only the subproperties should be shown in the object inspector. How could I miss that? So it just turns out to be ptmcomp said:

1) create your MyColor class

TMyColor = class(TPersistent)
private
  FColorHigh,
  FColorLow,
  FColorBetween: TColor;
published
  property ColorHigh: TColor read FColorHigh write FColorHigh;
  property ColorLow: TColor read FColorLow write FColorLow;
  property ColorBetween: TColor read FColorBetween write FColorBetween;
end;


2) create the container component

TMyComponent = class(TComponent)
private
  FMyColor: TMyColor;
  procedure SetMyColor(const Value: TMyColor);
public
  constructor Create(AOwner: TComponent); override;
  destructor Destroy; override;
published
  property MyColor: TMyColor read FMyColor write SetMyColor;
end;

TMyComponent.SetMyColor(const Value: TMyColor);
begin
  FMyColor.Assign(Value); // or directly set the values
end;

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMyColor := TMyColor.Create;
end;

destructor TMyComponent.Destroy;
begin
  FMyColor.Free;
  inherited;
end;

Ciao, Mike
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 9

Author Comment

by:ginsonic
ID: 2817034
I can't use the values or colors .
I can paint first time , but when I change , for example , the ColorHight the component don't repaint .

I try it the SetMyColor from Mike code ,  but don't work :(
I used Invalidate , Paint ... don't work .
If I put over my component a form and then I move it ( force the paint ) the component is painted OK .

Comments ?

Regards,
Nick
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2817640
Also this is no big problem. In order to have the component reflect changes of its properties you need set methods instead directly writing to the internal variables:

TMyColor = class(TPersistent)
private
  FColorHigh,
  FColorLow,
  FColorBetween: TColor;
  FOwner: TControl;
  procedure SetColorHigh(const Value: TColor);
public
  constructor Create(AOwner: TControl);
published
  property ColorHigh: TColor read FColorHigh write SetColorHigh;
end;

constructor TMyColor.Create(AOwner: TControl);

begin
  inherited;
  FOwner = AOwner;
end;

procedure TMyColor.SetColorHigh(const Value: TColor);

begin
  FOwner.Invalidate;
end;

The owner for the TMyColor class is of course TMyComponent which should pass itself as owner while creating FMyColor:

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMyColor := TMyColor.Create(Self);
end;

Ciao, Mike
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2817647
Oops, forgot something:

procedure TMyColor.SetColorHigh(const Value: TColor);

begin
  if FColorHigh <> Value then
  begin
    FColorHigh := Value;
    FOwner.Invalidate;
  end;
end;

Ciao, Mike
0
 
LVL 3

Expert Comment

by:Stefaan
ID: 2817687
Hi,

Can you show us the code please, so we can give you some additional help >


Stefaan
0
 
LVL 9

Author Comment

by:ginsonic
ID: 2822682
Work now .

ptmcomp give me first the right answer , but Lischke complete it .....

I will give these points to ptmcomp and I will put a new question for Lischke . Another 50 points .

Lischke please let a comment if you read that message to give you another 50 points .

THANKS TO ALL .
0
 
LVL 10

Expert Comment

by:Lischke
ID: 2824645
Okey, dokey.

Ciao, Mike
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

705 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now