The CListCtrlWithCustomDraw Class In the OnCustomdraw for CListCtrlWithCustomDraw, I provide a generic handler for custom draw notifications. The bulk of the code is a switch statement on the draw stage we are up to (refer to my previous article). At each of the pre-paint stages, I call virtual functions to get color information, fonts required, and to take over (or augment) the drawing process. I also allow for extra drawing during the post-paint stages. Let's look at the fleshed out OnCustomdraw function for CListCtrlWithCustomDraw: void CListCtrlWithCustomDraw::OnCustomdraw(NMHDR* pNMHDR,LRESULT* pResult) { // first, lets extract data from // the message for ease of use later NMLVCUSTOMDRAW* pNMLVCUSTOMDRAW = (NMLVCUSTOMDRAW*)pNMHDR; // we'll copy the device context into hdc // but won't convert it to a pDC* until (and if) // we need it as this requires a bit of work // internally for MFC to create temporary CDC // objects HDC hdc = pNMLVCUSTOMDRAW->nmcd.hdc; CDC* pDC = NULL; // here is the item info // note that we don't get the subitem // number here, as this may not be // valid data except when we are // handling a sub item notification // so we'll do that separately in // the appropriate case statements // below. int nItem = pNMLVCUSTOMDRAW->nmcd.dwItemSpec; UINT nState = pNMLVCUSTOMDRAW->nmcd.uItemState; LPARAM lParam = pNMLVCUSTOMDRAW->nmcd.lItemlParam; // next we set up flags that will control // the return value for *pResult bool bNotifyPostPaint = false; bool bNotifyItemDraw = false; bool bNotifySubItemDraw = false; bool bSkipDefault = false; bool bNewFont = false; // what we do next depends on the // drawing stage we are processing switch (pNMLVCUSTOMDRAW->nmcd.dwDrawStage) { case CDDS_PREPAINT: { // PrePaint m_pOldItemFont = NULL; m_pOldSubItemFont = NULL; bNotifyPostPaint = IsNotifyPostPaint(); bNotifyItemDraw = IsNotifyItemDraw(); // do we want to draw the control ourselves? if (IsDraw()) { if (! pDC) pDC = CDC::FromHandle(hdc); CRect r(pNMLVCUSTOMDRAW->nmcd.rc); // do the drawing if (OnDraw(pDC,r)) { // we drew it all ourselves // so don't do default bSkipDefault = true; } } } break; case CDDS_ITEMPREPAINT: { // Item PrePaint m_pOldItemFont = NULL; bNotifyPostPaint = IsNotifyItemPostPaint(nItem,nState,lParam); bNotifySubItemDraw = IsNotifySubItemDraw(nItem,nState,lParam); // set up the colors to use pNMLVCUSTOMDRAW->clrText = TextColorForItem(nItem,nState,lParam); pNMLVCUSTOMDRAW->clrTextBk = BkColorForItem(nItem,nState,lParam); // set up a different font to use, if any CFont* pNewFont = FontForItem(nItem,nState,lParam); if (pNewFont) { if (! pDC) pDC = CDC::FromHandle(hdc); m_pOldItemFont = pDC->SelectObject(pNewFont); bNotifyPostPaint = true; // need to restore font } // do we want to draw the item ourselves? if (IsItemDraw(nItem,nState,lParam)) { if (! pDC) pDC = CDC::FromHandle(hdc); if (OnItemDraw(pDC,nItem,nState,lParam)) { // we drew it all ourselves // so don't do default bSkipDefault = true; } } } break;

评论