删除CreateFont创建的字体

问题描述 投票:1回答:2

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

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

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

winapi fonts bitmap gdi+ gdi
2个回答
3
投票

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

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

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

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

如果你使用GetStockObject,你不需要打电话给DeleteObject


1
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.