Winapi 删除CreateFont创建的字体

Winapi 删除CreateFont创建的字体,winapi,fonts,bitmap,gdi+,gdi,Winapi,Fonts,Bitmap,Gdi+,Gdi,如果我使用CreateFont()创建字体(作为非静态变量)并使用SelectObject在函数中使用它,那么在退出该函数之前,我必须选择上一个对象并使用DeleteObject删除字体 但是如果我声明了一个全局变量HFONT gFont=CreateFont(…),那么在WM\u DESTROY消息中,我应该调用DeleteObject来删除字体吗 同样在这种情况下,如果我使用hOldFont=SelectObject(memDC,gFont)在函数中,我是否应该调用SelectObject(

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

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


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

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

调用
SelectObject()
时,您正在设置该类型的活动对象。可以将其视为“拿起红色笔进行绘制,然后拿起蓝色笔进行绘制”。如果GDI函数使用
(例如
矩形
),它将通过
选择对象
使用最后选择的笔。这就是为什么
SelectObject
返回上一个值,以便在完成恢复状态时存储它

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

最佳做法是将
设备上下文
(DC)还原为您找到它的方式。因此,如果设置了
字体
画笔
,则应在返回之前将其还原为原始值。恢复不重要的唯一时间是您准备以任何方式处置DC时,可能是在临时
位图的情况下


如果使用
GetStockObject
,则无需调用
DeleteObject

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

调用
SelectObject()
时,您正在设置该类型的活动对象。可以将其视为“拿起红色笔进行绘制,然后拿起蓝色笔进行绘制”。如果GDI函数使用
(例如
矩形
),它将通过
选择对象
使用最后选择的笔。这就是为什么
SelectObject
返回上一个值,以便在完成恢复状态时存储它

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

最佳做法是将
设备上下文
(DC)还原为您找到它的方式。因此,如果设置了
字体
画笔
,则应在返回之前将其还原为原始值。恢复不重要的唯一时间是您准备以任何方式处置DC时,可能是在临时
位图的情况下

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

一个Delphi(Pascal)示例:

Delphi(Pascal)示例:


对当您知道应该恢复设备上下文时,故意不恢复设备上下文是非常不明智的。这是一种未定义的行为,没有记录的结果,如果使用,后果自负。谢谢。关于DeleteObject,你有什么意见吗?当你不再需要它时删除它。是的。当您知道应该恢复设备上下文时,故意不恢复设备上下文是非常不明智的。这是一种未定义的行为,没有记录的结果,如果使用,后果自负。谢谢。关于DeleteObject,你有什么意见吗?当你不再需要它时删除它。谢谢。因此,如果我使用全局字体(在应用程序运行时一直使用),我仍然必须删除WM_DESTROY中的字体,对吗?是的,如果您使用
CreateFont
创建它,您应该使用
DestroyObject
释放它。但是,您不必担心
SelectObject
,因为应用程序的DC很快就会被销毁。但不要删除仍被选入DC的对象。如果你已经对DC做了很多调整,那么使用
SaveDC
RestoreDC
可以更简单地管理它。好的一点@AdrianMcCarthy,如果你有几个DC使用共享对象,只有在没有其他DC使用它的时候才调用
DeleteObject
(我已经很久没有使用GDI了).@SiLo:对于某些GDI对象(例如位图),您不应将它们同时选择到两个不同的DC中。(使用库存对象可能是安全的。)在删除DC之前,从DC中选择这些对象非常重要。谢谢。因此,如果我使用全局字体(在应用程序运行时一直使用),我仍然必须删除WM_DESTROY中的字体,对吗?是的,如果您使用
CreateFont
创建它,您应该使用
DestroyObject
释放它。但是,您不必担心
SelectObject
,因为应用程序的DC很快就会被销毁。但不要删除仍被选入DC的对象。如果你对DC做了很多调整,使用
SaveDC
RestoreDC
可以更简单地管理它。如果你有se,AdrianMcCarthy有一个很好的观点
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