特定对话框控件的MFC SetFont不起作用

MFC SetFont for specific dialog control not working

本文关键字:MFC SetFont 不起作用 控件 对话框      更新时间:2023-10-16

我有一个标准的MFC SDI应用程序。在关于对话框中(使用MFC向导创建),我试图改变一些静态文本格式(标签)。这是我的代码:

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
}

但是,这只会导致字体变粗体,而大小不会改变。我做错了什么?

字体变得更粗,所以CreateFont和SetFont正在做一些事情。这使得字体映射器成为下一个怀疑对象。"Arial"是一个建议,但字体映射器将首先查看其他特征。您看到的字体很可能是FW_BLACK重量中可用的最大栅格(非True Type)字体。要得到你想要的字体,需要填写CreateFont的其他参数,以便找到所需的字体。

对于调试,跟随CreateFont调用调用GetLogFont并查看数据结构以查看实际映射的字体。

上面关于字体生存期的注释是正确的。这可能不是你面临的第一个问题,但它确实是一个问题。CFont需要是一个对话框类变量,而不是函数中的局部变量,因此font对象的持续时间与对话框上的控件一样长。

看起来您并不需要CFont对象,因为您让它超出了作用域。

参见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);

lParam的低阶字指定在设置字体后是否应该立即重新绘制控件。如果该参数为TRUE,则控件将重新绘制自身。

虽然应该将对象也保存在容器中,(例如std::vector<HFONT>)并稍后删除/all对象(例如析构函数)。

应用程序应该调用DeleteObject函数来删除不再需要的字体;例如,在它破坏控件之后。