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.
source to share
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.
source to share
@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;
source to share