XGroupBox - an MFC groupbox control to display text and icon






4.98/5 (56 votes)
XGroupBox is an MFC control that displays a flicker-free groupbox with text and/or icon. You can use this to display either a standard groupbox or a header-only groupbox.
Introduction
Groupboxes are one of my favorite UI elements. They collect together related controls, and guide the user through non-trivial user interfaces. It seems natural to display an icon in the groupbox header, since studies have shown that graphic images are more quickly recognized by users.This control implements two styles of groupboxes: a standard groupbox that allows you to display text and/or an icon; and a header-only groupbox, which offers same features, but only displays a single line, rather than a frame. The header-only style offers advantages when used in a very compressed UI, since it requires less screen real estate.
Features
Here are features which XGroupBox implements:![]() |
Replacement for Win32 groupbox, without the flicker when resized |
![]() |
Display icon and/or text |
![]() |
Display standard groupbox or header-only groupbox |
![]() |
Easy to set colors, font, and horizontal alignment |
![]() |
Support theming or custom colors (for header-only style, theming is not supported) |
![]() |
Allow for disabling of control and optionally disabling all child controls contained within groupbox |
![]() |
When control is disabled, icon will be displayed in grayscale |
XGroupBox Demo
The demo app shows some examples of what this control can do:
Header-Only Style
A separate dialog shows how header-only style may be used:
XGroupBox Example Gallery
There is another dialog that runs through different option settings and shows you the code used to generate the XGroupBox that is being displayed:
XGroupBox API
Function | Description |
---|---|
CXGroupBox& EnableTheme(BOOL bEnable, BOOL bRedraw = TRUE) | Enables/disables use of themes (if available) |
BOOL EnableWindow(BOOL bEnable = TRUE, BOOL bRecurseChildren = FALSE) | Enables/disables control, and optionally its children |
ALIGNMENT GetAlignment() | Retrieves control alignment; this is alignment of text and icon |
BOOL GetBold() | Retrieves bold setting |
COLORREF GetBorderColor() | Retrieves border color |
BORDER_STYLE GetBorderStyle() | Retrieves border style (flat or etched) |
BOOL GetDisabledStyle() | Returns TRUE if control will display disabled state |
CFont* GetFont() | Retrieves pointer to CFont member variable |
BOOL GetFont(LOGFONT *pLF) | Retrieves LOGFONT struct for font |
CString GetFontFaceName() | Retrieves font face name |
int GetFontPointSize() | Retrieves font point size |
ALIGNMENT GetIconAlignment() | Retrieves icon alignment (left or right of text) |
int GetIconSpacing() | Retrieves spacing between icon and text |
void GetMargins(int& nXMargin, int& nYMargin) | Retrieves x and y margins |
CONTROL_STYLE GetControlStyle() | Retrieves control style (groupbox or header) |
COLORREF GetTextColor() | Retrieves text color |
CXGroupBox& SetAlignment(ALIGNMENT eAlign, BOOL bRedraw = TRUE) | Sets control alignment (for text and icon) |
CXGroupBox& SetBold(BOOL bBold, BOOL bRedraw = TRUE) | Sets bold font |
CXGroupBox& SetBorderColor(COLORREF crBorder, BOOL bRedraw = TRUE) | Sets border color |
CXGroupBox& SetBorderStyle(BORDER_STYLE eStyle, BOOL bRedraw = TRUE) | Sets border style (flat or etched) |
CXGroupBox& SetControlStyle(CONTROL_STYLE eStyle, BOOL bRedraw = TRUE) | Sets control style (groupbox or header) |
CXGroupBox& SetDisabledStyle(BOOL bShowDisabledState, BOOL bRedraw = TRUE) | Sets whether control will display disabled state |
CXGroupBox& SetFont(CFont *pFont, BOOL bRedraw = TRUE) | Sets font via CFont object |
CXGroupBox& SetFont(LOGFONT * pLogFont, BOOL bRedraw = TRUE) | Sets font via LOGFONT struct |
CXGroupBox& SetFont(LPCTSTR lpszFaceName, int nPointSize, BOOL bRedraw = TRUE) | Sets font face name and point size |
CXGroupBox& SetIcon(HICON hIcon, UINT nIconSize = 16, BOOL bRedraw = TRUE) | Sets icon via HICON |
CXGroupBox& SetIcon(UINT nIconId, UINT nIconSize = 16, BOOL bRedraw = TRUE) | Sets icon via resource id |
CXGroupBox& SetIconAlignment(ALIGNMENT eAlign, BOOL bRedraw = TRUE) | Sets icon alignment (left or right of text) |
CXGroupBox& SetIconSpacing(int nIconSpacing, BOOL bRedraw = TRUE) | Sets spacing between icon and text |
CXGroupBox& SetImageList(CImageList * pImageList, int nIconNo, BOOL bRedraw = TRUE) | Sets image list for icons |
CXGroupBox& SetMargins(int nXMargin, int nYMargin, BOOL bRedraw = TRUE) | Sets x and y margins |
CXGroupBox& SetTextColor(COLORREF cr, BOOL bRedraw = TRUE) | Sets text color |
CXGroupBox& SetWindowText(LPCTSTR lpszText, BOOL bRedraw = TRUE) | Sets text |
How to Use
Step 1 - Add Files
To integrate XGroupBox into your app, you first need to add following files to your project:
- XGroupBox.cpp
- XGroupBox.h
- XVisualStyles.h
Step 2 - Add Header File to Your Source Module
In the module where you want to use XGroupBox (typically this will be dialog header file), include header file XGroupBox.h.Step 3 - Add Button Control to Dialog
Using the VS IDE resource editor, add a static control where you want the XGroupBox control. Here is a portion of the .rc file for demo app: LTEXT "XGroupBox 1",IDC_GROUPBOX1,10,146,110,32
LTEXT "Danger Will Robinson!",IDC_STATIC,43,165,73,8
LTEXT "XGroupBox 2",IDC_GROUPBOX2,130,146,100,32
LTEXT "~ My Music ~",IDC_STATIC,164,165,45,8
LTEXT "XGroupBox 3",IDC_GROUPBOX3,10,183,220,42,0
LTEXT "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean nec neque eu.",
IDC_STATIC,18,202,132,17,NOT WS_GROUP
PUSHBUTTON "Button",IDC_BUTTON2,165,201,50,14
LTEXT "XGroupBox 4",IDC_GROUPBOX4,10,230,220,42
LTEXT "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean nec neque eu.",
IDC_STATIC,18,249,132,17,NOT WS_GROUP
PUSHBUTTON "Button",IDC_BUTTON3,165,248,50,14
LTEXT
tag - the alignment of text and icon is done with the SetAlignment()
function. Next, associate static control with CStatic
class variable. Then replace CStatic
with CXGroupBox
:
// Dialog Data
//{{AFX_DATA(CXGroupBoxTestDlg)
enum { IDD = IDD_XGROUPBOXTEST_DIALOG };
CXGroupBox m_XGroupBox1;
CXGroupBox m_XGroupBox2;
CXGroupBox m_XGroupBox3;
CXGroupBox m_XGroupBox4;
int m_nStyle;
int m_nAlign;
int m_nColor;
BOOL m_bEnableThemes;
BOOL m_bDisable;
int m_nBorderStyle;
//}}AFX_DATA
Step 4 - Add Initialization Code
Add initialization code to yourOnInitDialog()
function. In demo app, one-time initialization is performed in OnInitDialog()
:
// one-time initialization
m_XGroupBox1.SetTextColor(RGB(255,0,0), FALSE)
.SetBold(TRUE, FALSE);
m_XGroupBox2.SetTextColor(RGB(34,139,34), FALSE) // forestgreen
.SetBold(TRUE, FALSE)
.SetFont(_T("Comic Sans MS"), 10, FALSE)
.SetAlignment(CXGroupBox::right);
m_XGroupBox3.SetAlignment(CXGroupBox::center);
m_XGroupBox4.SetFont(_T("Comic Sans MS"), 14, FALSE);
Dynamic initialization is performed in OnChange()
:
//=============================================================================
void CXGroupBoxTestDlg::OnChange()
//=============================================================================
{
UpdateData(TRUE);
if (m_hGlobeIcon)
::DestroyIcon(m_hGlobeIcon);
m_hGlobeIcon = 0;
static UINT nIconId[] = { IDI_T256, IDI_T32BPP };
static CXGroupBox *pControls[4] = { &m_XGroupBox1, &m_XGroupBox2,
&m_XGroupBox3, &m_XGroupBox4 };
int i = 0;
int nSize = m_nColor ? 32 : 16;
if (m_nStyle == 0 || m_nStyle == 2)
{
// Note: you can also use LoadIcon(), if you are sure that
// you will get correct icon
m_hGlobeIcon = (HICON) ::LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(nIconId[m_nColor]),
IMAGE_ICON, nSize, nSize, LR_DEFAULTCOLOR);
ASSERT(m_hGlobeIcon);
}
if (m_hGlobeIcon)
{
CImageList list;
VERIFY(list.Create(nSize, nSize, ILC_COLOR32|ILC_MASK, 2, 1));
VERIFY(list.Add(m_hGlobeIcon) == 0);
m_XGroupBox1.SetIcon(IDI_REDX, 32, FALSE);
m_XGroupBox2.SetIcon(IDI_AUDIOCD, 32, FALSE);
m_XGroupBox3.SetImageList(&list, 0, FALSE);
m_XGroupBox4.SetImageList(&list, 0, FALSE);
}
else
{
// no icon
for (i = 0; i < 4; i++)
pControls[i]->SetIcon((HICON)0, nSize, FALSE);
}
for (i = 0; i < 4; i++)
{
CString str = _T("");
if (m_nStyle == 0 || m_nStyle == 1)
str.Format(_T("XGroupBox %d"), i+1);
pControls[i]->SetWindowText(str);
}
if (m_nStyle == 0 || m_nStyle == 1)
m_XGroupBox3.SetWindowText(MAKEINTRESOURCE(IDS_GROUPBOX3_TEXT), FALSE);
CXGroupBox::ALIGNMENT eAlign = CXGroupBox::left;
if (m_nAlign)
eAlign = CXGroupBox::right;
for (i = 0; i < 4; i++)
pControls[i]->SetIconAlignment(eAlign, FALSE);
for (i = 0; i < 4; i++)
pControls[i]->SetBorderStyle((CXGroupBox::BORDER_STYLE) m_nBorderStyle, FALSE);
RedrawWindow();
for (i = 0; i < 4; i++)
pControls[i]->RedrawWindow();
}
References
- XHyperLink - yet another hyperlink control. I always use this for hyperlink on about box.
- XColorStatic - a colorizing static control. Handy to display text in a static control with colors.
- XIcon - an MFC control to display text and icon. This control displays text and icon anywhere you like.
- Add XP Visual Style Support to OWNERDRAW Controls. Excellent wrapper for uxtheme.dll APIs. I have added some extensions to this great class. Highly recommended.
More Groupbox Control Articles
- GroupBox with an icon: the ImageGroupBox control. This .Net control makes you want to use it.
- CXPGroupBox -- XP style groupbox and window style groupbox. This control offers two kinds of groupbox.
- The Grouper - A Custom Groupbox Control. Visually stunning. I am in awe.
- Header-only GroupBox. .Net control that allows visual separation, rather than grouping.
- CGroupLine. A very nice MFC-based header-only groupbox.
Revision History
Version 1.0 - 2008 September 2
- Initial public release
Usage
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.