Solved

Caption problem with derived TSpeedButton Component?

Posted on 1998-07-29
13
378 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
Comment Utility
heh? Sorry.
0
 
LVL 2

Expert Comment

by:kjteng
Comment Utility
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
Comment Utility
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
 
LVL 4

Expert Comment

by:erajoj
Comment Utility
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
Comment Utility
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
Comment Utility
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 10

Expert Comment

by:viktornet
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Hi,
It seems I'm not as numbskulled as I thought!? ;-)

/// John
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

728 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now