0

My problem is that the font in the text won't show up as the font that I want it to be. I looked up the issue but I didn't see any solutions. The text is the "Sign In"

BOOL Account::OnInitDialog() {
    CDialogEx::OnInitDialog();

    CFont font;
    VERIFY(font.CreatePointFont(160, _T("Arial")));
    SignInStatic.SetFont(&font);
    font.DeleteObject();

    return TRUE;
}

The Sign In Text

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Abdu
  • 135
  • 8
  • Possible duplicate of [How to get Win32 to use Windows XP style fonts](https://stackoverflow.com/questions/3029573/how-to-get-win32-to-use-windows-xp-style-fonts) – lost_in_the_source Nov 24 '18 at 00:44
  • 1
    Your function works, but you are immediately destroying the font with `font.DeleteObject()`. Declare `CFont font;` as a member of `Account` dialog class and don't call `font.DeleteObject()`. That way the font will be destroyed when the instance of `Account` dialog is destroyed. – Barmak Shemirani Nov 24 '18 at 01:56
  • Thx you solved it. Any reason why I had to change font.SetFont(&font) to GetDlgItem(SignInText)->SetFont(&font); – Abdu Nov 24 '18 at 02:12

1 Answers1

3

When you call CWnd::SetFont(), the window you assigned the font to does not take ownership of the font. You are responsible to delete the font, but only when it is no longer in use.

As often, the documentation of the underlying Windows API, which is WM_SETFONT, provides more information than the MFC documentation:

The application should call the DeleteObject function to delete the font when it is no longer needed; for example, after it destroys the control.

As you are using the CFont class, you don't have to explicitly call DeleteObject(). CFont is a RAII class that automatically destroys its associated resource in its destructor.

All you have to care about is the scope of the CFont instance. Currently you create a local variable of CFont in the OnInitDialog method. Even when you remove the explicit DeleteObject call, the font will be destroyed when OnInitDialog returns and the window you assigned the font to now refers to an invalid font handle.

Solution

Declare an instance of CFont as a member variable of the Account class:

class Account : public CDialogEx
{
public:
    // Some stuff
private:
    CFont m_signInFont;
};

In OnInitDialog you have to use the member variable instead of the local variable and remove the DeleteObject call:

BOOL Account::OnInitDialog() {
    CDialogEx::OnInitDialog();

    VERIFY(m_signInFont.CreatePointFont(160, _T("Arial")));
    SignInStatic.SetFont(&m_signInFont);

    return TRUE; 
}

Now the font object will exist for the whole livetime of the dialog, which includes its children. You could even assign it to other children, as needed.

zett42
  • 25,437
  • 3
  • 35
  • 72