我想将 CListCtrl 的标题 (CHeaderCtrl) 设为粗体。我不想开发自己的字体,因为我想尊重系统默认字体,而每台计算机上的字体都不同。我只想将默认字体设为粗体。可以吗?以下代码会抛出错误:

Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!

Program: C:\Windows\SYSTEM32\mfc140ud.dll
File: D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\wingdi.cpp
Line: 1113

在线:m_headerFont.CreateFontIndirect(&lf); – 参见下图。

断点时刻的 lf 的值是:

   lfHeight: -12
   lfWidth: 0
   lfEscapement: 0
   lfOrientation: 0
   lfWeight: 700
   lfItalic: 0 '\0'
   lfUnderline: 0 '\0'
   lfStrikeOut: 0 '\0'
   lfCharSet: 1 '\x1'
   lfOutPrecision: 0 '\0'
   lfClipPrecision: 0 '\0'
   lfQuality: 0 '\0'
   lfPitchAndFamily: 0 '\0'
   lfFaceName: 0x00000004b38fc8cc L"Segoe UI"

代码示例:

class CMFCtestDlg : public CDialogEx
{
    CFont m_headerFont;
    //....
    //...
    BOOL OnInitDialog();
}

BOOL CMFCtestDlg::OnInitDialog()
{
    //.......
    //.......
    CFont *pDefaultFont = pHeaderCtrl->GetFont();
    LOGFONT lf{0};
    if(pDefaultFont != nullptr && pDefaultFont->GetLogFont(&lf))
    {
        // If the font is MS Shell Dlg, use SystemParametersInfo to get the system font
        if(_tcscmp(lf.lfFaceName, _T("MS Shell Dlg")) == 0)
        {
            if(SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0))
            {
                lf.lfWeight = FW_BOLD;
                m_headerFont.CreateFontIndirect(&lf);
                pHeaderCtrl->SetFont(&m_headerFont);
            }
        }
    }
}

5

  • 请将断言失败作为文本发布在另一个代码块中,您可以获取调试输出中的文本或使用键盘快捷键从对话框中复制它。


    – 

  • CGdiObject::Attach()断言失败是因为传递给函数(CFont继承自CGdiObject的 GDI 对象句柄是(检查wingdi.cppNULL中的第 1113 行)。这是因为先前对 Win32 的调用失败了。NULLCreateFontIndirect()


    – 

  • 谢谢,但为什么是 NULL?我在问题中添加了有关 lf 的更多详细信息。可能是因为字体 lf 是系统字体吗?


    – 

  • @MichalHadraba 这只是您的重复,之前的问题因缺乏细节而被关闭。如果您有更多信息要添加,您应该编辑该问题以便重新打开。现在太晚了,但请记住这一点,以便以后提问。


    – 

  • 很抱歉。我不知道它可以重新开放。


    – 



最佳答案
1

好吧,我上面的评论是错误的,我认为它失败了,因为它无法使用您传递的参数创建字体。但原因是该m_headerFont对象此时已经包含一个有效的字体句柄。您正在重复使用该对象,但CFont::CreateFontIndirect()调用了CGdiObject::Attach(),它“断言”该对象为“空”(m_hObject==NULL)。因此,您必须使用另一个对象或在调用之前CFont清除m_headerFontCreateFontIndirect()

    .
    .
    DeleteObject(m_headerFont.Detach()); // detach and delete the old HFONT
    m_headerFont.CreateFontIndirectW(&lf);
    .
    .

1

  • 太棒了!谢谢。


    –