1

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

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

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

4

2 回答 2

3

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

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

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

最佳做法是将DeviceContext(DC) 恢复为您找到它的方式。因此,如果您设置Fontor Brush,您应该在返回之前将其恢复为原始值。唯一不重要的恢复是当您无论如何都要处理 DC 时,也许是临时的Bitmap.

如果你使用GetStockObject,你不需要调用DeleteObject

于 2013-01-18T20:46:10.753 回答
1

德尔福(帕斯卡)示例:

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
于 2018-08-29T16:45:02.640 回答