Introduction

Lots of time we want to disable a set of controls in our dialog. Group box is a good control to categorize a few controls together, but unfortunately it cannot enable/disable its controls. I extended CButton class and made it very simple to accomplish this and it is encapsulated into one class.

So you can change the title of a group box into a check box or radio button (then you need more group boxes of course).

I must confess I borrowed some idea of other talented programmers.

How to use it

Draw a group box in resource editor as usual. In resource editor, change the style property of group box to icon or bitmap, this prevents Overlapped text when tab is pressed!

You can also enable tab key navigation by enabling Tab Stop in group box resource like following

Add a member variable for this added group box, but choose CCheckableGroupBox as control type.

In OnInitDialog(), call m_yourVariable.SetTitleStyle(BS_AUTOCHECKBOX); to change normal title to a check box, or use BS_AUTORADIOBUTTON for radio box.

you want a group of group box toggle by radio box title, just create more Checkable group box as you already did, and call SetGroupID to give them a group!

In updated version of this control, I support DDX_Check, which means now you can use UpdateData() to update and save the state of check box in an standard MFC fashion.

Because the check/radio box is created when SetTitleStyle() is called, no variable update is applicable before that point. If you want to update the status from a member variable, please call UpdateData(FALSE) after that. I know it's not perfect but it's not that bad anyway.

Updated (02/12/03) - Send BN_CLICKED Message to parent dialog while title box is clicked. This is crucial if you use this control along with my Data Driven UI Behaviour Pattern.

Updated (03/12/03) - Support embedded group boxes (Groupbox inside another), no level or number limitations!

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.

Share

About the Author

I have over 13 Years IT industry experience as Principle/Senior Programmer. I am experienced in .NET/J2EE system design and detailed implementation. I master UML modelling and OO design methodology with a strong C#/C++/Java coding background. I have been in working/managing a distributed project using Agile/Waterfall approach. My business knowledge includes Telecommunication, Financial Investment/Trading, and Banking.

I changed in this way:
So the text is drawn by the groupbox, and the checkbox consists only of the box.
The Checkbox is always right of the text.
Has anybody a better solution?
Especially on propertypages the standard of CCheckableGroupBox doesn't look fine with themes enabled.

Your article help me to correct a bug in my application. Thank you ! I have a question for you. Why changing the style property of group box to icon or bitmap prevents overlapped text when tab is pressed. It was my bug...

The class is great as it is but sometimes it's more desirable rather than enable or disable a group of controls to instead hide or show them.

I came up with this idea because I needed a way of allowing a user to toggle a large control on top of all other controls in a dialog. I needed a way of avoiding the controls beneath from being drawn over top of the big control when the mouse moves over them. I tried throwing a checkable groupbox around them and disabling and it worked. The problem was that when the dialog is minimized and restored, all the controls are drawn (disabled) before the big control is drawn, causing flicker. Also, beneath the big control were some controls which were disabled depending on some factors and when the big control was hidden and the controls beneath it enabled, all the controls were enabled instead of just the ones that should be.

I made a few changes to CCheckableGroupBox to include a flag which decides whether enabling/disabling it causes it's subcontrols to be enabled/disabled or hidden/show. Plus, when the controls are hidden, they automatically become disabled.

I also commented out the sections dealing with mapChkableGroupWnds which handles subcontrols that are checkable boxes. I find that handling checkable box subcontrols causes a lot of trouble and ignoring them makes things much better.

Now you can use SetCheckType(CGB_VISIBLE) which will make calles to SetCheck(...) toggle visibility rather then enabled status. Alternately you can for example use SetCheck(BST_CHECKED, CGB_VISIBLE) to make all subcontrols visible and SetCheck(BST_UNCHECKED, CGB_VISIBLE) to make them invisible (and disabled).

This class is more useful than the even Ziming intended. If you have a dialog where you need to enable or disable a group of buttons based on user input this class can make it easy. For example, I've got a dialog app which can allow the user to do stuff in a few different modes. There are a few controls that are used in all modes, and each mode has a few exclusive controls. What I did was to put a group box around each set of controls and assigned a CCheckableGroupBox to them, some of the group boxes are visible, some are hidden. Now when the user clicks a radio button to select the mode, I set or clear the group box to quickly and easily enable or disable that group of controls using SetCheck.

This is great. There's just a couple of things that need to be done differently, first, I had to modify the the SetTitleStyle method:

Now, it disables the contained controls when the checkbox is disabled or indeterminate, and enables them when it is enabled. And, doing a GetCheck on the groupbox control returns the expected values (BST_CHECKED/BST_UNCHECKED/BST_INDETERMINATE).

Make sure that files on the machine have the correct date (i.e. not in the future) if they do find some kind of "touch" utility to correct their timestamp (by the way check all three create/mod/access)

Considering I literally run at least a hundred different applications everyday on my machine and they don't behave the way this particular sample does, was what caught my attention. Immediately (like the very next second) I ran the sample again, and again it prompted with the same message. At first I replied, "Yes," and it would rebuild the application, and subsequently run fine. Then, I would run it again (immediately), and again it would do the same prompt. This time I replied, "No," but it didn't matter because it ran fine anyway.

Still again, I ran it once more, and again it prompted me to rebuild. Again I replied, "No," and again it ran fine.

That's what happening, and it's ONLY happening to this sample even though I've made no change to the code.

What "create," "mod," and "access" are you talking about that I should check?

When you stated that the timestamp must be current (i.e. not in the future), I checked to see if any of the files I was using had a future timestamp, AND SOME DO (including the 'workspace' file which I downloaded and ran the way I got it, without making any change to it).

Currently, the time my computer is showing is about 6:30 a.m. Pacific time in the United States. Some of the files I downloaded are showing the same date, but nearly 9:00 a.m., which has NOT occurred yet for us in the Western United States.

I believe if I were to run the sample AFTER 9:00 a.m., I won't have the same situation to deal with.

The reason the compiler keeps asking you to recompile everything is because the date/time stamp on the various project files is newer than the current date/time on your computer. As a result, whenever the compiler builds the binaries it gives them each a date/time stamp that is older than the one on the corresponding source file.

The problem is easily fixed by running a touch utility on the source files. (Check Google for a download.) Ziming doesn't see the problem becuase his clock is set differently than yours.

After downloading the new ".dsp", ".dsw", ".h" and ".cpp" for the CheckableGroupBox files, I replaced the old files with the new ones, and rebuilt the entire application. However, what I got was the old version; not the new one with the radio buttons.

Short of wiping out everything and starting over from scratch, I believe the files I replaced ought to have worked. Any suggestion why they didn't?