4
votes

Overview

When writing components I like to give my published properties a default value, by doing this the Object Inspector displays any newly changed properties in Bold which of course is very useful to anyone using the component as they can easily identify between default and modified values.

Example

Here is an example of a component containing two Color and two Font properties:

I am making the published properties default inside the class structure:

type
  TMyComponent = class(TComponent)
  private
    FColor: TColor;
    FColorTo: TColor;
    FFont: TFont;
    FFontHot: TFont;
    procedure SetColor(const Value: TColor);
    procedure SetColorTo(const Value: TColor);
    procedure SetFont(const Value: TFont);
    procedure SetFontHot(const Value: TFont);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Color: TColor read FColor write SetColor default clGreen;
    property ColorTo: TColor read FColorTo write SetColorTo default clBlue;
    property Font: TFont read FFont write SetFont; //< set default?
    property FontHot: TFont read FFontHot write SetFontHot; //< set default?
  end;

and the constructor:

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FColor := clGreen;
  FColorTo := clBlue;

  FFont := TFont.Create;
  FFont.Color := clRed;
  FFont.Name := 'Segoe UI';
  FFont.Size := 10;
  FFont.Style := [];

  FFontHot:= TFont.Create;
  FFontHot.Color := clNavy;
  FFontHot.Name := 'Verdana';
  FFontHot.Size := 8;
  FFontHot.Style := [fsItalic];
end;

destructor TMyComponent.Destroy;
begin
  FFont.Free;
  FFontHot.Free;

  inherited Destroy;
end;

Problem

The problem I have is how to make a published Font property be "marked" as default?

When I add the component to the Form both the TFont properties in the Object Inspector are in Bold (non-default). If I click the ellipse next to each published font I can see the values I set from the constructor show up - but again they are in Bold. Oddly enough though, the Size value for each font is never shown in Bold (ie appears unchanged).

Standard published properties can be made default very easily, but how can you do this with classes like TFont that has sub-properties?

I cannot see a way of setting the default values from the class structure, only in the constructor. Even if I could define the default values from the class structure (which seems impossible) I doubt it would work because the font has not been created yet. For example (which obviously does not work):

published
  property FontHot: TFont read FFontHot write SetFontHot default FFontHot.Color := clRed; //< set default?

So, how can I make a published TFont property show as default and unchanged when adding the new component to the Object Inspector?

I guess the same would apply to other classes similar to TFont which as sub-properties.

1

1 Answers

10
votes

For object properties, the default storage specifier is stored. After stored comes False (never save to DFM), True (save always), or a parameterless function returning either. You need the last:

private
  function IsFontStored: Boolean;
published
  property Font: TFont read FFont write SetFont stored IsFontStored;

Within the IsFontStored function, you can decide whether the currently set font is the default font. If so, return False.