Solved

Caption problem with derived TSpeedButton Component?

Posted on 1998-07-29
13
386 Views
Last Modified: 2010-04-04
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
0
Comment
Question by:doogie
13 Comments
 
LVL 8

Expert Comment

by:ZifNab
ID: 1359014
heh? Sorry.
0
 
LVL 2

Expert Comment

by:kjteng
ID: 1359015
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:= '????'
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1359016
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
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:erajoj
ID: 1359017
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

0
 
LVL 4

Expert Comment

by:erajoj
ID: 1359018
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
0
 

Expert Comment

by:DPedrelli
ID: 1359019
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.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1359020
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
0
 
LVL 3

Expert Comment

by:Matvey
ID: 1359021
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...


0
 

Author Comment

by:doogie
ID: 1359022
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.
0
 

Author Comment

by:doogie
ID: 1359023
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.
0
 
LVL 2

Expert Comment

by:freter
ID: 1359024
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
0
 

Author Comment

by:doogie
ID: 1359025
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.
0
 
LVL 4

Accepted Solution

by:
erajoj earned 150 total points
ID: 1359026
Hi,
It seems I'm not as numbskulled as I thought!? ;-)

/// John
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

726 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