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

XGroupBox - an MFC groupbox control to display text and icon

Rate me:
Please Sign up or sign in to vote.
4.98/5 (60 votes)
2 Sep 2008CPOL5 min read 125K   4.6K   92   26
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:
screenshotReplacement for Win32 groupbox, without the flicker when resized
screenshotDisplay icon and/or text
screenshotDisplay standard groupbox or header-only groupbox
screenshotEasy to set colors, font, and horizontal alignment
screenshotSupport theming or custom colors (for header-only style, theming is not supported)
screenshotAllow for disabling of control and optionally disabling all child controls contained within groupbox
screenshotWhen control is disabled, icon will be displayed in grayscale

XGroupBox Demo

The demo app shows some examples of what this control can do:

screenshot

This dialog is resizable and shows difference in flickering between XGroupBox and Win32 groupbox.

Header-Only Style

A separate dialog shows how header-only style may be used:

screenshot

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:

screenshot

XGroupBox API

FunctionDescription
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
Note that all the static controls use the 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 your OnInitDialog() 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(&quot;&quot;);
        if (m_nStyle == 0 || m_nStyle == 1)
            str.Format(_T(&quot;XGroupBox %d&quot;), 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

More Groupbox Control Articles

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.

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) 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 www.hdsoft.org.






Comments and Discussions

 
QuestionUsed for changintext color Pin
Member 56884435-Apr-14 3:09
Member 56884435-Apr-14 3:09 
QuestionHow to Create the XGroupBox not DDX_Control? Pin
54223256724-Jul-11 17:11
54223256724-Jul-11 17:11 
AnswerRe: How to Create the XGroupBox not DDX_Control? Pin
54223256724-Jul-11 17:17
54223256724-Jul-11 17:17 
GeneralOnPaint() function that repaint the XGroupBox and hide controls in it!! Pin
JSmey29-Apr-10 23:08
JSmey29-Apr-10 23:08 
GeneralRe: OnPaint() function that repaint the XGroupBox and hide controls in it!! Pin
JSmey29-Apr-10 23:19
JSmey29-Apr-10 23:19 
GeneralRe: OnPaint() function that repaint the XGroupBox and hide controls in it!! Pin
Hans Dietrich29-Apr-10 23:23
mentorHans Dietrich29-Apr-10 23:23 
QuestionIs it possible? Pin
kllbzz26-Dec-09 9:47
kllbzz26-Dec-09 9:47 
GeneralThanks a Lot Pin
cyper_12-Aug-09 4:03
cyper_12-Aug-09 4:03 
GeneralWorked first try! Pin
jcarlile0331-Mar-09 22:53
jcarlile0331-Mar-09 22:53 
GeneralWM_UPDATEUISTATE message Pin
P. Lequeux27-Mar-09 0:23
P. Lequeux27-Mar-09 0:23 
GeneralMemory leaks Pin
90623-Feb-09 0:16
90623-Feb-09 0:16 
GeneralRe: Memory leaks Pin
Hans Dietrich23-Feb-09 0:22
mentorHans Dietrich23-Feb-09 0:22 
QuestionBackground color different of COLOR_BTNFACE Pin
alen6721-Jan-09 6:07
alen6721-Jan-09 6:07 
QuestionIcon with 16777216 colors? Pin
m_kurkute13-Oct-08 2:57
m_kurkute13-Oct-08 2:57 
AnswerRe: Icon with 16777216 colors? Pin
Hans Dietrich13-Oct-08 13:30
mentorHans Dietrich13-Oct-08 13:30 
QuestionMinor bug? Pin
Snorri Kristjansson22-Sep-08 11:28
professionalSnorri Kristjansson22-Sep-08 11:28 
GeneralThanks Pin
hw770417-Sep-08 2:44
hw770417-Sep-08 2:44 
GeneralEasy 5... as usual Pin
Franc Morales2-Sep-08 7:06
Franc Morales2-Sep-08 7:06 
GeneralRe: Easy 5... as usual Pin
Hans Dietrich2-Sep-08 7:17
mentorHans Dietrich2-Sep-08 7:17 
GeneralRe: Easy 5... as usual Pin
ugly beast2-Sep-08 9:04
ugly beast2-Sep-08 9:04 
GeneralRe: Easy 5... as usual Pin
Franc Morales2-Sep-08 9:06
Franc Morales2-Sep-08 9:06 
General1-vote Pin
Ivan Krasko8-Sep-08 7:29
Ivan Krasko8-Sep-08 7:29 
GeneralRe: 1-vote (correction) Pin
Ivan Krasko8-Sep-08 7:37
Ivan Krasko8-Sep-08 7:37 
GeneralYou do cool stuff! Pin
Ilíon2-Sep-08 6:19
Ilíon2-Sep-08 6:19 
GeneralExcellent! Pin
NGS 5496722-Sep-08 5:08
NGS 5496722-Sep-08 5:08 

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.