Custom Draw Buttons '& A smarter Groupbox


What's in this Code?

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:

How to 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 steps 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 2. Conversely SetRadio(2) will select this one, deselecting the currently selected one. Simple.
 

2. CCustomButton: A generic user draw button

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 included a sample implementation of a CCustomButton in CCustomIconButton which takes an 'icon' from a toolbar style strip bitmap and draws it in a button frame. ( See the picture above).

Class hierarchy:

How do you use the CCustomButton &  CCustomIconButton ?

1. To use CCustomButton simply override the following 2 methods :

virtual BOOL IsCustom()const {return TRUE;} // Return TRUE so that Draw() is called
virtual void Draw(CDC*,CRect,const CCustomButtonData& state)
{
   //Draw the button based on state flags in state
}
2. CCustomIconButton is a simple sample of what can be done using the CCustomButton. To use it

(a). Subclass your button with a CCustomIconButton.
(b). In OnInitDialog() call:  myButton.LoadIcon(), Passing the ID of a strip bitmap, the offset of the button         image (again 1 based) and the size of the button image.

eg. myButton.LoadIcon(IDB_MYBITMAP,nOffset,CSize(24,23));

How do the CCustomButton and CCustomIconButton classes work?

The CCustomButton overrides all of the methods and message handlers that are needed to prevent the underlying button drawing itself. If the IsCustom() method returns FALSE then the button will look and behave as normal. But if IsCustom() returns TRUE then the Draw() method is called for drawing the button. The current button state is passed to the Draw() method via the CCustomButtonData class.
The code for CCustomButton is in CCustomButton.cpp/.h
The code for CCustomIconButton is in CCustomIconButton.cpp/.h
For more information, please refer to the comments in the source code.


Download source and sample - 24 KB



Comments

  • Thanks for the info -- you rock!

    Posted by Legacy on 01/15/2004 12:00am

    Originally posted by: Aaron

    This sample helped me figure out what I needed... Many thanks!!

    Reply
  • Create on-the-fly

    Posted by Legacy on 01/03/2002 12:00am

    Originally posted by: Zoiberg

    How I can create a groupbox like that but on-the-fly. I means the text & button properties come from a compound file.

    Reply
  • Accessing a single function for a range of Radio Buttons

    Posted by Legacy on 12/11/2001 12:00am

    Originally posted by: Chithra Dinesh

    Accessing a single function for a range of Radio Buttons (or a Range of control) can be accomplished by using the Message Handler ON_COMMAND_RANGE

    Reply
  • Help me!

    Posted by Legacy on 06/22/2001 12:00am

    Originally posted by: Nguyen Chi Quynh

    I want play a file *.dat (movie) by program Visual C++
    Is this OK, If you help me open the door do that.
    Thank you verry much.

    Reply
  • SetRadio and GetRadio fail if RadioGroup is not last in tab order

    Posted by Legacy on 06/09/1999 12:00am

    Originally posted by: Eric Margheim

    I've used your CCustomButton classes several times. Thanks for the work.

    I ran into some problems with CRadioGroup in that the index was always off by one, e.g. GetRadio would always return 1 greater than what it should have. After debugging, I noticed that in DoRadioGroup, the CRadioGroup wnd was being examined first and was passing the conditionals, i.e. IntersectRect was TRUE and it was returning TRUE to IsAutoRadio. It was, therefore, impersonating the first radio button.

    After looking at your sample, I noticed that the group box was always last in the tab order, so I created my group box last (I'm creating everything dynamically not subclassing) and it worked fine.

    I'm guessing the problem is actually with IsAutoRadio, because that should be returning FALSE for a CRadioGroup wnd.

    • Fix to IsAutoRadio()

      Posted by bdempsey on 01/11/2005 11:12am

      if you change the line in CRadioHelpers::IsAutoRadio(CWnd* pRadio) from
      bAutoRadio=(::GetWindowLong(pRadio->GetSafeHwnd(),GWL_STYLE) & BS_AUTORADIOBUTTON)!=0;
      to
      bAutoRadio = ((::GetWindowLong(pRadio->GetSafeHwnd(), GWL_STYLE) & 0xf) == BS_AUTORADIOBUTTON);
      it will work with any tab order.

      Reply
    Reply
  • AfxExtractSubstring

    Posted by Legacy on 05/13/1999 12:00am

    Originally posted by: mihai

    Looks in MFC sources for header of AfxExtractSubstring.
    
    Sincerely, Mihai

    Reply
  • Thx for the code, just one small remark: C++ programmers expect 0 based indexes - nt

    Posted by Legacy on 03/26/1999 12:00am

    Originally posted by: Martin

    Thx for the code, just one small remark: C++ programmers expect 0 based indexes - nt

    Reply
  • CCustom Button

    Posted by Legacy on 12/21/1998 12:00am

    Originally posted by: Roli Arora

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Wednesday, September 24, 2014 8:00 AM - 9:00 AM PDT According to a recent Forrester Research report, many companies are choosing low-code platforms over traditional programming platforms, due to the speed with which low-code apps can be assembled and tested. With customer-facing applications on the rise, traditional programming platforms simply can't keep up with the "short schedules and rapid change cycles" required to develop these applications. Check out this upcoming webinar and join Clay Richardson from …

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds