Contiuously updating sizing header

If you have ever used a CHeader the first thing you notice that it isn't as nice as the one that appears at the top of list controls. What I mean by this is that when you resize the control
all you get is a resizing line.  When you move this line the header does not update its items
as it moves only at the end when you release the button.  With a CListCtrl the headers continuously update as they move.

This functionality is cool and would be nice to have in a standard CHeader control.
Following is the procedure by which you can add this functionality to your own CHeader derived classes.  All you need to do is override a couple of the mouse procedures and you are in business. An Avi of how it works:

Below are the new procedures and the code for each:
//Header
class CSizeHeader : public CHeaderCtrl
{
	// Construction
	public:
	CSizeHeader();

	// Attributes
	public:

	// Operations
	public:

	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CSizeHeader)
	//}}AFX_VIRTUAL

	// Implementation
	public:
	CString m_sGrayFont;
	CString m_sSelFont;
	virtual ~CSizeHeader();

	// Generated message map functions
	protected:
	CSize m_minSize;
	CRect m_itemRect;
	CSize m_offset;
	int m_cx;
	int m_twidth;
	int m_hititem;
	CFont m_selFont;
	//{{AFX_MSG(CSizeHeader)
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
	};

// -------------------------------------------------------------------------------------------------------
//.cpp file
CSizeHeader::CSizeHeader()
{
	m_sSelFont = _T("Helv");
	m_sGrayFont = _T("Helv");
}

CSizeHeader::~CSizeHeader()
{
}
 

BEGIN_MESSAGE_MAP(CSizeHeader, CHeaderCtrl)
//{{AFX_MSG_MAP(CSizeHeader)
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CSizeHeader::OnLButtonDown(UINT nFlags, CPoint point) 
{
	HD_ITEM item;
	char text[255];

	item.pszText = text;
	item.mask = HDI_TEXT | HDI_WIDTH;
	item.cchTextMax = 255;


	m_twidth = 0;
	for(int i = 0; i < GetItemCount(); i++)
	{
		GetItem(i, &item);
		m_twidth += item.cxy;
		if(m_twidth  > point.x - 10 && m_twidth < point.x + 10)
		{
			m_hititem = i;
			m_cx = item.cxy;
			break;
		}
		else
			m_hititem = -1;
//		return;
	}	
	CHeaderCtrl::OnLButtonDown(nFlags, point);
	return;
}

void CSizeHeader::OnMouseMove(UINT nFlags, CPoint point) 
{
	if(m_hititem > -1)
	{
		SetCapture();
		HD_ITEM item;
		char text[255];

		item.pszText = text;
		item.mask = HDI_TEXT | HDI_WIDTH;
		item.cchTextMax = 255;

		GetItem(m_hititem, &item);

		item.cxy = m_cx - (m_twidth - point.x);

		SetItem(m_hititem, &item);
		return;
	}
	CHeaderCtrl::OnMouseMove(nFlags, point);
	return;
}

void CSizeHeader::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if(m_hititem > -1)
	{
		m_hititem = -1;
		ReleaseCapture();
		return;
	}
	CHeaderCtrl::OnLButtonUp(nFlags, point);
	return;
}

BOOL CSizeHeader::OnEraseBkgnd(CDC* pDC) 
{
	HD_ITEM item;
	char text[255];

	item.pszText = text;
	item.mask = HDI_TEXT | HDI_WIDTH;
	item.cchTextMax = 255;

	int twidth = 0;

	for(int i = 0; i < GetItemCount(); i++)
	{
		GetItem(i, &item);
		twidth += item.cxy;
	}

	CRect rect;

	GetClientRect(rect);
	rect.DeflateRect(0, CY_BORDER);
	rect.left = twidth;
	
	CBrush rBrush(GetSysColor(COLOR_3DFACE));
	pDC->FillRect(rect, &rBrush);
	return FALSE;	
}



Comments

  • Some useful undocumented header styles

    Posted by Legacy on 04/14/2000 12:00am

    Originally posted by: Matthew Shovelton

    I've just been playing about with CHeaderCtrls and, through scanning the MFC header files, have discovered 3 undocumented styles (HDS_* codes). One of them produces the behaviour described in the above article. The styles are:

    HDS_FULLDRAG - Dynamically updates the header control as you resize it. It sends HDN_ITEMCHANGING and HDN_ITEMCHANGED notifications as you resize, so trap these instead of HDN_TRACK.

    HDS_DRAGDROP - Allows drag and drop movement of header items

    HDS_HOTTRACK - Highlights header items as you move the cursor over the header.

    Hope you find this useful.


    • Trapping the messages

      Posted by mpirooz on 06/30/2008 03:41pm

      The best way I've discovered to accomplish this is to set the LRESULT* passed into the reflect functions to -1.

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds