【问题标题】:delete font created by CreateFont删除 CreateFont 创建的字体
【发布时间】:2013-01-02 15:35:14
【问题描述】:

如果我使用 CreateFont() 创建字体(作为非静态变量)并使用 SelectObject 在函数中使用它,那么在退出该函数之前,我必须选择前一个对象并使用 DeleteObject 删除字体。

但是如果我声明一个全局变量HFONT gFont = CreateFont(...),那么在WM_DESTROY消息中,我应该调用DeleteObject来删除字体吗?

同样在这种情况下,如果我在函数中使用hOldFont = SelectObject(memDC, gFont);,我应该在退出该函数之前调用SelectObject(memDC, hOldFont);吗?在我看来,对于 Bitmap,我们应该这样做清理,但我不知道这是否适用于其他 GDI 对象。

【问题讨论】:

  • 是的。当您知道应该恢复设备上下文时故意不恢复是非常不明智的。这是未定义的行为,没有记录的结果,使用后果自负。
  • 谢谢。而对于DeleteObject,你有什么意见吗?
  • 当您不再需要该字体时将其删除。

标签: winapi fonts bitmap gdi+ gdi


【解决方案1】:

将每个DeviceContext (DC) 视为画布。对于每个type,每个画布一次只能有一个活动的GDI 对象。因此,您可以为该画布选择一个BrushPenFont 等作为活动

当您调用SelectObject() 时,您正在设置该类型的活动对象。把它想象成“拿起红笔画画,然后拿起蓝笔画画”。如果 GDI 函数采用Pen(例如Rectangle),它将使用最后通过SelectObject 选择的笔。这就是为什么SelectObject 返回之前的值,以便您可以存储它以在完成后恢复状态。

您应该始终在您不再需要的任何已创建 GDI 对象上使用DestroyObject。此外,对于每个 CreateDC 呼叫,您应该始终使用 DeleteDC,对于每个 GetDC 呼叫(当您不再需要 DC 时)使用 ReleaseDC

最好将DeviceContext (DC) 恢复为您找到它的方式。所以如果你设置了Font或者Brush,你应该在返回之前把它恢复到原来的值。唯一不重要的恢复是当您无论如何都要处理 DC 时,可能是临时的Bitmap

如果您使用GetStockObject,则无需致电DeleteObject

【讨论】:

  • 谢谢。所以如果我使用全局字体(在应用程序运行时一直使用),我仍然需要删除 WM_DESTROY 中的字体,对吧?
  • 是的,如果你使用CreateFont创建它,你应该使用DestroyObject释放它。但是,您不必担心SelectObject,因为您的应用程序的 DC 很快就会被销毁。
  • 但不要删除仍被选入 DC 的对象。如果您对 DC 进行了大量调整,则使用 SaveDCRestoreDC 可能是一种更简单的管理方法。
  • 好点@AdrianMcCarthy,如果您有多个使用共享对象的 DC,只有在没有其他 DC 使用它时才调用 DeleteObject(自从我使用 GDI 以来已经有一段时间了) .
  • @SiLo:对于某些 GDI 对象(例如位图),您永远不应该将它们同时选择到两个不同的 DC 中。 (库存对象可能是安全的。)在删除 DC 之前,从 DC 中选择这些对象很重要。
【解决方案2】:

一个 Delphi (Pascal) 示例:

Procedure AngleTextOut(hDC: THandle; const sTxt: string; iX, iY, iH, iAngle: integer);
var
    aryC: array[0..255] of Char;
    hFont, hFontOld: THandle;
begin
    StrPCopy(aryC, sTxt);
    hFont:= CreateFont(-iH, 0, iAngle *10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'arial');
    hFontOld:= SelectObject(hDC, hFont);
    TextOut(hDC, iX, iY, aryC, StrLen(aryC));
    SelectObject(hDC, hFontOld);
    DeleteObject(hFont);
end;//  AngleTextOut

【讨论】:

    猜你喜欢
    • 2019-12-19
    • 2018-06-03
    • 2018-10-18
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多