当控件的父窗口被销毁时,是否有必要显式恢复控件字体?

Is it necessary to explicitly restore a control font when its parent window is destroyed?

本文关键字:控件 恢复 字体 是否 窗口      更新时间:2023-10-16

我在我的windows创建方法

中使用了以下代码
HANDLE hFont = ::GetStockObject(DEFAULT_GUI_FONT);
m_InfoTab.SendMessage(WM_SETFONT, (WPARAM)hFont);

m_InfoTab是一个标准的Windows/MFC选项卡控件。是否有必要保存原来的字体和恢复它时,父窗口被破坏?

不需要恢复原字体。然而,你自己负责管理字体对象,也就是说,当它不再使用时删除它。WM_SETFONT的文档在这里相当明确:

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

在本例中,您不会遇到任何问题,因为您通过调用GetStockObject()来检索字体对象。这些对象由系统控制,不需要对它们调用DeleteObject(尽管它也没有害处)。

应用程序是否泄漏GDI句柄可以使用任务管理器轻松验证。转到Processes选项卡,选择View -> select Columns…并勾选GDI对象。监视就绪后,更改代码并使用SetTimer()uElapsed = 1000安装计时器(每秒一次)。使用以下代码添加OnTimer处理程序:

void CMyDialog::OnTimer(UINT_PTR nIDEvent)
{
    // Retrieve the system font
    HFONT hFontSystem = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
    LOGFONT lfSystem = { 0 };
    GetObject( hFontSystem, sizeof( lfSystem ), &lfSystem );
    // And construct and identical font object
    HFONT hFontNew = CreateFontIndirect( &lfSystem );
    // This will leak the font object
    m_InfoTab.SendMessage( WM_SETFONT, (WPARAM)hFontNew );
    __super::OnTimer(nIDEvent);
}

现在打开任务管理器,启动应用程序并观察GDI对象计数每秒增加1。

不,所讨论的窗口(m_infoTab)负责管理其字体,并在必要时释放旧的字体。