Change the background color of the header of a List Control

There are two answers for this question: 1 - The window background color is changed by overriding the WM_ERASEBKGND message processing and painting the background with the chosen color (yellow on the picture). 2 - The item background color is changed by using the custom draw service (red and blue items on the picture).

So, how does one go about it? You have to specialize the CListCtrl's embedded CHeaderCtrl. The sample application shows how this can be done through two specialized classes CColorListCtrl and CColorHeaderCtrl. The list holds an instance of the header which is subclassed when the list is created (or subclassed):

// CColorListCtrl::SubclassHeader // // Subclasses the header control, if any // The return value is used for OnCreate // int CColorListCtrl::SubclassHeader() { CHeaderCtrl* pHeader; int nRval = 0; // // Subclass the header control // pHeader = GetHeaderCtrl(); if(pHeader && pHeader->GetSafeHwnd()) { if(!m_hdr.SubclassWindow(pHeader->GetSafeHwnd())) nRval = -1; } return nRval; }

There is nothing more to say about CColorListCtrl (by the way, the header control can be subclassed "outside" the list control: we use this here for convenience). Now, let's see what the CColorHeaderCtrl is doing. First, the window backgroung painting code: // CColorHeaderCtrl::OnEraseBkgnd // // This is where we specify the background color of the header // BOOL CColorHeaderCtrl::OnEraseBkgnd(CDC* pDC) { CRect rc; GetClientRect(&rc); pDC->FillSolidRect(&rc, RGB(255, 255, 0)); // Yellow return TRUE; }

As you can see, it is very simple: it just paints the client area with yellow. The item painting code is a bit more tricky because it uses the custom draw service. This service interacts with the window through a message exchange mechanism. It uses the NM_CUSTOMDRAW notification message (reflected here) to tell the window in what stage the drawing process is (we handle CDDS_PREPAINT and CDDS_ITEMPREPAINT) and to request it to override the desired settings. Here, we only change the text and background colors according to the item number: // CColorHeaderCtrl::OnCustomDraw // // Handles custom draw // void CColorHeaderCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { NMCUSTOMDRAW* pCD = (NMCUSTOMDRAW*)pNMHDR; DWORD dwDrawStage, dwItemSpec; *pResult = CDRF_DODEFAULT; dwDrawStage = pCD->dwDrawStage; dwItemSpec = pCD->dwItemSpec; if(dwDrawStage == CDDS_PREPAINT) { *pResult = CDRF_NOTIFYITEMDRAW; } else if(dwDrawStage == CDDS_ITEMPREPAINT) { HDC hDC = pCD->hdc; SetTextColor(hDC, RGB(255, 255, 255)); if(dwItemSpec) SetBkColor(hDC, RGB( 0, 0, 255)); // Blue else SetBkColor(hDC, RGB( 255, 0, 0)); // Red *pResult = CDRF_NEWFONT; } }

It works like this: First, the service tells us that it is about to paint the header (CDDS_PREPAINT). We reply saying that we want to be notified for the painting of each item (CDRF_NOTIFYITEMDRAW). Next, the service tells us that it is about to paint an item (CDDS_ITEMPREPAINT). We change the appropriate colors on the DC and reply saying that we did so (CDRF_NEWFONT). Note that we could even have changed the font, specifying a different one per item. For all the other states we don't care about, we tell the service to do the default painting (CDRF_DODEFAULT).

And that's it.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值