Click here to Skip to main content
15,881,757 members
Articles / Desktop Programming / MFC
Article

Custom Draw Buttons & A Smarter Groupbox

Rate me:
Please Sign up or sign in to vote.
4.64/5 (11 votes)
11 Jan 2000 206.8K   5.6K   78   15
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
    • <a href=Roundbuttons.asp>CRoundButton</a> - 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


    Written By
    United States United States
    This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

    Comments and Discussions

     
    QuestionLicense Info Pin
    Member 1277777224-Jan-17 7:29
    Member 1277777224-Jan-17 7:29 
    GeneralProblem when press TAB Pin
    Adrian Savage21-Dec-06 0:23
    Adrian Savage21-Dec-06 0:23 
    QuestionCompilation problem with .NET 2003 Pin
    ROCKISDEAD19-Oct-05 23:49
    ROCKISDEAD19-Oct-05 23:49 
    AnswerRe: Compilation problem with .NET 2003 Pin
    gfine20-Oct-05 7:06
    gfine20-Oct-05 7:06 
    GeneralProblem using in colored dialogs Pin
    tma2k27-Jun-05 1:25
    tma2k27-Jun-05 1:25 
    GeneralOnClick Pin
    dimavs30-Sep-04 20:25
    dimavs30-Sep-04 20:25 
    GeneralPlease help! Pin
    speedpacer26-Jun-03 9:54
    speedpacer26-Jun-03 9:54 
    GeneralDisregard... Pin
    speedpacer26-Jun-03 13:41
    speedpacer26-Jun-03 13:41 
    GeneralRadio button query Pin
    Arun_gorur7-Apr-03 17:10
    Arun_gorur7-Apr-03 17:10 
    GeneralRe: Radio button query Pin
    SylL25-Jun-04 3:09
    SylL25-Jun-04 3:09 
    Generaldefault radio button to be TRUE Pin
    rohit.dhamija29-Jan-03 20:04
    rohit.dhamija29-Jan-03 20:04 
    GeneralRe: default radio button to be TRUE Pin
    ligh56t12-Aug-03 4:27
    ligh56t12-Aug-03 4:27 
    GeneralCCustomTextButton in Dialog Bar Pin
    Ken Sutherland28-Aug-01 15:45
    Ken Sutherland28-Aug-01 15:45 
    GeneralRe: CCustomTextButton in Dialog Bar Pin
    Ken Sutherland28-Aug-01 20:36
    Ken Sutherland28-Aug-01 20:36 
    After some investigating, I see that a "normal" CCustomTextButton will work fube in a Dialog Bar. The problem seems to be that I am using menu ID's for my radio button ID's, instead of control ID's.

    I am making a color selection interface. One way the user can select a color is with a menu item, which I generate progmatically. Now I want the user to be able to select the color with radio buttons on the dialog bar. By assigning the same ID to the menu item and the radio button, an update on one will automatically update the other.

    It works with normal radio buttons, but isn't working with CCustomTextButton. It seems that the the button is loosing the capture imediately after capturing it.

    I'll keep plugging at it!


    Ken in Sapporo
    GeneralRe: CCustomTextButton in Dialog Bar Pin
    Ken Sutherland29-Aug-01 14:19
    Ken Sutherland29-Aug-01 14:19 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.