Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Custom Draw Buttons & A Smarter Groupbox

0.00/5 (No votes)
11 Jan 2000 1  
A class to make working with radio buttons easier, and another for custom drawing buttons
  • Download demo project - 66 Kb
  • Sample Image - CustomButtons.gif

    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 effects
    • CCustomTextButton - Button that displays colored text
    • CAnimatingButton - Button that displays animated colored text
    • CRoundButton - 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:

    1. Subclass your button with a class derived from CCustomButton.
    2. 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'
      
      }
      
    3. 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()
      
      }
      
    4. 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.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here