Multiline Header Control Inside a CListCtrl

First of all I have to mention that Alon Peleg helped me find the solution to the problem so I feel it is only fair that his name will be mentioned as an author.

On a recent project we did I had to make the header control of a CListCtrl multiline. This small project show how to do it by subclassing the CHeaderCtrl of the CListCtrl.

If you want to use this code just the HeaderCtrlExt.h and HeaderCtrlExt.cpp files into your source code.

In addition on your CListView or CListCtrl derived class add a member variable of type CHeaderCtrlEx and a member variable of type CFont.

If you are using a CListCtrl without a view then put the following code in the end of the OnCreate handler of the CListCtrl:

///////////////////////SET UP THE MULTILINE HEADER CONTROL
//m_NewHeaderFont is of type CFont
m_NewHeaderFont.CreatePointFont(190,"MS Serif");

CHeaderCtrl* pHeader = NULL;
pHeader=GetHeaderCtrl();

if(pHeader==NULL)
   return;

VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));

//A BIGGER FONT MAKES THE CONTROL BIGGER
m_HeaderCtrl.SetFont(&m_NewHeaderFont);

HDITEM hdItem;

hdItem.mask = HDI_FORMAT;

for(i=0; i < m_HeaderCtrl.GetItemCount(); i++)
{
   m_HeaderCtrl.GetItem(i,&hdItem);

   hdItem.fmt|= HDF_OWNERDRAW;

   m_HeaderCtrl.SetItem(i,&hdItem);
}

If you are using a CListView or any class derived by it then add the following code in the OnInitialUpdate override of the CListView:

///////////////////////SET UP THE MULTILINE HEADER CONTROL
//m_NewHeaderFont is of type CFont
m_NewHeaderFont.CreatePointFont(190,"MS Serif");

CListCtrl& ListCtrl = GetListCtrl();

CHeaderCtrl* pHeader = NULL;
pHeader=ListCtrl.GetHeaderCtrl();

if(pHeader==NULL)
   return;

VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));

//A BIGGER FONT MAKES THE CONTROL BIGGER
m_HeaderCtrl.SetFont(&m_NewHeaderFont);

HDITEM hdItem;

hdItem.mask = HDI_FORMAT;

for(i=0; i<m_HeaderCtrl.GetItemCount(); i++)
{
   m_HeaderCtrl.GetItem(i,&hdItem);

   hdItem.fmt|= HDF_OWNERDRAW;

   m_HeaderCtrl.SetItem(i,&hdItem);
}

The only difference between the two parts of code is way we get a pointer to the Header control.

That's it. Enjoy!!!



Downloads

Comments

  • Re:Update for use with XP Theme and Common Controls 6.0

    Posted by hideo on 01/16/2007 01:00am

    I am a Japanese engineer, the comment cannot be written in English well. 
    I had the same problem too.
    It came to operate well for me by correcting the source program as follows.
    
    (1)Before
    	UINT	uFormat;
    	switch( hdi.fmt ) {
    	case HDF_CENTER:		uFormat = DT_CENTER;		break;
    	case HDF_LEFT:			uFormat = DT_LEFT;			break;
    	case HDF_RIGHT:			uFormat = DT_RIGHT;			break;
    	}
    
    (2)After
    	UINT	uFormat;
    	uFormat = DT_LEFT;
    	if ( ( hdi.fmt & HDF_RIGHT ) != 0 ) {
    		uFormat = DT_RIGHT;
    	} else
    	if ( ( hdi.fmt & HDF_CENTER ) != 0 ) {
    		uFormat = DT_CENTER;
    	}

    Reply
  • Update for use with XP Theme and Common Controls 6.0

    Posted by atl_bearcat on 01/11/2007 04:49pm

    I had the same problem with getting this code to work with the Common Controls 6.0 and the XP Theme.
    
    After a lot of searching, I found a post from Migel on another website that suggessted the approach below.  It works great!  I thought it should be posted here as well since it was so hard to find.
      
    Basically, you'll need to define a subclass for CHeaderCtrl and catch the HDM_LAYOUT message.  Here is Migel's example:
    
    add new class to the your project:
    /////////////////////////////////////////////////////////////////////////////
    // CMyFatHeader window
    
    class CMyFatHeader : public CHeaderCtrl
    {
    // Construction
    public:
         CMyFatHeader();
    
    // Attributes
    public:
    
    // Operations
    public:
    
    // Overrides
         // ClassWizard generated virtual function overrides
         //{{AFX_VIRTUAL(CMyFatHeader)
         //}}AFX_VIRTUAL
    
    // Implementation
    public:
         virtual ~CMyFatHeader();
    
         // Generated message map functions
    protected:
         //{{AFX_MSG(CMyFatHeader)
         afx_msg LRESULT OnHeaderLayout(WPARAM wp, LPARAM lp);
         //}}AFX_MSG
    
         DECLARE_MESSAGE_MAP()
    };
    
    // MyFatHeader.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "list_example.h"
    #include "MyFatHeader.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CMyFatHeader
    
    CMyFatHeader::CMyFatHeader()
    {
    }
    
    CMyFatHeader::~CMyFatHeader()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(CMyFatHeader, CHeaderCtrl)
         //{{AFX_MSG_MAP(CMyFatHeader)
              // NOTE - the ClassWizard will add and remove mapping macros here.
         ON_MESSAGE(HDM_LAYOUT, OnHeaderLayout)
         //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CMyFatHeader message handlers
    
    afx_msg LRESULT CMyFatHeader::OnHeaderLayout(WPARAM, LPARAM lParam)
    {
         LPHDLAYOUT lphdlayout = (LPHDLAYOUT)lParam;
    
         LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);
    
         lphdlayout->pwpos->cy = 40;
         lphdlayout->prc->top = 40;
    
         return lResult;
    }
    
    ////////////////////// in the your List Derived control all these
    
    class CMyList : public CListCtrl
    {
         CMyFatHeader m_hdr; // this line!
    // Construction
    public:
         CMyList();
    
    // Attributes
    public:
    
    // Operations
    public:
    
    // Overrides
         // ClassWizard generated virtual function overrides
         //{{AFX_VIRTUAL(CMyList)
         protected:
         virtual void PreSubclassWindow(); ///!!!!! this line
         //}}AFX_VIRTUAL
    
    // Implementation
    public:
         virtual ~CMyList();
    
         // Generated message map functions
    protected:
         //{{AFX_MSG(CMyList)
         afx_msg BOOL OnItemchanged(NMHDR* pNMHDR, LRESULT* pResult);
         //}}AFX_MSG
    
         DECLARE_MESSAGE_MAP()
    };
    
    
    /// cpp file add this member
    void CMyList::PreSubclassWindow() 
    {
         CListCtrl::PreSubclassWindow();
         m_hdr.SubclassDlgItem(0, this);
    }

    Reply
  • Can not download this source file HeaderCtrlEx_src.zip?

    Posted by zhangyiyun on 09/25/2006 10:07pm

    I can not download this source file HeaderCtrlEx_src.zip. Because the download file is bad ,I could not open it. Who could help me and send it to me. Thanks. MyEmail: zyiyun@mail.xjtu.edu.cn

    Reply
  • Does not work with CListCtrl when using XP theme

    Posted by mjames12 on 08/18/2006 02:47pm

    The example uses CListView and works great when I ported it to CListCtrl in Win2000. However, in WinXP it no longer works. It works if I set me theme to Windows Classic but if I set it to XP theme, it does not work. Any suggestions?

    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 …

  • CentreCorp is a fully integrated and diversified property management and real estate service company, specializing in the "shopping center" segment, and is one of the premier retail service providers in North America. Company executives travel a great deal, carrying a number of traveling laptops with critical current business data, and no easy way to back up to the network outside the office. Read this case study to learn how CentreCorp implemented a suite of business continuity services that included …

Most Popular Programming Stories

More for Developers

RSS Feeds