I modified the example CGXIconControl to allow it to draw text as well as the icon. It works well, except that when the control refreshes - say when I select the column, my text disappears.

It seems like an InvalidateRect problem. If I refresh the grid, or drag it off screen and back again, the text is redrawn - but soon disappears again.

What do I need to do to make my DrawText permanent? Code below

Code:
//------------------------------------------------------------------------------
void CGXIconControl::Draw(CDC* pDC, CRect rect, ROWCOL nRow, ROWCOL nCol, const CGXStyle& style, const CGXStyle* pStandardStyle)
//------------------------------------------------------------------------------
{
	BOOL b;

	ASSERT(pDC != NULL && pDC->IsKindOf(RUNTIME_CLASS(CDC)));
	// ASSERTION-> Invalid Device Context ->END
	ASSERT(nRow <= Grid()->GetRowCount() && nCol <= Grid()->GetColCount());
	// ASSERTION-> Cell coordinates out of range ->END
	ASSERT_VALID(pDC);
	DrawBackground(pDC, rect, style);
	pDC->SetBkMode(TRANSPARENT);

	if (rect.right <= rect.left || rect.Width() <= 1 || rect.Height() <= 1)
	{
		return;
	}
	CString str = style.GetIncludeValue() ? style.GetValue() : _T("");

	CString sTxtBefore = _T("");
	CString sTxtAfter = _T("");

	int nHAlign = style.GetHorizontalAlignment();
	int nVAlign = style.GetVerticalAlignment();

	// Save these value to restore them when done drawing
	COLORREF crOldTextColor = pDC->GetTextColor();
	COLORREF crOldBkColor = pDC->GetBkColor();

	if (!style.GetEnabled())
	{
		pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
	}

	CBrush Brush;
	Brush.CreateSolidBrush(style.GetEnabled() ? ::GetSysColor(COLOR_WINDOWTEXT) : ::GetSysColor(COLOR_GRAYTEXT));
	LOGBRUSH lBrush = { 0 };
	Brush.GetLogBrush(&lBrush);
	CBrush* pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);

	CPen linePen;
	linePen.CreatePen(PS_SOLID, 1, &lBrush);
	CPen* pOldPen = pDC->SelectObject(&linePen);

	// Set font bold if necessary
	CFont* pCurfont = pDC->GetCurrentFont();
	LOGFONT lf;
	CFont font;
	if (pCurfont)
	{
		pCurfont->GetLogFont(&lf);
	}

	if (style.GetFont().GetBold())
	{
		lf.lfWeight = FW_BOLD;
	}
	font.CreateFontIndirect(&lf);
	CFont* pOldFont = pDC->SelectObject(&font);

	int nIcoStart = str.Find(_T("#ICO"));
	if (nIcoStart == -1)
	{
		// We didn't find an icon indicator, so just draw the text
		pDC->DrawText(str, rect, DT_SINGLELINE|nHAlign|nVAlign);
	}
	else
	{
		sTxtBefore = str.Left(nIcoStart);
		CSize szBefore = pDC->GetTextExtent(sTxtBefore);

		int nIconEnd = str.Find(_T(")"), nIcoStart);
		CString strIDResource = str.Mid(nIcoStart + 5, nIconEnd - (nIcoStart + 5));
		UINT nIDResource = _ttoi(strIDResource);

		// Load the highest bit-depth available
		HICON hIcon = NULL;
		hIcon = LoadResourceIcon(nIDResource, m_nIconSize, m_nIconSize, 32);
		hIcon == NULL ? LoadResourceIcon(nIDResource, m_nIconSize, m_nIconSize, 24) : NULL;
		hIcon == NULL ? LoadResourceIcon(nIDResource, m_nIconSize, m_nIconSize, 16) : NULL;
		hIcon == NULL ? LoadResourceIcon(nIDResource, m_nIconSize, m_nIconSize, 8) : NULL;

		sTxtAfter = str.Right(str.GetLength() - nIconEnd - 1);
		CSize szAfter = pDC->GetTextExtent(sTxtAfter);

		CRect rectCell = CGXControl::GetCellRect(nRow, nCol, rect, &style);
		CRect rectBefore = rectCell;
		CRect rectAfter = rectCell;
		int nTotalWidth = szBefore.cx + m_nIconSize + szAfter.cx;

		// Calculate positions
		int nTop, nLeft;

		switch (nHAlign)
		{
			case DT_LEFT:
			{
				rectBefore.right = rectBefore.left + szBefore.cx;
				nLeft = rectBefore.right;
				rectAfter.left = nLeft + m_nIconSize;
				rectAfter.right = rectAfter.left + szAfter.cx;
			} break;

			case DT_CENTER:
			{
				rectBefore.left = (rectCell.right - rectCell.Width() / 2) - nTotalWidth / 2;
				rectBefore.right = rectBefore.left + szBefore.cx;

				nLeft = rectBefore.right;

				rectAfter.left = nLeft + m_nIconSize;
				rectAfter.right = rectAfter.left + szAfter.cx;
			} break;

			case DT_RIGHT:
			{
				// Work from the right
				rectAfter.right = rectCell.right;
				rectAfter.left = rectAfter.right - szAfter.cx;
				nLeft = rectAfter.left - m_nIconSize;
				rectBefore.right = nLeft;
				rectBefore.left = rectBefore.right - szBefore.cx;
			} break;
		}

		switch (nVAlign)
		{
			case DT_TOP:
				nTop = rectCell.top;
				break;

			case DT_VCENTER:
				nTop = rectCell.top + (rectCell.Height() / 2 - m_nIconSize / 2);
				break;

			case DT_BOTTOM:
				nTop = rectCell.bottom - m_nIconSize;
				break;
		}

		if (!sTxtBefore.IsEmpty())
		{
			pDC->DrawText(sTxtBefore, rectBefore, DT_SINGLELINE|nHAlign|nVAlign);
		}

		b = ::DrawIconEx(pDC->m_hDC, nLeft, nTop, hIcon, m_nIconSize, m_nIconSize, 0, NULL, DI_NORMAL);
		b = ::DestroyIcon(hIcon);

		if (!sTxtAfter.IsEmpty())
		{
			pDC->DrawText(sTxtAfter, rectAfter, DT_SINGLELINE|nHAlign|nVAlign);
		}
	}

	// Reset original values
	pDC->SetTextColor(crOldTextColor);
	pDC->SetBkColor(crOldBkColor);
	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pOldFont);

	// Child Controls: spin-buttons, hotspot, combobox btn, ...
	CGXControl::Draw(pDC, rect, nRow, nCol, style, pStandardStyle);
}