Unable to use CMFCButton::SelectFont in derived CMFCLinkCtrl class

ChuckieAJ 201 Reputation points
2025-02-07T14:09:18.95+00:00

I have an odd conundrum! The CMFCLinkCtrl class does not expose the font colour properties because it uses GetGlobalData information. That's not OK when using dark mode. Besides, it is a handicap and makes the class less useful.

I delved into the source code for this class (afxlinkctrl.cpp) and tried to roll my own tweaked version:

	void CDarkModeMFCLinkCtrl::OnDraw(CDC* pDC, const CRect& rect, UINT uiState)
	{
		if (!IsUsingDarkMode())
		{
			// Call base implementation
			__super::OnDraw(pDC, rect, uiState);
		}

		ASSERT_VALID(pDC);
	
		// Set font:
		CFont* pOldFont = NULL;
	
		if (m_bAlwaysUnderlineText || m_bHover)
		{
			pOldFont = pDC->SelectObject(&(GetGlobalData()->fontDefaultGUIUnderline));
		}
		else
		{
			// pOldFont = CMFCButton::SelectFont(pDC);
			if (m_hFont != NULL && ::GetObjectType(m_hFont) != OBJ_FONT)
			{
				m_hFont = NULL;
			}

			pOldFont = m_hFont == NULL ? (CFont*)pDC->SelectStockObject(DEFAULT_GUI_FONT) : pDC->SelectObject(CFont::FromHandle(m_hFont));
		}
	
		ENSURE(pOldFont != NULL);
	
		// Set text parameters:
		// Replace the 
		// pDC->SetTextColor(m_bHover ? GetGlobalData()->clrHotLinkHoveredText : (m_bVisited ? GetGlobalData()->clrHotLinkVisitedText : GetGlobalData()->clrHotLinkNormalText));
		auto crHovered = RGB(0, 122, 204);
		auto crNormal = DarkModeTools::darkTextColor;
		auto crVisited = DarkModeTools::darkTextColor;

		pDC->SetTextColor(m_bHover ? crHovered : (m_bVisited ? crVisited : crNormal));
		pDC->SetBkMode(TRANSPARENT);
	
		// Obtain label:
		CString strLabel;
		GetWindowText(strLabel);
	
		CRect rectText = rect;
		pDC->DrawText(strLabel, rectText, m_bMultilineText ? DT_WORDBREAK : DT_SINGLELINE);
	
		pDC->SelectObject(pOldFont);
	}

I had to comment out the line pOldFont = CMFCLinkCtrl::SelectFont(pDC); and add the manual code. It generated compile errors:

DarkModeMFCLinkCtrl.cpp(57,27): warning C4003: not enough arguments for function-like macro invocation 'SelectFont'
DarkModeMFCLinkCtrl.cpp(57,27): error C2589: '(': illegal token on right side of '::'
DarkModeMFCLinkCtrl.cpp(57,27): error C2275: 'HFONT': expected an expression instead of a type
DarkModeMFCLinkCtrl.cpp(57,27): error C2146: syntax error: missing ';' before identifier 'SelectObject'
DarkModeMFCLinkCtrl.cpp(57,27): error C2059: syntax error: ')'

I don't understand why I had to do this. I have included afxbutton.h in my file, and the SelectFont is a valid virtual function.

Header:

virtual CFont* SelectFont(CDC* pDC);

Source:

CFont* CMFCButton::SelectFont(CDC* pDC)
{
	ASSERT_VALID(pDC);

	if (m_hFont != NULL && ::GetObjectType(m_hFont) != OBJ_FONT)
	{
		m_hFont = NULL;
	}

	CFont* pOldFont = m_hFont == NULL ? (CFont*) pDC->SelectStockObject(DEFAULT_GUI_FONT) : pDC->SelectObject(CFont::FromHandle(m_hFont));

	ENSURE(pOldFont != NULL);
	return pOldFont;
}

My class header:

namespace DarkModeTools
{
	// CDarkModeMFCLinkCtrl
	
	class CDarkModeMFCLinkCtrl : public CMFCLinkCtrl, public CDarkModeBase
	{
		DECLARE_DYNAMIC(CDarkModeMFCLinkCtrl)
	
	public:
		CDarkModeMFCLinkCtrl();
		virtual ~CDarkModeMFCLinkCtrl();
	
	protected:
		DECLARE_MESSAGE_MAP()
	public:
		virtual void OnDraw(CDC* pDC, const CRect& rect, UINT uiState);
	};
}

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,857 questions
{count} votes

Accepted answer
  1. RLWA32 47,206 Reputation points
    2025-02-07T15:58:59.8+00:00

    Sounds like there is a SelectFont macro that conflicts with the function declaration.

    Have you tried #undef SelectFont?

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.