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;
	}
}
Esempio n. 2
0
//------------------------------------------------------------------------
//! 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);
}