Custom Draw Buttons & A Smarter Groupbox






4.64/5 (10 votes)
Jan 12, 2000

208378

5635
A class to make working with radio buttons easier, and another for custom drawing buttons
Part 1. CRadioGroup: A group box class that handles radio buttons as an array
Sometimes when you have a number of radio buttons in a group you don't want to deal with
them individually. CRadioGroup
is a simple class that allows you to access any radios
bounded by a groupbox as a 1 based array.
Class hierarchy:
CObject | +-CCmdTarget | +-CWnd | +-CButton | +-CRadioGroup
How do you use the CRadioGroup?
To use the CRadioGroup
class simply subclass a Groupbox in a dialog and use the SetRadio()
and GetRadio()
methods to access the currently selected radio button. I have made
the accessing 1 based ( 0 based arrays have always upset me), but this can be easily
changed.
When used in conjunction with CCustomButton
the CRadioGroup
will also receive a BN_CLICKED
message whenever a contained radio is clicked. Thus only one handler is required for any
number of radio buttons inside a group box.
Subclassing the groupbox:
void CMyDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CCRadioGroupSampleDlg) DDX_Control(pDX, IDC_GROUP1, m_Group1); //}}AFX_DATA_MAP }
Handling hits on the radio buttons via the groupbox (NB. The radio buttons must be
CCustomButton
's or derived from a CCustomButton
) :
ON_BN_CLICKED(IDC_GROUP1, OnGroup1)
The code for CRadioGroup is in CRadioGroup.cpp/.h (See
source.)
How does the CRadioGroup work?
The class simply step through the auto-radio buttons that are bounded by it and finds the currently selected one. If this is the second auto-radio button then GetRadio() will return 1. Conversely SetRadio(1) will select this one, deselecting the currently selected one. Simple.
Part 2. CCustomButton: Generic user draw buttons
When I started writing MFC dialog code I thought it would be easy to override the drawing of buttons. Foolish me!
All I wanted was to draw the buttons based on the type and current state while retaining the button behaviour. After some trial and error I created a class that allowed standard button behaviour but with the option of the user handling all drawing. I have also added some extra features including
- A user defined hit region
- Support for hovering behavior
- Simple animation
Class hierarchy:
CObject | +-CCmdTarget | +-CWnd | +-CButton | +-CCustomButton
Sample Code:
I have included a range of sample implementations of custom buttons. These are all
derived from CCustomButton
and are displayed in the smaple code provided.
CCustomIconButton -
Button that displays a centered icon taken from a toolbar style strip bitmap and also supports simple hovering effectsCCustomTextButton -
Button that displays colored textCAnimatingButton -
Button that displays animated colored textCRoundButton -
A round button that supports hovering effects. The code for drawing the round buttons was written by Chris Maunder (Copyright (c) 1998.).
How to use CCustomButton:
- Subclass your button with a class derived from
CCustomButton
. - To draw your own button, simply override the following 2 methods :
virtual bool CustomDraw() const {return true;} virtual void OnDraw(CDC*,const CCustomButtonData& state) { //Draw the button based on state flags in parameter 'state' }
- To provide hovering effects override the following 2 methods :
virtual bool HoverEffects()const{return true;} virtual void OnHover(bool bEnteringButton) { // Override OnHover() to provide non-drawing effect such as sounds. // Any drawing effects while hovering can be added in OnDraw() }
- To provide simple animation call
SetAnimation()
.void SetAnimation(bool bActive,int nNoOfFrames=0, int nMillisecsPerFrame=10); //If set active OnDraw() will be called every 'nMillisecsPerFrame' with //the frame variable 'CCustomButtonState::m_nFrame' incremented each time.
For more information, please refer to the comments in the source code.