Board index » cppbuilder » Radiobuttons to Pushbuttons

Radiobuttons to Pushbuttons


2003-11-29 05:37:13 AM
cppbuilder32
I know that I can change the appearance of a TRadioButton to look like a
push button with the following code:
GetWindowLong(RadioButton->Handle, GWL_STYLE);
dwStyle = dwStyle | BS_PUSHLIKE;
SetWindowLong(RadioButton->Handle, GWL_STYLE, dwStyle);
My problem is that I'm trying to write a component that is a group box that
contains several radiobuttons.
I'm trying to change the style of the radiobuttons in the constructor, but I
receive an invalidoperation.
How can I change the radiobuttons to look like pushbuttons?
-- Here's the relevant pieces of the header file --
class PACKAGE TDowSelector : public TCustomGroupBox
{
private:
TRadioButton *Radio1;
public:
virtual __fastcall TDowSelector(TComponent* Owner);
};
-- Here's the relevant pieces of the cpp file --
#include "DowSelector.h"
static inline void ValidCtrCheck(TDowSelector *)
{
new TDowSelector(NULL);
}
__fastcall TDowSelector::TDowSelector(TComponent* Owner) :
TCustomGroupBox(Owner)
{
DWORD dwstyle;
Radio1 = new TRadioButton(this);
Radio1->Parent = this;
Radio1->Caption = "Mon";
Radio1->Name = "RadioMon"
GetWindowLong(RadioMon->Handle, GWL_STYLE); // InvalidOperation is
generated here.
dwStyle = dwStyle | BS_PUSHLIKE;
SetWindowLong(RadioMon->Handle, GWL_STYLE, dwStyle);
}
namespace Dowselector
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TDowSelector)};
RegisterComponentsP("Samples", classes, 0);
}
}
 
 

Re:Radiobuttons to Pushbuttons

Evidentally my original post didn't "post" so here it is again...
I know that I can change the appearance of a TRadioButton to look like a push button with the following code:
GetWindowLong(RadioButton->Handle, GWL_STYLE);
dwStyle = dwStyle | BS_PUSHLIKE;
SetWindowLong(RadioButton->Handle, GWL_STYLE, dwStyle);
My problem is that I'm trying to write a component that is a group box that contains several radiobuttons. I don't think I can use a RadioGroup because I need to assign DoubleClick events to the buttons.
I'm trying to change the style of the radiobuttons in the constructor, but I receive an invalidoperation.
How can I change the radiobuttons to look like pushbuttons?
-- Here's the relevant pieces of the header file --
class PACKAGE TDowSelector : public TCustomGroupBox
{
private:
TRadioButton *Radio1;
public:
virtual __fastcall TDowSelector(TComponent* Owner);
};
-- Here's the relevant pieces of the cpp file --
#include "DowSelector.h"
static inline void ValidCtrCheck(TDowSelector *)
{
new TDowSelector(NULL);
}
__fastcall TDowSelector::TDowSelector(TComponent* Owner) :
TCustomGroupBox(Owner)
{
DWORD dwstyle;
Radio1 = new TRadioButton(this);
Radio1->Parent = this;
Radio1->Caption = "Mon";
Radio1->Name = "RadioMon"
GetWindowLong(RadioMon->Handle, GWL_STYLE); // InvalidOperation is generated here.
dwStyle = dwStyle | BS_PUSHLIKE;
SetWindowLong(RadioMon->Handle, GWL_STYLE, dwStyle);
}
namespace Dowselector
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TDowSelector)};
RegisterComponentsP("Samples", classes, 0);
}
}
Thanks,
Darius
 

Re:Radiobuttons to Pushbuttons

"Darius" < XXXX@XXXXX.COM >wrote in message
Quote
I don't think I can use a RadioGroup because I need to assign
DoubleClick events to the buttons.
Sure you can. The radio buttons in a TRadioGroup are normal TRadioButton
instances. You can access the individual buttons via the inherited Controls
property. Or better, you could simply override the inherited Notification()
method, which will be called during a button's creation, ie:
class PACKAGE TDowSelector : public TRadioGroup
{
typedef TRadioGroup inherited;
private:
void __fastcall RadioButtonDblClick(TObject *Sender);
//...
protected:
void __fastcall Notification(TComponent *AComponent, TOperation
Operation);
//...
};
void __fastcall TDowSelector::Notification(TComponent *AComponent,
TOperation Operation)
{
if( Operation == opInsert )
{
TRadioButton *radio = dynamic_cast<TRadioButton*>(AComponent);
if( (radio) && (radio->Owner == this) )
radio->OnDblClick = RadioButtonDblClick;
}
inherited::Notification(AComponent, Operation);
}
void __fastcall TDowSelector::RadioButtonDblClick(TObject *Sender)
{
// do something
}
Alternatively, you can have the GroupBox intercept the CM_CONTROLCHANGE
message instead, which will be sent when the RadioButton's Parent property
is set to the GroupBox. For example:
// 1) using WndProc to intercept the message
class PACKAGE TDowSelector : public TRadioGroup
{
typedef TRadioGroup inherited;
private:
void __fastcall RadioButtonDblClick(TObject *Sender);
//...
protected:
void __fastcall WndProc(TMessage &Message);
//...
};
void __fastcall TDowSelector::WndProc(TMessage &Message)
{
if( Message.Msg == CM_CONTROLCHANGE )
{
TCMControlListChange *Msg = (TCMControlListChange*)&Message;
if( Msg->Inserting )
{
TRadioButton *radio =
dynamic_cast<TRadioButton*>(Msg->Control);
if( radio )
radio->OnDblClick = RadioButtonDblClick;
}
}
inherited::WndProc(Message);
}
void __fastcall TDowSelector::RadioButtonDblClick(TObject *Sender)
{
// do something
}
// 2) using a MESSAGE_MAP to intercept the message
class PACKAGE TDowSelector : public TRadioGroup
{
typedef TRadioGroup inherited;
private:
void __fastcall RadioButtonDblClick(TObject *Sender);
void __fastcall CMControlListChange(TCMControlListChange &Message);
//...
public:
//...
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(CM_CONTROLCHANGE, TCMControlListChange,
CMControlListChange)
END_MESSAGE_MAP(TRadioGroup)
};
void __fastcall TDowSelector::CMControlListChange(TCMControlListChange
&Message)
{
if( Message.Inserting )
{
TRadioButton *radio =
dynamic_cast<TRadioButton*>(Message.Control);
if( radio )
radio->OnDblClick = RadioButtonDblClick;
}
inherited::Dispatch(&Message);
}
void __fastcall TDowSelector::RadioButtonDblClick(TObject *Sender)
{
// do something
}
Quote
I'm trying to change the style of the radiobuttons in the constructor,
but I receive an invalidoperation.
The constructor is not the correct place to do that. The GroupBox's Parent
has not been assigned yet, thus the error because the Parent is required for
such an operation. You need to delay the code until after the GroupBox's
Parent has been assigned. You would need to override either the Loaded() or
SetParent() method of the GroupBox in order to wait for the Parent property
to become valid, or you can alternatively intercept the CM_CONTROLCHANGE
message as shown above and alter the RadioButton itself at that time.
Gambit
 

{smallsort}

Re:Radiobuttons to Pushbuttons

Thanks for all the great info!
As far as changing the style of the radiobuttons in the constructor, I followed your suggestion and change the style in Loaded() and it works, but...
So I compile and install my component and then I create a new application and drop my component on the form. The radiobutton still looks like a pushbutton at design time. Then I run the application and it looks like a pushbutton.(good) Now if I save, close, reopen the application the radiobutton now looks like a pushbutton. (This is what I want to happen at design time).
So my question is, how can I have the radiobutton look like a pushbutton when the component is first dropped onto the form?
-- Here's the relevant pieces of the header file --
class PACKAGE TDowSelector : public TCustomGroupBox
{
private:
TRadioButton *Radio1;
public:
virtual void __fastcall Loaded(void); // Added
virtual __fastcall TDowSelector(TComponent* Owner);
};
-- Here's the relevant pieces of the cpp file --
#include "DowSelector.h"
static inline void ValidCtrCheck(TDowSelector *)
{
new TDowSelector(NULL);
}
__fastcall TDowSelector::TDowSelector(TComponent* Owner) :
TCustomGroupBox(Owner)
{
Radio1 = new TRadioButton(this);
Radio1->Parent = this;
Radio1->Left = 10;
Radio1->Top = 15;
Radio1->Caption = "Mon";
Radio1->Name = "RadioMon"
}
//---------------------------------------------------------------------------
void __fastcall TDowSelector::Loaded(void)
{
DWORD dwstyle;
// Make the radiobuttons look like pushbutton by setting the style to BS_PUSHLIKE.
dwStyle = GetWindowLong(Radio1->Handle, GWL_STYLE);
dwStyle |= BS_PUSHLIKE;
SetWindowLong(Radio1->Handle, GWL_STYLE, dwStyle);
}
//---------------------------------------------------------------------------
namespace Dowselector
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TDowSelector)};
RegisterComponentsP("Samples", classes, 0);
}
}
 

Re:Radiobuttons to Pushbuttons

Thanks for the suggestions.
At least I know I wasn't doing anything wrong since my radiobutton wasn't changing to a pushbutton when I drop it on the form.
With your great suggestions I'm sure I can get it figured out.
Thanks for the quick responses.
Darius
 

Re:Radiobuttons to Pushbuttons

"Darius" < XXXX@XXXXX.COM >wrote in message
Quote
The radiobutton still looks like a pushbutton at design time. Then I run
the application and it looks like a pushbutton.(good) Now if I save,
close, reopen the application the radiobutton now looks like a
pushbutton. (This is what I want to happen at design time).
Loaded() is only called when the component is streamed in from the DFM file.
It is not called the first time the component is first dropped onto the
form, because it has not been stored into the DFM yet.
Quote
So my question is, how can I have the radiobutton look like a pushbutton
when the component is first dropped onto the form?
If you are going to continue using TCustomGroupBox and instantiating your
own TRadioButton instances manually, then I would suggest you derive a new
class from TRadioButton and override its inherited CreateParams() method to
assign your custom styling from there instead. For example:
class TDowRadioButton : public TRadioButton
{
protected:
void __fastcall CreateParams(TCreateParams &Params);
public:
__fastcall TDowRadioButton(TComponent *Owner);
};
__fastcall TDowRadioButton::TDowRadioButton(TComponent *Owner)
: TRadioButton(Owner)
{
}
void __fastcall TDowRadioButton::CreateParams(TCreateParams &Params)
{
TRadioButton::CreateParams(Params);
Params.Style |= BS_PUSHLIKE;
}
Then you can change your GroupBox to the following:
class TDowSelector : public TCustomGroupBox
{
private:
TDowRadioButton *Radio1;
void __fastcall RadioButtonDblClick(TObject *Sender);
public:
__fastcall TDowSelector(TComponent* Owner);
};
__fastcall TDowSelector::TDowSelector(TComponent* Owner)
: TCustomGroupBox(Owner)
{
Radio1 = new TDowRadioButton(this);
Radio1->Parent = this;
Radio1->OnDblClick = RadioButtonDblClick;
//...
}
void __fastcall TDowSelector::RadioButtonDblClick(TObject *Sender)
{
//...
}
The alternative is to go back to a TRadioGroup and assign your custom
styling when new TRadioButton instances are added to the TRadioGroup, which
my previous reply showed you how to detect that.
Gambit