Link to home
Start Free TrialLog in
Avatar of doogie
doogie

asked on

Caption problem with derived TSpeedButton Component?

Hi

I really am having a problem with this one.

I have created a component, which is derived from the TSpeedButton.
The problem I am having is twofold:

(1) I would like to be able to set the caption of the derived component to a
default value eg: 'This button'
      It then displays in the property editor, but not on the button.
(2) I would like to be able to allow the user to change the button caption
at design time, if he or she wishes to have a different caption to the
default one, but the default button caption is going to be linked to the
ButtonType property, which can be one of two values, and if the user changes
this property, the caption must be reflected.

This is quite a request I know!!!... all help will really be appreciated

Adrian Wreyford
Avatar of ZifNab
ZifNab

heh? Sorry.
Don't quite understand your question.
If your component is derived from TSpeedButton, you should be able to change the caption property at design time because it is a published property.

To set default value to the caption property,  add the following to the constructor of your component:
caption:= '????'
Does this do you any good at all?:

unit MyBitBtnUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;

type
  TMyButtonStyles = ( bsDefault, bsCustom );
  TMyBitBtn = class(TSpeedButton)
  protected
    FDefCaption  : TCaption;
    FSavedCaption: TCaption;
    FButtonStyle : TMyButtonStyles;
    procedure SetDefCaption( sCaption: TCaption );
    procedure SetCustCaption( sCaption: TCaption );
    procedure SetButtonStyle( bs: TMyButtonStyles );
    { Protected declarations }
  public
    constructor Create( AOwner: TComponent ); override;
    { Public declarations }
  published
    property DefaultCaption: TCaption read FDefCaption write SetDefCaption;
    property Caption: TCaption read FSavedCaption write SetCustCaption;
    property ButtonStyle: TMyButtonStyles read FButtonStyle write SetButtonStyle;
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMyBitBtn]);
end;

procedure TMyBitBtn.SetButtonStyle( bs: TMyButtonStyles );
begin
  FButtonStyle := bs;
  case FButtonStyle of
    bsDefault: inherited Caption := FDefCaption;
    bsCustom : inherited Caption := FSavedCaption;
  end;
end;

procedure TMyBitBtn.SetCustCaption( sCaption: TCaption );
begin
  FSavedCaption := sCaption;
  if ( FButtonStyle = bsCustom ) then inherited Caption := sCaption;
end;

procedure TMyBitBtn.SetDefCaption( sCaption: TCaption );
begin
  FDefCaption := sCaption;
  if ( FButtonStyle = bsDefault ) then inherited Caption := sCaption;
end;

constructor TMyBitBtn.Create( AOwner: TComponent );
begin
  inherited Create( AOwner );
  FSavedCaption := 'Caption';
  FDefCaption := 'This button';
  Width := 65; // so there's room
  SetButtonStyle( bsDefault );
end;

end.

/// John
I read your question again and this time... I didn't understand it. So my previous comment is probably really numbskulled.
So... could you please try to explain again, like I was six years old. :-)

/// John

One more try before i go to sleep (it's 2.30 in the morning here you know)...

unit MySpeedBtnUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;

type
  TMyButtonStyles = ( bsMode1, bsMode2 );
  TMySpeedBtn = class(TSpeedButton)
  protected
    FButtonStyle : TMyButtonStyles;
    procedure SetButtonStyle( bs: TMyButtonStyles );
    { Protected declarations }
  public
    constructor Create( AOwner: TComponent ); override;
    { Public declarations }
  published
    property ButtonStyle: TMyButtonStyles read FButtonStyle write SetButtonStyle;
    { Published declarations }
  end;

const
  DEFCAPTIONS : array[ TMyButtonStyles ] of string = ( 'Default 1', 'Default 2' );

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMySpeedBtn]);
end;

procedure TMySpeedBtn.SetButtonStyle( bs: TMyButtonStyles );
begin
  FButtonStyle := bs;
  if not ( csDesigning in ComponentState )
  then Caption := DEFCAPTIONS[ FButtonStyle ];
end;

constructor TMySpeedBtn.Create( AOwner: TComponent );
begin
  inherited Create( AOwner );
  if ( csDesigning in ComponentState )
  then Caption := 'Button'
  else Caption := DEFCAPTIONS[ FButtonStyle ];
  Width := 75; // so there's room
end;

end.

This was probably not what you wanted either, but you can't blame a guy for trying?...

/// John
I'm not sure if I understand.
You want to have a TSpeedButton with a ButtonType property of two possible types.  Each button type will have its own caption and the button will display the appropriate caption for the currently set type.  Each caption will have a default but may be overriden by the user.  Is that what you are trying to do?
D.
Hey...
Qesution #1)  Use this to change the caption....

constructor Create(AComp : TComponent);
begin
  Inherited Create(AComp);
  {Your code goes here...if there is any}
  Caption := 'This button';
end;
-------------------
As I read ?#2 I wasn;t sure what are you trying to do...Maybe a litle more exaplaining will be better...Don't ya think?

Regards,
Viktor Ivanov
PS in the create constructor you should write something like this. If you don't, it will propably not work.

ControlStyle := ControlStyle - [csSetCaption];

This will prevent creation of buttons with captions MyButton1, MyButton2, MyButton3...


Avatar of doogie

ASKER

Thanks for all the interest shown from all parties:
Here is my code... perhaps that will clear up all the confusion.
Check the comments at the SetCaption procedure

unit DobAgeBtn;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons;

type
  TDobAgeBtnType = (btDobAge, btAgeDob);

type
  TDobAgeBtn = class(TSpeedButton)
  private
    { Private declarations }
    FCaption: string;          //here i declare it
    FDOB: TDateTime;
    FAgeYears: string;
    FAgeMonths: string;
    FAgeDays: string;
    FCalcYears: string;
    FCalcMonths: string;
    FCalcDays: string;
    FCalcDOB: TDateTime;
    FCalcType: TDobAgeBtnType;
    procedure SetAge (const Value: TDateTime);
    procedure SetDOBY (const Value: String);
    procedure SetDOBM (const Value: String);
    procedure SetDOBD (const Value: String);
    procedure SetCaption(Value: string);     //precedure to set caption
    procedure SetCalcType(Value: TDobAgeBtnType);
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Caption: String read FCaption write SetCaption;
    Property DOB: TDateTime read FDOB write SetAge;
    Property AgeYears: string read FAgeYears write SetDOBY;
    Property AgeMonths: string read FAgeMonths write SetDOBM;
    Property AgeDays: string read FAgeDays write SetDOBD;
    {The following properties are read only, and accessible at runtime}
    Property CalcDOB: TDateTime read FCalcDOB;
    Property CalcYears: string read FCalcYears;
    Property CalcMonths: string read FCalcMonths;
    Property CalcDays: string read FCalcDays;
    property CalcType: TDobAgeBtnType read FCalcType write SetCalcType default btDobAge;
  end;

procedure Register;

implementation

constructor TDobAgeBtn.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  FCaption := 'Dob:Age';     //Default caption set here
  FCalcType := btDobAge;     // for this default button type
end;

procedure Register;
begin
  RegisterComponents('Samples', [TDobAgeBtn]);
end;

destructor TDobAgeBtn.Destroy;
begin
  inherited Destroy;
end;

procedure TDobAgeBtn.SetAge (const Value: TDateTime);
{code to calculate comes here}
end;

procedure TDobAgeBtn.SetCaption (Value: string);
begin
// when I do this, the caption is displayed in the property editor as Dob:Age, but not on the button placed on the form!
If you change the caption... the caption is changed on the button to de text you enter, but not while typing as is the usual behaviour, but only once exiting the property, but then something funny happens, the caption displays the text entered, butthe property reverts back to the default???? this is my problem!

If FCaption <> Value then
   begin
   inherited Caption := value;
   Invalidate; // attempt to force redraw???
   end;
end;

procedure TDobAgeBtn.SetCalcType(Value: TDobAgeBtnType);
begin
If FCalcType <> Value then
   begin
   FCalcType := value;
   end;
end;

procedure TDobAgeBtn.SetDOBY (const Value: String);
{code to calculate comes here}
end;

procedure TDobAgeBtn.SetDOBM (const Value: String);
{code to calculate comes here}
end;

procedure TDobAgeBtn.SetDOBD (const Value: String);
{code to calculate comes here}
end;

end.
Avatar of doogie

ASKER

Thanks for all the interest shown from all parties:
Here is my code... perhaps that will clear up all the confusion.
Check the comments at the SetCaption procedure

unit DobAgeBtn;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons;

type
  TDobAgeBtnType = (btDobAge, btAgeDob);

type
  TDobAgeBtn = class(TSpeedButton)
  private
    { Private declarations }
    FCaption: string;          //here i declare it
    FDOB: TDateTime;
    FAgeYears: string;
    FAgeMonths: string;
    FAgeDays: string;
    FCalcYears: string;
    FCalcMonths: string;
    FCalcDays: string;
    FCalcDOB: TDateTime;
    FCalcType: TDobAgeBtnType;
    procedure SetAge (const Value: TDateTime);
    procedure SetDOBY (const Value: String);
    procedure SetDOBM (const Value: String);
    procedure SetDOBD (const Value: String);
    procedure SetCaption(Value: string);     //precedure to set caption
    procedure SetCalcType(Value: TDobAgeBtnType);
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    property Caption: String read FCaption write SetCaption;
    Property DOB: TDateTime read FDOB write SetAge;
    Property AgeYears: string read FAgeYears write SetDOBY;
    Property AgeMonths: string read FAgeMonths write SetDOBM;
    Property AgeDays: string read FAgeDays write SetDOBD;
    {The following properties are read only, and accessible at runtime}
    Property CalcDOB: TDateTime read FCalcDOB;
    Property CalcYears: string read FCalcYears;
    Property CalcMonths: string read FCalcMonths;
    Property CalcDays: string read FCalcDays;
    property CalcType: TDobAgeBtnType read FCalcType write SetCalcType default btDobAge;
  end;

procedure Register;

implementation

constructor TDobAgeBtn.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  FCaption := 'Dob:Age';     //Default caption set here
  FCalcType := btDobAge;     // for this default button type
end;

procedure Register;
begin
  RegisterComponents('Samples', [TDobAgeBtn]);
end;

destructor TDobAgeBtn.Destroy;
begin
  inherited Destroy;
end;

procedure TDobAgeBtn.SetAge (const Value: TDateTime);
{code to calculate comes here}
end;

procedure TDobAgeBtn.SetCaption (Value: string);
begin
// when I do this, the caption is displayed in the property editor as Dob:Age, but not on the button placed on the form!
If you change the caption... the caption is changed on the button to de text you enter, but not while typing as is the usual behaviour, but only once exiting the property, but then something funny happens, the caption displays the text entered, butthe property reverts back to the default???? this is my problem!

If FCaption <> Value then
   begin
   inherited Caption := value;
   Invalidate; // attempt to force redraw???
   end;
end;

procedure TDobAgeBtn.SetCalcType(Value: TDobAgeBtnType);
begin
If FCalcType <> Value then
   begin
   FCalcType := value;
   end;
end;

procedure TDobAgeBtn.SetDOBY (const Value: String);
{code to calculate comes here}
end;

procedure TDobAgeBtn.SetDOBM (const Value: String);
{code to calculate comes here}
end;

procedure TDobAgeBtn.SetDOBD (const Value: String);
{code to calculate comes here}
end;

end.
Hey guys, I think doogie wants to have the following:
In a TBitBtn, one can set the Kind property to bkOK, bkCancel,... bkCustom. Depending on the value of this prop., the Glyph property is automaticalle set by the component itself. As far as I understood the Q, doogie wants to have this feature for the Caption as well.
My recommendation: take a look at Borland's sources of TBitBtn and examine how they did.
You quite probably have to write a property interface function SetCaptionTyp(AValue: TCaptonType) that checks wether user wants to have default caption or not. Also, you will need a prop.int. function SetCaption(AValue: string) that checks wether the Caption to be set *is* the default caption or not and then adjusts the CaptionType property accordingly!

On caveat:
Don't even think of setting the Caption of this Button in it's constructor!! As you can see in Q.10067138, it is *not* recommendable to set any properties that are attached to visual controls in the constructor. If you want to set default values, do so in the CreateWnd procedure! For some controls and props, it may work to make use of customization code in the constructor, but if you come to such complicated controls like treeviews and listviews, you'll get busted it you try, believe me!

Cheers, Freter
Avatar of doogie

ASKER

Thanks to the input from erajoj / John. He had the answer, but my question might not have been that clear, and using his advice I managed to solve it. No the caption acts as I wish it to.
On initialisation ... default style
If you change the caption to eg 'rrerwe' it is reflected, and reamains that.
If you now change the default style, the default style is reflected in the caption, etc .. etc


Here is my final code.. note the modifications of Johns code to get to the result
Thanks to all
John gets the points!!!!!

unit DobAgeBtn;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Buttons;

type
  TDobAgeBtnStyle = (bsDobAge, bsAgeDob);

type
  TDobAgeBtn = class(TSpeedButton)
  private
    { Private declarations }
    FDOB: TDateTime;
    FAgeYears: string;
    FAgeMonths: string;
    FAgeDays: string;
    FCalcYears: string;
    FCalcMonths: string;
    FCalcDays: string;
    FCalcDOB: TDateTime;
    FButtonStyle: TDobAgeBtnStyle;
    procedure SetAge (const Value: TDateTime);
    procedure SetDOBY (const Value: String);
    procedure SetDOBM (const Value: String);
    procedure SetDOBD (const Value: String);
    procedure SetButtonStyle(bs: TDobAgeBtnStyle);
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    Property DOB: TDateTime read FDOB write SetAge;
    Property AgeYears: string read FAgeYears write SetDOBY;
    Property AgeMonths: string read FAgeMonths write SetDOBM;
    Property AgeDays: string read FAgeDays write SetDOBD;
    {The following properties are read only, and accessible at runtime}
    Property CalcDOB: TDateTime read FCalcDOB; { write FCalcDOB;}
    Property CalcYears: string read FCalcYears; { write FcalcYears;}
    Property CalcMonths: string read FCalcMonths; {write FCalcmonths;}
    Property CalcDays: string read FCalcDays; {write FCalcDays;}
    property ButtonStyle: TDobAgeBtnStyle read FButtonStyle write SetButtonStyle default bsDobAge;
    end;
   
  const
  DEFCAPTIONS: array[TDobAgeBtnStyle] of string = ('Dob:Age','Age:Dob');

procedure Register;

implementation

constructor TDobAgeBtn.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
//slight change from Johns code
  if not( csDesigning in ComponentState) then
  Caption := DEFCAPTIONS[FButtonStyle];
  Width := 75;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TDobAgeBtn]);
end;

destructor TDobAgeBtn.Destroy;
begin
  inherited Destroy;
end;

procedure TDobAgeBtn.SetAge (const Value: TDateTime);
end;


procedure TDobAgeBtn.SetButtonStyle( bs: TDobAgeBtnStyle );
begin
  FButtonStyle := bs;
// slight change from Johns code
  if ( csDesigning in ComponentState )
  then Caption := DEFCAPTIONS[ FButtonStyle ];
end;

procedure TDobAgeBtn.SetDOBY (const Value: String);
end;

procedure TDobAgeBtn.SetDOBM (const Value: String);
end;

procedure TDobAgeBtn.SetDOBD (const Value: String);
end;

end.
ASKER CERTIFIED SOLUTION
Avatar of erajoj
erajoj
Flag of Sweden image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial