2
votes

I have a standard MFC SDI app. In the About Dialog (created with the MFC Wizard), I am trying to change some static text format (labels). This is my code:

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

    auto font_programname = std::make_shared<CFont>();
    font_programname->CreateFontW(25, 0, 0, 0, FW_BLACK, 0, 1, 0, 0, 0, 0, 0, 0, _T("Arial"));
    _label_programname.SetFont(font_programname.get());

    return TRUE;  // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
}

However, this results only in the font becoming bold, but the size does not change. What am I doing wrong?

2
Are you sure 25 is a valid value? Does CreateFontW return 0? - o_weisman
Another thing: According to the MS documentation, you should not pass a Font object that may be destroyed before the label is destroyed (link here: support.microsoft.com/en-us/kb/85518) . You should make font_programname a class member in CAboutDlg. - o_weisman
@o_weisman it returns 1 - manatttta
Well then, how about my second suggestion? - o_weisman
@o_weisman tried out with a raw pointer for debugging, same output! thank you anyway! - manatttta

2 Answers

1
votes

The font is becoming bolder, so the CreateFont and SetFont are doing something. This leaves the Font Mapper as the next suspect. The "Arial" is a suggestion, but the font mapper will look at other characteristics first. The font you are seeing is most likely the largest raster (non True Type) font that is available in an FW_BLACK weight. Getting the exact font you want will require filling in other parameters of CreateFont so the desired font is located.

For debugging, follow the CreateFont call with a call to GetLogFont and view the data structure to see what font was actually mapped.

The comment above concerning the lifetime of the font is correct. That may not be the first issue you are facing but it is an issue. The CFont needs to be a dialog-class variable, not a local variable in the function, so the font object lasts as long as the control on the dialog.

1
votes

It does look like you do not need a CFont object for your purposes, as you let it go out of scope.

Also see WM_SETFONT.

const int iFontSize = 25;
const CString sFont = L"Arial";

HFONT hFont = CreateFontW(iFontSize, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, sFont);
yourControl.SendMessageW(WM_SETFONT, reinterpret_cast<WPARAM>(hFont), TRUE);

The low-order word of lParam specifies whether the control should be redrawn immediately upon setting the font. If this parameter is TRUE, the control redraws itself.

Though you should keep the object(s) in a container too, (E.g. std::vector<HFONT>) and delete the/all object(s) later (destructor).

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