void CGridColumnTraitText::OnCustomDraw(CGridListCtrlEx& owner, NMLVCUSTOMDRAW* pLVCD, LRESULT* pResult) { int nRow = (int)pLVCD->nmcd.dwItemSpec; switch (pLVCD->nmcd.dwDrawStage) { // Before painting a cell case CDDS_ITEMPREPAINT | CDDS_SUBITEM: { // Remove the selection color for the focus cell, to make it easier to see focus int nCol = pLVCD->iSubItem; if (pLVCD->nmcd.uItemState & CDIS_SELECTED && owner.GetFocusCell()==nCol && owner.GetFocusRow()==nRow) { pLVCD->nmcd.uItemState &= ~CDIS_SELECTED; } if (!owner.IsRowSelected(nRow) && owner.GetHotItem()!=nRow) { if (UpdateTextColor(pLVCD->clrText)) *pResult |= CDRF_NEWFONT; if (UpdateBackColor(pLVCD->clrTextBk)) *pResult |= CDRF_NEWFONT; // Only change cell colors when not selected / in focus if (owner.OnDisplayCellColor(nRow, nCol, pLVCD->clrText, pLVCD->clrTextBk)) *pResult |= CDRF_NEWFONT; } LOGFONT newFont = {0}; if (owner.OnDisplayCellFont(nRow, nCol, newFont)) { CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc); CFont* pNewFont = new CFont; VERIFY( pNewFont->CreateFontIndirect(&newFont) ); m_pOldFont = pDC->SelectObject(pNewFont); *pResult |= CDRF_NOTIFYPOSTPAINT; // We need to restore the original font *pResult |= CDRF_NEWFONT; } } break; // After painting a cell case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: { if (m_pOldFont!=NULL) { // Restore the original font CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc); CFont* pNewFont = pDC->SelectObject(m_pOldFont); delete pNewFont; } } break; } }
//------------------------------------------------------------------------ //! Overrides the custom draw handler, to allow custom coloring of rows. //! - Fix white background for icon images //! - Fix white background between icon and cell text //! //! @param owner The list control drawing //! @param pLVCD Pointer to NMLVCUSTOMDRAW structure //! @param pResult Modification to the drawing stage (CDRF_NEWFONT, etc.) //------------------------------------------------------------------------ void CGridRowTraitXP::OnCustomDraw(CGridListCtrlEx& owner, NMLVCUSTOMDRAW* pLVCD, LRESULT* pResult) { if (owner.UsingVisualStyle()) { // Perform standard drawing CGridRowTraitText::OnCustomDraw(owner, pLVCD, pResult); return; } // We are using classic- or XP-style int nRow = (int)pLVCD->nmcd.dwItemSpec; // Repair the standard drawing switch (pLVCD->nmcd.dwDrawStage) { case CDDS_ITEMPREPAINT | CDDS_SUBITEM: { // We want to fix cell images *pResult |= CDRF_NOTIFYPOSTPAINT; } break; case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: { // Fix CListCtrl selection drawing bug with white background for icon image // Fix CListCtrl selection drawing bug with white margin between icon and text int nCol = pLVCD->iSubItem; if (CRect(pLVCD->nmcd.rc)==CRect(0,0,0,0)) break; int nImage = owner.GetCellImage(nRow, nCol); if (nImage == I_IMAGECALLBACK) break; CImageList* pImageList = owner.GetImageList(LVSIL_SMALL); if (pImageList==NULL) break; COLORREF backColor = COLORREF(-1); if (owner.GetExtendedStyle() & LVS_EX_TRACKSELECT && owner.GetHotItem()==nRow) { #if(WINVER >= 0x0500) backColor = ::GetSysColor(COLOR_HOTLIGHT); #else if (owner.IsRowSelected(nRow)) backColor = ::GetSysColor(COLOR_HIGHLIGHT); else break; #endif } else if (owner.IsRowSelected(nRow)) { if (!(owner.GetExtendedStyle() & LVS_EX_FULLROWSELECT)) break; // No drawing of selection color without full-row-select if (m_InvertCellSelection && owner.GetFocusRow()==nRow && owner.GetFocusCell()==nCol) { // No drawing of selection color for focus cell if (pLVCD->clrTextBk > RGB(255,255,255)) break; backColor = pLVCD->clrTextBk; } else { if (owner.GetFocus()!=&owner && !owner.IsCellEditorOpen()) { // Selection color is different when not having focus if (owner.GetStyle() & LVS_SHOWSELALWAYS) backColor = ::GetSysColor(COLOR_BTNFACE); else break; // no drawing of selection color when not in focus } else { backColor = ::GetSysColor(COLOR_HIGHLIGHT); } } } else { // Redraw with the given background color if (pLVCD->clrTextBk > RGB(255,255,255)) break; // If a color is more than white, then it is invalid backColor = pLVCD->clrTextBk; } CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc); CRect rcIcon, rcCell; VERIFY( owner.GetCellRect(nRow, nCol, LVIR_ICON, rcIcon) ); VERIFY( owner.GetCellRect(nRow, nCol, LVIR_BOUNDS, rcCell) ); // When the label column is placed first it has a left-margin if (nCol==0 && nCol==owner.GetFirstVisibleColumn()) { int cxborder = ::GetSystemMetrics(SM_CXBORDER); rcCell.left += cxborder*2; } // Remove white margin between cell-image and cell-text rcCell.right = rcIcon.right + 2; CBrush brush(backColor); pDC->FillRect(&rcCell, &brush); // Draw icon COLORREF oldBkColor = pImageList->SetBkColor(backColor); pImageList->Draw ( pDC, nImage, rcIcon.TopLeft(), ILD_NORMAL ); pImageList->SetBkColor(oldBkColor); if (nCol==0 && owner.GetExtendedStyle() & LVS_EX_CHECKBOXES) { CImageList* pStateImageList = owner.GetImageList(LVSIL_STATE); if (pImageList==NULL) break; int checkState = owner.GetCheck(nRow); COLORREF oldStateBkColor = pStateImageList->SetBkColor(backColor); pStateImageList->Draw ( pDC, checkState, rcCell.TopLeft(), ILD_NORMAL ); pStateImageList->SetBkColor(oldStateBkColor); } } break; } // Perform standard drawing CGridRowTraitText::OnCustomDraw(owner, pLVCD, pResult); }