删除CreateFont创建的字体

时间:2013-01-18 20:33:33

标签: winapi fonts bitmap gdi+ gdi

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

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

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

2 个答案:

答案 0 :(得分:3)

将每个DeviceContext(DC)视为画布。这些画布中的每一个一次只能为每个类型提供一个活动的 GDI对象。因此,您可以为该画布选择一个BrushPenFont活动

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

您应该始终在任何不再需要的已创建GDI对象上使用DestroyObject。此外,对于每{{}}}次来电,您应始终使用DeleteDC;对于每次CreateDC来说,您应始终使用ReleaseDC(当您不再需要DC时)。

最佳做法是将GetDC(DC)恢复为您找到它的方式。因此,如果您设置DeviceContextFont,则应在返回之前将其恢复为原始值。恢复并不重要的唯一时间是当你即将处置DC时,也许是在临时Brush的情况下。

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

答案 1 :(得分:1)

一个Delphi(帕斯卡)示例:

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