Click here to Skip to main content
15,121,549 members
Articles / Programming Languages / C++
Posted 9 Apr 2008


52 bookmarked

EnableGroupboxControls - a non-MFC function to enable or disable all the controls within a groupbox

Rate me:
Please Sign up or sign in to vote.
3.65/5 (9 votes)
9 Apr 2008CPOL4 min read
EnableGroupboxControls is a function that enables or disables all the controls within a groupbox based solely upon the window rect of the controls. A simple approach to implementing a groupbox checkbox is also explained.


EnableGroupboxControls is a function I have used in several projects, where I wanted to enable/disable all the controls within a groupbox. There are several other solutions to this problem here on CodeProject - I have included a list here. None of these, however, had everything I was looking for:
screenshot Able to be used in MFC or non-MFC project - since I spend a lot of time maintaining older Windows applications, I wanted a very lightweight solution.
screenshot Able to be used without instantiating class - this was important, because I necessarily have to minimize the impact on existing code.
screenshot Able to be used without recoding or redefining existing control variables - again, for same reasons as previous point.
screenshot Able to accommodate nested groupboxes - many of the dialogs in apps I maintain are non-trivial, because the apps themselves are highly technical. Nesting groupboxes is one way of coping with complex user interfaces.

EnableGroupboxControls API

Here is the EnableGroupboxControls function:
// EnableGroupboxControls()
// Purpose:     This function enables/disables all the controls that are
//              completely contained with a groupbox.
// Parameters:  hWnd    - HWND of groupbox control
//              bEnable - TRUE = enable controls within groupbox
// Returns:     int     - number of controls enabled/disabled.  If zero is
//                        returned, it means that no controls lie within the
//                        rect of the groupbox.
int EnableGroupboxControls(HWND hWnd, BOOL bEnable)
    int rc = 0;

    if (::IsWindow(hWnd))
        // get class name
        TCHAR szClassName[MAX_PATH];
        szClassName[0] = _T('\0');
        ::GetClassName(hWnd, szClassName, sizeof(szClassName)/sizeof(TCHAR)-2);

        // get window style
        LONG lStyle = ::GetWindowLong(hWnd, GWL_STYLE);

        if ((_tcsicmp(szClassName, _T("Button")) == 0) &&
            ((lStyle & BS_GROUPBOX) == BS_GROUPBOX))
            // this is a groupbox

            RECT rectGroupbox;
            ::GetWindowRect(hWnd, &rectGroupbox);

            // get first child control

            HWND hWndChild = 0;
            HWND hWndParent = ::GetParent(hWnd);
            if (IsWindow(hWndParent))
                hWndChild = ::GetWindow(hWndParent, GW_CHILD);

            while (hWndChild)
                RECT rectChild;
                ::GetWindowRect(hWndChild, &rectChild);

                // check if child rect is entirely contained within groupbox
                if ((rectChild.left >= rectGroupbox.left) &&
                    (rectChild.right <= rectGroupbox.right) &&
                    ( >= &&
                    (rectChild.bottom <= rectGroupbox.bottom))
                    //TRACE(_T("found child window 0x%X\n"), hWndChild);
                    ::EnableWindow(hWndChild, bEnable);

                // get next child control
                hWndChild = ::GetWindow(hWndChild, GW_HWNDNEXT);

            // if any controls were affected, invalidate the parent rect
            if (rc && IsWindow(hWndParent))
                ::InvalidateRect(hWndParent, NULL, FALSE);
    return rc;

EnableGroupboxControls Demo

The EnableGroupboxControls demo app shows how controls inside a groupbox may be enabled/disabled:


When the checkbox for groupbox 1 is unchecked, all the controls inside groupbox 1 and groupbox 2 are disabled:


Here is the code that manages these nested groupboxes:
void CEnableGroupboxControlsTestDlg::OnCheck1() 
    EnableGroupboxControls(::GetDlgItem(m_hWnd, IDC_GROUPBOX_1), m_bCheck1);
    // enable controls within embedded groupbox

void CEnableGroupboxControlsTestDlg::OnCheck2() 
    EnableGroupboxControls(::GetDlgItem(m_hWnd, IDC_GROUPBOX_2), m_bCheck1 && m_bCheck2);
Note that there is no linkage between the checkboxes and the groupboxes except what you see in the above code. The two groupboxes are created in the dialog template with a field of spaces (instead of text). Then checkboxes are created and overlaid on the groupbox, so that the visual appearance is that of a groupbox "controlled" by a checkbox. Here is dialog template for demo app, with the two checkbox/combobox pairs highlighted:


Overlaying the groupbox header with a checkbox will work only if you know the trick: the groupbox must precede the checkbox in tab order. Tab order is simply the order in which controls appear in the dialog template. If the groupbox came after the checkbox, it would overlay the checkbox, and the checkbox would not be visible to the user. This works this way because the order of controls in the dialog template is also the order in which the controls are created and displayed at run time.
You can set the tab order inside Visual Studio, but with overlapping controls it is not completely straightforward. Here is what the dialog template looks like in VS2005, with tab order labels made visible by menu command Format | Tab Order:


The two groupbox headers that are outlined in red are the ones that have been overlaid by checkboxes. Since the tab order labels for 1 and 2, and 8 and 9, are displayed over each other, it is difficult to set the tab order in VS IDE. However, as usual, there is a trick: temporarily move the checkboxes above or below the groupbox, and then edit the tab order. When you are finished, move checkboxes back.

Of course, it is not necessary to have checkbox in groupbox header, in order to make use of EnableGroupboxControls. The button labelled Disable Groupbox 3 is an example of how to do this.

How to use

Step 1 - Add Files

To integrate EnableGroupboxControls into your app, you first need to add following files to your project:

  • EnableGroupboxControls.cpp
  • EnableGroupboxControls.h

The .cpp file should be set to Not using precompiled header in Visual Studio. Otherwise, you will get error

fatal error C1010: unexpected end of file while looking for precompiled header directive

Step 2 - Add Header File to Your Source Module

In the module where you want to use EnableGroupboxControls, include header file EnableGroupboxControls.h .

Step 3 - Add Code

When user clicks a checkbox (or makes some kind of selection). add code like I have shown above, to call EnableGroupboxControls function.


Here are some other articles that discuss managing controls within a groupbox:

Revision History

Version 1.0 - 2008 April 9

  • Initial public release


This software is released into the public domain. You are free to use it in any way you like, except that you may not sell this source code. If you modify it or extend it, please to consider posting new code here for everyone to share. This software is provided "as is" with no expressed or implied warranty. I accept no liability for any damage or loss of business that this software may cause.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Hans Dietrich
Software Developer (Senior) Hans Dietrich Software
United States United States
I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.

Recently, I have moved to Los Angeles where I am doing consulting and development work.

For consulting and custom software development, please see

Comments and Discussions

GeneralMy vote of 5 Pin
Vishnu Narang25-Jan-12 17:31
MemberVishnu Narang25-Jan-12 17:31 
GeneralBug: Wrong Pin
JimmyO10-Apr-08 11:01
MemberJimmyO10-Apr-08 11:01 
GeneralRe: Bug: Wrong Pin
Hans Dietrich10-Apr-08 13:24
mentorHans Dietrich10-Apr-08 13:24 
GeneralRe: Bug: Wrong Pin
JimmyO10-Apr-08 14:09
MemberJimmyO10-Apr-08 14:09 
GeneralRe: Bug: Wrong Pin
Hans Dietrich10-Apr-08 14:59
mentorHans Dietrich10-Apr-08 14:59 
GeneralRe: Bug: Wrong Pin
Damir Valiulin24-Apr-08 13:49
MemberDamir Valiulin24-Apr-08 13:49 
GeneralRe: Bug: Wrong Pin
JimmyO24-Apr-08 14:40
MemberJimmyO24-Apr-08 14:40 
GeneralRe: Bug: Wrong Pin
Damir Valiulin24-Apr-08 19:10
MemberDamir Valiulin24-Apr-08 19:10 
GeneralShould check and move keyboard focus before disabling a control Pin
Leo Davidson10-Apr-08 2:05
MemberLeo Davidson10-Apr-08 2:05 
Before disabling a control it's important to test if it has the keyboard focus and, if it does, move the focus to the next item.

If you disabling the item with the keyboard focus then the focus is lost completely, which is obviously bad.

Of course, it is fairly rare that you disable the item the user is currently focused on, but it does happen in some situations so it's good to do the right thing, especially with generic code.

Here's my little helper function, which only works in dialogs, since it uses WM_NEXTDLGCTL. (As an aside, using WM_NEXTDLGCTL rather than SetFocus is important with dialogs if you don't want to end up with two buttons that both think they are the DEFPUSHBUTTON.)

BOOL LeoHelpers::EnableDlgControl(HWND hwndControl, BOOL bEnable)
  BOOL bResult = FALSE;

  if (NULL != hwndControl)
    if (!bEnable && ::GetFocus() == hwndControl)
      // We're about to disable the control with focus. Give focus to the next control.
      // Set focus to next control. (Do not use SetFocus in dialogs. Use WM_NEXTDLGCTL instead.)
      ::SendMessage(::GetParent(hwndControl), WM_NEXTDLGCTL, 0, FALSE);

    bResult = ::EnableWindow(hwndControl, bEnable);

  return bResult;

GeneralRe: Should check and move keyboard focus before disabling a control Pin
Hans Dietrich10-Apr-08 3:55
mentorHans Dietrich10-Apr-08 3:55 

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.