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; }