【问题标题】:MFC: Dynamically change control font size?MFC:动态更改控件字体大小?
【发布时间】:2011-11-28 20:28:43
【问题描述】:

我有一个 CListCtrl 类,我希望能够轻松更改其字体大小。我将 CListCtrl 子类化为 MyListControl。我可以在 PreSubclassWindow 事件处理程序中使用此代码成功设置字体:

void MyListControl::PreSubclassWindow()
{
    CListCtrl::PreSubclassWindow();

    // from http://support.microsoft.com/kb/85518
    LOGFONT lf;                        // Used to create the CFont.

    memset(&lf, 0, sizeof(LOGFONT));   // Clear out structure.
    lf.lfHeight = 20;                  // Request a 20-pixel-high font
    strcpy(lf.lfFaceName, "Arial");    //    with face name "Arial".
    font_.CreateFontIndirect(&lf);    // Create the font.
    // Use the font to paint a control.
    SetFont(&font_);
}

这行得通。但是,我想做的是创建一个名为 SetFontSize(int size) 的方法,它只会改变现有的字体大小(保持面部和其他特征不变)。所以我相信这种方法需要获取现有字体,然后更改字体大小,但我这样做的尝试失败了(这会杀死我的程序):

void MyListControl::SetFontSize(int pixelHeight)
{
    LOGFONT lf;                        // Used to create the CFont.

    CFont *currentFont = GetFont();
    currentFont->GetLogFont(&lf);
    LOGFONT lfNew = lf;
    lfNew.lfHeight = pixelHeight;                  // Request a 20-pixel-high font
    font_.CreateFontIndirect(&lf);    // Create the font.

    // Use the font to paint a control.
    SetFont(&font_);

}

我怎样才能创建这个方法?

【问题讨论】:

  • 这会以什么方式“杀死”你的程序?
  • 有一个 mfc ASSERT 失败。

标签: mfc fonts


【解决方案1】:

我找到了一个可行的解决方案。我愿意接受改进建议:

void MyListControl::SetFontSize(int pixelHeight)
{
    // from http://support.microsoft.com/kb/85518
    LOGFONT lf;                        // Used to create the CFont.

    CFont *currentFont = GetFont();
    currentFont->GetLogFont(&lf);
    lf.lfHeight = pixelHeight;
    font_.DeleteObject();
    font_.CreateFontIndirect(&lf);    // Create the font.

    // Use the font to paint a control.
    SetFont(&font_);
}

让它发挥作用的两个关键是:

  1. 删除 LOGFONT 的副本,lfNew。
  2. 在创建新字体之前调用font_.DeleteObject();。显然已经没有现有的字体对象了。 MFC 代码中有一些 ASSERT 检查现有指针。该 ASSERT 是导致我的代码失败的原因。

【讨论】:

  • 什么是 font_ ?它没有被声明。
  • font_ 是 CFont 类型,它是我的 MyListControl 类的成员变量。
  • font_.DeleteObject() 是真正的救星。在wingdi.cpp 中的第1113 行附近有一个断言,用于检查现有的附加对象。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多