设置MFC对话框控件字体粗细的函数包装

huangapple go评论56阅读模式
英文:

Function to wrap setting the font weight on an MFC dialog control

问题

我有一个C++类,它继承自MFC的CStatic类,用于在MFC对话框上显示静态文本。我想要在该类中添加一个方法,允许我选择字体的粗细。我不太理解CFonts和LOGFONTs之间的关系,以及何时创建它们和销毁它们。以下是我的第一次尝试:

HRESULT CPVCtrlFontStatic2::SetWeight(long weight)
{
    // 获取控件的当前字体
    CFont* pFont = GetFont();
    
    // 从当前字体获取逻辑字体对象
    LOGFONT lf;
    pFont->GetLogFont(&lf);
    
    // 设置所需的字体粗细
    lf.lfWeight = weight;
    
    // 创建一个新的字体对象
    pFont->CreateFontIndirect(&lf);
    
    // 告诉控件使用新字体
    SetFont(pFont);
    
    return S_OK;
}

当我运行这段代码时,Windows在调用CreateFontIndirect()时崩溃,因为字体对象的m_hObject值不是NULL。看起来我需要创建一个新的CFont对象。但是如果我将其创建在栈上,它不会在超出作用域时消失吗?或者控件正在使用它会使它保留在内存中吗?如果我使用new动态创建它,那么我就必须管理它的生命周期,这会增加我不想要的复杂性。正确的做法是什么?

【注意】:为了保持代码的完整性,我已经将代码部分翻译出来了,但我理解你只需要代码的翻译部分。以下是代码的翻译:

我有一个继承自MFC `CStatic` 类的C++类,用于在MFC对话框上显示静态文本。我想要在该类中添加一个方法,允许我选择字体的粗细。我不太理解CFonts和LOGFONTs之间的关系,以及何时创建它们和销毁它们。以下是我的第一次尝试:

```cpp
HRESULT CPVCtrlFontStatic2::SetWeight(long weight)
{
    // 获取控件的当前字体
    CFont* pFont = GetFont();
    
    // 从当前字体获取逻辑字体对象
    LOGFONT lf;
    pFont->GetLogFont(&lf);
    
    // 设置所需的字体粗细
    lf.lfWeight = weight;
    
    // 创建一个新的字体对象
    pFont->CreateFontIndirect(&lf);
    
    // 告诉控件使用新字体
    SetFont(pFont);
    
    return S_OK;
}

当我运行这段代码时,Windows在调用CreateFontIndirect()时崩溃,因为字体对象的m_hObject值不是NULL。看起来我需要创建一个新的CFont对象。但是如果我将其创建在栈上,它不会在超出作用域时消失吗?或者控件正在使用它会使它保留在内存中吗?如果我使用new动态创建它,那么我就必须管理它的生命周期,这会增加我不想要的复杂性。正确的做法是什么?


<details>
<summary>英文:</summary>

I have a C++ class that derives from the MFC `CStatic` class, for displaying static text on MFC dialogs.  I want to add a method to that class that will let me choose the font weight.  I don&#39;t understand the relationship between CFonts and LOGFONTs, and when to create them and destroy them.  Here&#39;s my first attempt:

    HRESULT CPVCtrlFontStatic2::SetWeight(long weight)
    {
    	// Get the control&#39;s current font
    	CFont* pFont = GetFont();
    
    	// Get a logical font object from the current font
    	LOGFONT lf;
    	pFont-&gt;GetLogFont(&amp;lf);
    
    	// Set the desired weight
    	lf.lfWeight = weight;
    
    	// Create a new font object
    	pFont-&gt;CreateFontIndirect(&amp;lf);
    
    	// Tell the control to use the new font.
    	SetFont(pFont);
    
    	return S_OK;
    }

When I run this, Windows crashes in the call to `CreateFontIndirect()` because the font object&#39;s `m_hObject` value is not `NULL`.  It seems I need to create a new `CFont` object.  But if I create it on the stack, it will disappear as soon as it goes out of scope, won&#39;t it?  Or will the fact that the control is using it keep it in memory?  If I create it dynamically using new, then I have to manage its lifetime, adding complication I don&#39;t want.  What is the correct way to do this?

</details>


# 答案1
**得分**: 3

[CFont 的文档](https://learn.microsoft.com/en-us/cpp/mfc/reference/cfont-class?view=msvc-170#cfont)没有描述它的析构函数,但几乎可以肯定它声明对其包含的 `HFONT` 拥有权,并在适当的时候销毁它。所以是的,您需要控制该 `CFont` 对象的生命周期。

在您的派生静态类中放置一个 `CFont` 成员对象并使用它。

```C++
// 创建一个新的字体对象
m_font.CreateFontIndirect(&amp;lf);

// 告诉控件使用新的字体。
SetFont(&amp;m_font);
英文:

The documentation for CFont does not describe the destructor, but it almost certainly claims ownership of the HFONT that it contains and destroys it at that time. So yes, you need to control the lifetime of that CFont object.

Put a CFont member object in your derived static class and use that.

// Create a new font object
m_font.CreateFontIndirect(&amp;lf);

// Tell the control to use the new font.
SetFont(&amp;m_font);

huangapple
  • 本文由 发表于 2023年5月25日 04:19:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76327139.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定