Delphi 2009 - setting default property values ​​in delphi custom components

It should be very simple, but I can't seem to find the exact answer I want. I have a TSpeedButton based delphi custom control. I want the Caption property for the SpeedButton to always be "comments", but I don't want to set it at runtime. I want to set it in the component itself so that when I place it in my form it will already be filled with this text. I also want to set the height and width of the button, but I'm guessing the method for doing this would be the same as for setting the caption.

For completeness, here's the component code:

unit CustomSpeedButton;

interface

uses
  SysUtils, Classes, Controls, Buttons;

type
  TCustomSpeedButton = class(TSpeedButton)
  private
    FCommentText: string;
    FCommentTitle: string;

    procedure SetCommentText(const Value: string);
    procedure SetCommentTitle(const Value: string);

    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }

  published
    { Published declarations }
    property CommentTitle: string read FCommentTitle write SetCommentTitle;
    property CommentText: string read FCommentText write SetCommentText;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TCustomSpeedButton]);
end;

{ TCustomSpeedButton }

procedure TCustomSpeedButton.SetCommentText(const Value: string);
begin
  FCommentText := Value;
end;

procedure TCustomSpeedButton.SetCommentTitle(const Value: string);
begin
  FCommentTitle := Value;
end;

end.

      

+2


source to share


3 answers


Since you wanted the Caption property to be done correctly, Mason's answer won't work because he missed the "csSetCaption" and his "default" clause won't work either because both Caption and your properties are string types ...

Below are the units you want.

The behavior looks like this:

  • Internally, the value of the Caption property will be "Comments"
  • users can override this at design time by setting a new value

(If you don't want 2.you need to assign the Caption property in the overridden Loaded method like that mentioned by Ken, however it was not clear from your question if you want this. If you do, please rephrase your question.)

This is how the code works.

For string properties, you cannot hint at any default threading system . But you can set the initial value for design time in the constructor: Caption: = DefaultCustomSpeedButtonCaption;

For the Caption property, you must also turn off the default Caption property assignment (otherwise your component will automatically receive a caption, such as "CustomSpeedButton1"). This line does it for you: ControlStyle: = ControlStyle - [csSetCaption];



Finally, it is good practice to split the component registration into a separate block. This allows you to have a design-time package that registers your components with the IDE and a run-time package (or no package at all) to use your components in your applications.

If you have a component icon, then you also load it in the registration block (since this is only needed during development).

Ray Konopka has written an excellent book on writing components that is still very relevant: Developing Custom Delphi 3 Components Like many good books in Delphi, this is out of print, but you can order a PDF copy on your site .

I'm not sure what your CommentTitle and CommentText properties are for, so I saved them in the source below.

Listing 1: the actual component

unit CustomSpeedButtonUnit;

interface

uses
  SysUtils, Classes, Controls, Buttons;

const
  DefaultCustomSpeedButtonCaption = 'Comments';

type
  TCustomCustomSpeedButton = class(TSpeedButton)
  strict private
    FCommentText: string;
    FCommentTitle: string;
  strict protected
    procedure SetCommentText(const Value: string); virtual;
    procedure SetCommentTitle(const Value: string); virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property CommentTitle: string read FCommentTitle write SetCommentTitle;
    property CommentText: string read FCommentText write SetCommentText;
  end;

  TCustomSpeedButton = class(TCustomCustomSpeedButton)
  published
// note you cannot use 'default' for string types; 'default' is only valid for ordinal ordinal, pointer or small set type
// [DCC Error] CustomSpeedButtonUnit.pas(29): E2146 Default values must be of ordinal, pointer or small set type
//    property Caption default DefaultCustomSpeedButtonCaption;
    property CommentTitle;
    property CommentText;
  end;

implementation

constructor TCustomCustomSpeedButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Caption := DefaultCustomSpeedButtonCaption;
  ControlStyle := ControlStyle - [csSetCaption];
end;

destructor TCustomCustomSpeedButton.Destroy;
begin
  inherited Destroy;
end;

procedure TCustomCustomSpeedButton.SetCommentText(const Value: string);
begin
  FCommentText := Value;
end;

procedure TCustomCustomSpeedButton.SetCommentTitle(const Value: string);
begin
  FCommentTitle := Value;
end;

end.

      

Listing 2: registering components

unit CustomSpeedButtonRegistrationUnit;

interface

procedure Register;

implementation

uses
  CustomSpeedButtonUnit;

procedure Register;
begin
  RegisterComponents('Standard', [TCustomSpeedButton]);
end;

end.

      

+3


source


You need to set initial values ​​in the component constructor.



EDIT: you'll want to add a constructor as well ControlStyle := ControlStyle - [csSetCaption];

.

+2


source


@Etherman: if you want to have a default string property and you want to store it in the DFM - even if it's BLANK - you need to do it yourself. Fortunately, Delphi gives you ways to do this. Take a look at this code:

type
  TMyComp = class(TControl)
  private
    FMyStringProperty: string;
    procedure WriteMyStringProperty(Writer: TWriter);
    procedure DefineProperties(Filer: TFiler);  override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property MyStringProperty: string read FMyStringProperty write FMyStringProperty stored False;
  end;


implementation


constructor TMyComp.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMyStringProperty := 'my default value';
end;

procedure TMyComp.WriteMyStringProperty(Writer: TWriter);
begin
  Writer.WriteString(FMyStringProperty);
end;

procedure TMyComp.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  Filer.DefineProperty('MyStringProperty', nil, WriteMyStringProperty, True);
end;

      

+1


source







All Articles