Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC
Article

GroupControl

Rate me:
Please Sign up or sign in to vote.
4.69/5 (29 votes)
21 Feb 2005CPOL5 min read 239.4K   7.8K   107   20
CButton-derived control to help with using groups.

Sample Image - GroupControl_demo.jpg

Introduction

CGroupControl is a CButton-derived class which assists with the use of group boxes (i.e., buttons with the BS_GROUPBOX style). The CGroupControl makes it easy to enable/disable, show/hide, or move a group. No code is required in the group's parent, as this is done automatically whenever the group control itself is enabled/disabled, shown/hidden, or moved. The control also includes a mechanism to allow you to perform any action on each control in a group.

How to use it

Using the CGroupControl class is very straightforward. Follow the steps below to add one to an existing project.

  1. After putting the source files (GroupControl.cpp and GroupControl.h) into the directory you wish to use them from, add the files to your Visual Studio project.
  2. In the resource editor, add a group-box where you wish, and give it an ID other than its default IDC_STATIC.
  3. In Class Wizard, add a member variable for your group-box control, selecting "Control" from the "Category" list, and selecting "CGroupControl" from the "Variable Type" list. (If CGroupControl does not appear in the list, you may need to delete your class wizard file (.clw) and regenerate it.)
  4. That's all you have to do to take advantage of the enabling, showing, and moving functionality.

Documentation

The control has one function which iterates round its siblings to see if they lie within the boundary of the group box control. These are the items then acted upon by use of a callback function. The functionality included is for the handlers for WM_ENABLE, WM_SHOWWINDOW, and WM_WINDOWPOSCHANGING, but this can easily be extended to perform any action. The method of determining whether a control belongs to a group is described below, followed by a description of the callback mechanism.

Iteration

To determine whether a control belongs to a group, the group control iterates around its siblings, getting their positions, and simply testing to see if they lie within the boundary of the group box. There are a couple of options concerning this:

  • Whether to include controls that are only partially within the group, i.e., overlapping.
  • Whether to look at all controls, or only those whose tab order places them after the group box.

By default, the control will not include overlapped controls, and will look at all siblings. In order to change this behaviour, the following two functions may be used:

void SetAllowOverlap(BOOL bAllowOverlap = TRUE);
void SetUseTabOrder(BOOL bUseTabOrder = TRUE);

If the UseTabOrder option is set, then the group will start by looking at its first sibling and stops iteration when it finds the first control not within its boundary. This will be slightly faster, but relies on having set the tab order correctly.

Control Actions

The callback function signature is:

BOOL GroupControlActionFunc(CWnd*, LPARAM);

This is typedef'd to GROUPCONTROLACTIONFUNC.

The function used to iterate around the controls is:

BOOL DoGroupControlAction(GROUPCONTROLACTIONFUNC pfnGCAF, LPARAM lParam = 0)

Calling this function, passing in the address of the callback function, will iterate around the group's controls and call the callback function for each of the controls, passing in a CWnd pointer to the control, and the lParam passed to DoGroupControlAction. The lParam is used to pass any relevant information to the callback functions.

As an example, the following code is the callback function used to implement the enabling/disabling of the group's controls:

static BOOL GroupControlActionFunc_Enable(CWnd* pCtrl, LPARAM lParam)
{
    if (pCtrl == NULL)
        return TRUE;
    BOOL bEnable = (BOOL)lParam;
    pCtrl->EnableWindow(bEnable);
    return TRUE;
}

This is invoked by the following call to DoGroupControlAction:

DoGroupControlAction(GroupControlActionFunc_Enable, bEnable);

Here, the lParam is simply used to specify whether to enable or disable the controls.

It is possible to set the group control to ignore its controls and not carry out any action on them, by calling the IgnoreControls() function, passing in TRUE. This causes the group control to act as a normal group control. This is especially useful if other child controls move all their siblings, as with Peter Mares' CKCSideBannerWnd banner control.

Functions

The public functions in the class are as follows:

  • CGroupControl();

    Standard empty constructor

  • BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, UINT nID);

    Creates the control. This is identical to CButton::Create() with the addition of checking that the style is correct for a group box.

  • BOOL IsInGroup(CWnd* pCtrl, BOOL& bOverlapped);

    Can be used to determine if any control belongs to a group. The function returns TRUE if any part of the control is within the boundary of the group. If only part of the control is within the group, then bOverlapped is set to TRUE.

  • BOOL DoGroupControlAction(GROUPCONTROLACTIONFUNC pfnGCAF, LPARAM lParam = 0);

    This function can be used to iterate around the group's controls, and perform an action on each item. pfnGCAF is a callback function called for each item, passing it a CWnd pointer representing the control. lParam is an application defined value passed into the callback function. Note that calling this function has no effect on the controls if the group control is set to ignore its controls.

  • void SetUseTabOrder(BOOL bUseTabOrder = TRUE);

    If bUseTabOrder is TRUE, this causes the group to iterate around controls, starting from the first sibling after the group, and ending with the last control which is within the group's boundary. If bUseTabOrder is FALSE, the group will look at all sibling controls.

  • void SetAllowOverlap(BOOL bAllowOverlap = TRUE);

    If bAllowOverlap is TRUE, then the group will consider a control as belonging to the group if any part of the control is within the group's boundary. If bAllowOverlap is FALSE, the whole control must lie inside the group's boundary to belong to the group. This only applies when iterating around the controls.

  • BOOL GetUseTabOrder();

    Returns whether iteration uses the control tab order.

  • BOOL GetAllowOverlap();

    Returns whether overlapping controls are considered to belong to the group.

  • void IgnoreControls(BOOL bIgnore = TRUE);

    Causes the group to act as a normal group box, and not do actions on controls within the group. Note that this has no effect on the behaviour of the IsInGroup() function.

  • BOOL ControlsIgnored() const;

    Returns whether the group is set to ignore its controls.

History

  • Version 1.1 - 17 Feb 2005
    • Added method "IgnoreControls" to allow the group box to be moved/sized etc. without the controls within the group doing the same, i.e., causes the group control to act as a normal group control. This is useful if other child controls move all their siblings as with Peter Mares' CKCSideBannerWnd banner control.
  • Version 1 - 24 Jul 2002 - First version.

License

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


Written By
Software Developer (Senior)
United Kingdom United Kingdom
Originally from an electronics background, I moved into software in 1996, partly as a result of being made redundant, and partly because I was very much enjoying the small amount of coding (in-at-the-deep-end-C) that I had been doing!

I swiftly moved from C to C++, and learned MFC, and then went on to real-time C on Unix. After this I moved to the company for which I currently work, which specialises in Configuration Management software, and currently program mainly in C/C++, for Windows. I have been gradually moving their legacy C code over to use C++ (with STL, MFC, ATL, and WTL). I have pulled in other technologies (Java, C#, VB, COM, SOAP) where appropriate, especially when integrating with third-party products.

In addition to that, I have overseen the technical side of the company website (ASP, VBScript, JavaScript, HTML, CSS), and have also worked closely with colleagues working on other products (Web-based, C#, ASP.NET, SQL, etc).

For developing, I mainly use Visual Studio 2010, along with an in-house-designed editor based on Andrei Stcherbatchenko's syntax parsing classes, and various (mostly freeware) tools. For website design, I use Dreaweaver CS3.

When not developing software, I enjoy listening to and playing music, playing electric and acoustic guitars and mandolin.

Comments and Discussions

 
GeneralMy vote of 3 Pin
futurejo25-Apr-13 22:46
futurejo25-Apr-13 22:46 
GeneralRe: My vote of 3 Pin
Jason.LYJ18-Sep-15 17:46
professionalJason.LYJ18-Sep-15 17:46 
GeneralMy vote of 5 Pin
chenhong123b17-Jul-11 17:54
chenhong123b17-Jul-11 17:54 
GeneralOwner draw Radio button Pin
Shailesh Namjoshi30-Apr-07 3:40
Shailesh Namjoshi30-Apr-07 3:40 
QuestionHow could a drag and drop be added Pin
anarkia19855-Dec-06 15:05
anarkia19855-Dec-06 15:05 
GeneralJust forgot to mention... Pin
Kochise14-Apr-06 2:20
Kochise14-Apr-06 2:20 
GeneralRe: Just forgot to mention... Pin
Paul Vickery17-Apr-06 22:48
professionalPaul Vickery17-Apr-06 22:48 
GeneralEvent generation for overlapping buttons Pin
DJas3-Apr-06 22:49
DJas3-Apr-06 22:49 
GeneralProblem using in colored dialogs Pin
tma2k27-Jun-05 1:27
tma2k27-Jun-05 1:27 
QuestionWhat am I missing? Pin
skornel19-Mar-05 11:45
skornel19-Mar-05 11:45 
AnswerRe: What am I missing? Pin
skornel19-Mar-05 12:06
skornel19-Mar-05 12:06 
GeneralGreat control, but... Pin
Kochise15-Feb-05 10:38
Kochise15-Feb-05 10:38 
GeneralRe: Great control, but... Pin
Paul Vickery16-Feb-05 23:41
professionalPaul Vickery16-Feb-05 23:41 
Questionhow to use functional keys only for controling player(sound) Pin
iipc9-Jul-04 18:59
iipc9-Jul-04 18:59 
AnswerRe: how to use functional keys only for controling player(sound) Pin
iipc15-Jul-04 20:01
iipc15-Jul-04 20:01 
QuestionCan you add method to control the color of boxline? Pin
zcy18-Mar-03 20:06
zcy18-Mar-03 20:06 
QuestionUse this on Windows CE? Pin
Nilla6-Jan-03 23:04
Nilla6-Jan-03 23:04 
GeneralWill be nice, if... Pin
Paul Selormey23-Jul-02 23:36
Paul Selormey23-Jul-02 23:36 
GeneralRe: Will be nice, if... Pin
Gavin Greig24-Jul-02 2:34
Gavin Greig24-Jul-02 2:34 
GeneralRe: Will be nice, if... Pin
johnston28-Aug-02 9:51
johnston28-Aug-02 9:51 

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.