Click here to Skip to main content
14,298,693 members

Collapsed groupbox

Rate this:
4.27 (16 votes)
Please Sign up or sign in to vote.
4.27 (16 votes)
9 Oct 2009CPOL
A variant for collapsed groupbox class
Image 1

Introduction

First of all, sorry for my English, I'm from Ukraine. :)
The main idea was to make a collapsed groupbox. I found a large number of C# groupboxes I needed, but none in C++. And I had no time to create it from the beginning, so I used the class described here by JackCa. After fixing some bugs and writing several functions, I got a nice variant of collapsed groupbox.

How To Use It

You have to include a class header in your dialog h file:

#include <span class="code-string">"CollapseGroupBox.h"</span>

Then change the base class of your groupbox variables from CStatic or CButton to CollapseGroupBox.
For example:

// before
CStatic m_st1;
CStatic m_st2;
CStatic m_st3;
CStatic m_st4;

change to:

//after
CollapseGroupBox m_st1;
CollapseGroupBox m_st2;
CollapseGroupBox m_st3;
CollapseGroupBox m_st4;

If you don't have groupbox's variables, use class wizard to create them. Select "Control" category for them.

Using the Code

First of all, if your groupbox has a caption string and you like caption's right alignment, and your dialog isn't scalable, you have to do nothing at all to get good results. Nonetheless, I'll give you a brief description of how to use this class.
Let's talk about caption.
Caption variants are SS_LEFT, SS_CENTER, SS_RIGHT:

BOOL CGBdemoDlg::OnInitDialog()
{
...
// default caption alignment is RIGHT. To change it follow code above
	m_st2.SetAlignment(SS_LEFT); // left caption alignment
	m_st4.SetAlignment(SS_CENTER); // center caption alignment
...
}	

My dialog has 4 groupboxes. And groupbox 1 and 3 will have right caption alignment.

You also have the possibility to change box visualization as you want. These functions allow to modify colors:

SetBorderColor(COLORREF clrBorder);
SetCatptionTextColor(COLORREF clrText);
SetBackgroundColor(COLORREF clrBKTilte);

And these - to modify caption string and its visualization:

SetText(LPCTSTR lpszTitle);
SetFontBold(BOOL bBold);
SetFontName(const CString& strFont, BYTE byCharSet = ANSI_CHARSET);
SetFontUnderline(BOOL bSet);
SetFontItalic(BOOL bSet);
SetFontSize(int nSize);
SetFont(LOGFONT lf);
SetAlignment(DWORD dwType);

Also if your dialog BGColor isn't COLOR_BTNFACE, use function setBGColor(COLORREF bgColor); for nice background visualization.

Now, let's talk about collapsing.

std::vector<cwnd* /> intoElements; 	// vector of groupbox's components
bool m_frameMinimized; 	// Header-Only Style flag
BOOL IsInGroupBox(CWnd* pCtrl) const;
void GetGroupBoxElements();
void ShowElements(bool bShow);

As you see, we have a vector of elements located inside in groupbox. Function IsInGroupBox tells us about location of one element, and function GetGroupBoxElements check the location of everything in the dialog and fills our vector. But if you want, you may fill it by your own hands. :)

intoElements.push_back(GetDlgItem(ELEMENT_ID));

And now the most interesting thing. In my dialog, box4 is in box3. And, without this code, collapsing works incorrectly:

BOOL CGBdemoDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
	if (wParam == UM_UPDATEFORM)
	{// groupbox changed his state (Header-Only Style / Full State)
		if (lParam == (LPARAM)m_st3.m_hWnd)
		{
			if (m_st3.m_frameMinimized == false)
				m_st4.SetFrameExpand(m_st4.m_frameMinimized);
		}
	}
	if (wParam == UM_MOUSELEAVE)
	{// mouse leaves groupbox
	}
	if (wParam == UM_MOUSEENTRY)
	{// mouse comes to groupbox
	}

	return CDialog::OnCommand(wParam, lParam);
}

Our groupbox sends three variants of messages:

  • mouse leaves groupbox
  • mouse comes to groupbox
  • groupbox changed its state

So, we can control everything we need. For example, in my application (not in this demo) I use UM_UPDATEFORM to size dialog vertically for hiding free space.

A few words about dynamic creation... try this:

m_boxMain.Create(_T("Caption"),WS_CHILD | WS_VISIBLE | 
	BS_GROUPBOX,CRect(xxx,xxx,xxx,xxx),this,ELEMENT_ID);

About one of the most popular questions "I can't see any controls in groupbox".
The simplest answer is Open dialog in editor, select groupbox, Ctrl+C, Del, Ctrl+V and everything will be OK. :)
Or you can add private function for changing Z-order or elements in vector intoElements and put it at the end of GetGroupBoxElements.

History

  • 8th October, 2009: Initial version

License

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

Share

About the Author

Nick Gorlov
Software Developer
Ukraine Ukraine
No Biography provided

Comments and Discussions

 
QuestionChange header? Pin
Andornot17-Apr-19 20:56
memberAndornot17-Apr-19 20:56 
Thank you for your collapsible groupbox project.

I would like to change the header from a rounded rect to a plain rectangle, so I make the
following changes:
//m_BackgroundDC.RoundRect(rectTitle, CPoint(10, 10));
m_BackgroundDC.Rectangle(rectTitle);


But, it seems the header is now smaller than the groupbox frame. So I increase the header rect
by 1:
rectTitle.right  = rectClient.right + 1;


This has a strange effect. Every time I collapse and expand the group, it moves the groupbox to the right by 1 pixel every time. I don't understand why this is happening.

Other issues:

- You shouldn't be saving system colors in the CollapseGroupBox class.
If the system changes while your program is running, then those colors won't get updated.

- I prefer that groupboxes be collapsed/expanded in OnLButtonUp(), not OnLButtonDown().

- Changing title background in OnMouseMove() is causing flicker. There's no need to capture mouse
if it's input not being used. That entire section can be commented out.

- I hope someone can implement a better roll-up feature when using multiple collapsible groupboxes, that moves both the groupbox and its contents.

modified 18-Apr-19 22:32pm.

AnswerRe: Change header? Pin
Andornot19-Apr-19 12:08
memberAndornot19-Apr-19 12:08 
QuestionHeader disappears on MoveWindow? Pin
dstrombe24-Jul-15 5:31
memberdstrombe24-Jul-15 5:31 
AnswerRe: Header disappears on MoveWindow? Pin
Nick Gorlov26-Jul-15 20:56
memberNick Gorlov26-Jul-15 20:56 
GeneralRe: Header disappears on MoveWindow? Pin
dstrombe27-Jul-15 3:17
memberdstrombe27-Jul-15 3:17 
QuestionOrder of controls Pin
Octopod20-Jan-12 3:21
memberOctopod20-Jan-12 3:21 
GeneralMy vote of 1 Pin
Octopod19-Jan-12 23:02
memberOctopod19-Jan-12 23:02 
GeneralCrash:because not getting the control handle Pin
samal.subhashree1-Nov-09 20:34
membersamal.subhashree1-Nov-09 20:34 
GeneralRe: Crash:because not getting the control handle Pin
Nick Gorlov2-Nov-09 4:09
memberNick Gorlov2-Nov-09 4:09 
GeneralFantastic job Pin
samal.subhashree31-Oct-09 1:32
membersamal.subhashree31-Oct-09 1:32 
QuestionI like it, so what's the best way to use it? Pin
Grump12-Oct-09 23:25
memberGrump12-Oct-09 23:25 
AnswerRe: I like it, so what's the best way to use it? [modified] Pin
Nick Gorlov13-Oct-09 2:02
memberNick Gorlov13-Oct-09 2:02 
GeneralI was intrigued - Group Boxes disappearing bug Pin
c-sharp9-Oct-09 4:42
memberc-sharp9-Oct-09 4:42 
GeneralRe: I was intrigued - Group Boxes disappearing bug Pin
Nick Gorlov11-Oct-09 20:04
memberNick Gorlov11-Oct-09 20:04 
GeneralRe: I was intrigued - Group Boxes disappearing bug Pin
c-sharp12-Oct-09 1:55
memberc-sharp12-Oct-09 1:55 
GeneralRe: I was intrigued - Group Boxes disappearing bug Pin
LazyDave12-Oct-09 11:15
professionalLazyDave12-Oct-09 11:15 
GeneralRe: I was intrigued - Group Boxes disappearing bug Pin
Nick Gorlov12-Oct-09 20:02
memberNick Gorlov12-Oct-09 20:02 

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.

Article
Posted 9 Oct 2009

Tagged as

Stats

41.3K views
2.7K downloads
41 bookmarked