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!!!

Comments
Re:Update for use with XP Theme and Common Controls 6.0
Posted by hideo on 01/16/2007 01:00amI 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; }ReplyUpdate for use with XP Theme and Common Controls 6.0
Posted by atl_bearcat on 01/11/2007 04:49pmI 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); }ReplyCan not download this source file HeaderCtrlEx_src.zip?
Posted by zhangyiyun on 09/25/2006 10:07pmI 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
ReplyDoes not work with CListCtrl when using XP theme
Posted by mjames12 on 08/18/2006 02:47pmThe 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