Click here to Skip to main content
15,880,972 members
Articles / Desktop Programming / MFC

Rollup Control

Rate me:
Please Sign up or sign in to vote.
4.94/5 (54 votes)
16 Dec 20032 min read 377.3K   6.5K   118  
A 3DSMax like Rollup control
//////////////////////////////////////////////////////////////////////////////
//
// RollupCtrl.cpp
//
// 
// Code Johann Nadalutti
// Mail: jnadalutti@hotmail.com
//
//////////////////////////////////////////////////////////////////////////////
//
// This code is free for personal and commercial use, providing this 
// notice remains intact in the source files and all eventual changes are
// clearly marked with comments.
//
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
//////////////////////////////////////////////////////////////////////////////
// History
// --------
// #v1.0
//	31/03/01:	Created
//
// #v1.01
//	13/04/01:	Added ScrollToPage() method
//				Added automatic page visibility to ExpandPage() method
//				Added Mousewheel support
//	15/04/01:	Added mouse capture checking on WM_MOUSEMOVE dialog msg
//				Added SetCursor() on Dialog WM_SETCURSOR
//				Added MovePageAt() method
//	17/04/01:	Fixed Group Boxes displayed over Buttons
//	20/04/01:	Added IsPageExpanded() and IsPageExpanded() methods
//				Added PopupMenu
//				Added Button subclassing (now button's focus not drawn)
//
// #v1.02
//	10/06/02: Added pages dividing up into columns 
//	17/06/02: Added SetPageCaption() method
//	19/11/02: Fixed _RemovePage() method
//	29/10/03: Background color for AfxRegisterWndClass()
//
// Note
// -----
//	Dialog box width is
//		RollupCtrlClientRect.Width() - RC_SCROLLBARWIDTH - (RC_GRPBOXINDENT*2)
//
//
// Thanks to
// ----------
//
// PJ Arends, Ramon Smits, Uwe Keim, Daniel Madden, Do Quyet Tien,
// Ravi Bhavnani, Masaaki Onishi, Bernard Desfour ...
// and all others users for their comments.
//

#pragma once

#include <afxtempl.h>

/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl structures and defines

	struct RC_PAGEINFO {
		CString		cstrCaption;
		CWnd*			pwndTemplate;
		CButton*	pwndButton;
		CButton*	pwndGroupBox;
		BOOL			bExpanded;
		BOOL			bEnable;
		BOOL			bAutoDestroyTpl;
		WNDPROC 	pOldDlgProc;		//Old wndTemplate(Dialog) window proc
		WNDPROC 	pOldButProc;		//Old wndTemplate(Button) window proc
	};

	#define	RC_PGBUTTONHEIGHT				18
	#define	RC_SCROLLBARWIDTH				6
	#define RC_CURSOR								MAKEINTRESOURCE(IDC_SIZENS)
	#define RC_MINCOLUMNWIDTH				16
	#define	RC_GRPBOXINDENT					6
	#define	RC_SCROLLBARCOLOR				RGB(150,180,180)

	//TrackMenu IDs
	#define RC_MID_EXPANDALL				0x100
	#define RC_MID_COLLAPSEALL			0x101
	#define RC_MID_STARTPAGES				0x102

/////////////////////////////////////////////////////////////////////////////
// CRollupCtrl window

class CRollupCtrl : public CWnd
{
	DECLARE_DYNCREATE(CRollupCtrl)

public:

	// Constructor-Destructor
	CRollupCtrl();
	virtual ~CRollupCtrl();

	// Methods
	BOOL	Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

	int		InsertPage(const char* caption, CDialog* pwndTemplate, BOOL bAutoDestroyTpl=TRUE, int idx=-1);	//Return page zero-based index
	int		InsertPage(const char* caption, UINT nIDTemplate, int idx=-1);	//Return page zero-based index
	int		InsertPage(const char* caption, UINT nIDTemplate, CRuntimeClass* rtc, int idx=-1);	//Return page zero-based index

	void	RemovePage(int idx);	//idx is a zero-based index
	void	RemoveAllPages();

	void	ExpandPage(int idx, BOOL bExpand=TRUE, BOOL bScrollToPage=TRUE);	//idx is a zero-based index
	void	ExpandAllPages(BOOL bExpand=TRUE);

	void	EnablePage(int idx, BOOL bEnable=TRUE);	//idx is a zero-based index
	void	EnableAllPages(BOOL bEnable=TRUE);

	const RC_PAGEINFO*	GetPageInfo(int idx);

	// New v1.01 Methods
	void	ScrollToPage(int idx, BOOL bAtTheTop=TRUE);
	int		MovePageAt(int idx, int newidx);	//newidx can be equal to -1 (move at end)

	BOOL	IsPageExpanded(int idx);
	BOOL	IsPageEnabled(int idx);
	int		GetPagesCount()		{ return (int)m_PageList.GetSize(); }

	// New v1.02 Methods
	BOOL	IsAutoColumnsEnabled()								{ return m_bEnabledAutoColumns;	}
	void	EnableAutoColumns(BOOL bEnable=TRUE);
	BOOL	SetColumnWidth(int nWidth);						//nWidth must be superior to RC_MINCOLUMNWIDTH
	BOOL	SetPageCaption(int idx, LPCSTR caption);

	//Helpers
	void	RecalLayout();

protected:

	// Internal methods
	int		GetPageIdxFromButtonHWND(HWND hwnd);
	void	_ExpandPage(RC_PAGEINFO* pi, BOOL bExpand);
	void	_EnablePage(RC_PAGEINFO* pi, BOOL bEnable);
	int		_InsertPage(const char* caption, CDialog* dlg, int idx, BOOL bAutoDestroyTpl);
	void	_RemovePage(int idx);

	// Datas
	CString	m_strMyClass;
	CArray	<RC_PAGEINFO*,RC_PAGEINFO*>		m_PageList;
	int			m_StartYPos, m_PageHeight;
	int			m_OldMouseYPos, m_SBOffset;
	CBrush	m_cbrush;
	CMenu		m_cmenuCtxt;
	int			m_nColumnWidth;
	BOOL		m_bEnabledAutoColumns;

	// Window proc
	static LRESULT CALLBACK DlgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	static LRESULT CALLBACK ButWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

public:

	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CRollupCtrl)
	protected:
	virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
	//}}AFX_VIRTUAL

	// Generated message map functions
protected:
	//{{AFX_MSG(CRollupCtrl)
	afx_msg void OnPaint();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
	afx_msg void OnContextMenu( CWnd* pWnd, CPoint pos );
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions