C 如果释放不干净的设备上下文,会发生什么?

C 如果释放不干净的设备上下文,会发生什么?,c,winapi,gdi,C,Winapi,Gdi,通常,如果程序在设备上下文中选择对象,或更改其属性,则应在释放设备上下文之前将其更改回。如果没有,会发生什么 假设我这样做: HDC hdc = GetDC(some_window); SelectObject(hdc, some_font); SetTextColor(hdc, 0x123456); SetBkColor(hdc, 0xFEDCBA); SetROP2(hdc, R2_XORPEN); ReleaseDC(some_window, hdc); 而某些窗口的窗口类没有CS\u

通常,如果程序在设备上下文中选择对象,或更改其属性,则应在释放设备上下文之前将其更改回。如果没有,会发生什么

假设我这样做:

HDC hdc = GetDC(some_window);
SelectObject(hdc, some_font);
SetTextColor(hdc, 0x123456);
SetBkColor(hdc, 0xFEDCBA);
SetROP2(hdc, R2_XORPEN);
ReleaseDC(some_window, hdc);

某些窗口的窗口类没有
CS\u OWNDC
CS\u CLASSDC
标志。发生了什么?

在您列出的函数中,
SelectObject
是唯一一个在未取消选择对象(通过选择原始对象)时会导致问题的函数。这将导致
some\u font
资源泄漏,因为DC在释放时会持有一个打开的句柄

您应该这样做:

HDC hdc = GetDC(some_window);
HGDIOBJ hOldObj = SelectObject(hdc, some_font);

// ... 

SelectObject(hdc, hOldObj);
ReleaseDC(some_window, hdc);
或许是这样:

HDC hdc = GetDC(some_window);
int nSaved = SaveDC(hdc);
SelectObject(hdc, some_font);

// ... 

RestoreDC(nSaved);
ReleaseDC(some_window, hdc);
作为:

这些函数中的每一个都返回一个标识新对象的句柄。 应用程序检索句柄后,必须调用 选择对象功能以替换默认对象。但是,应用程序应该保存标识默认对象和 当不再需要新对象时,使用此句柄替换该对象。 当应用程序使用新对象完成绘图时,它必须 通过调用SelectObject功能恢复默认对象 然后通过调用DeleteObject 功能。未能删除对象会导致严重的性能问题 问题


无法还原原始字体对象会导致句柄泄漏。操作系统将保留某些字体的句柄。如果重复执行此代码,则每次都会泄漏另一个句柄。您将看到任务管理器中的句柄数正在增加。如果这种情况持续很长时间,最终会出现绘画失败,看起来像垃圾一样。

如果字体没有被破坏怎么办?(直到程序终止)@immibis如果字体未使用
DeleteObject
销毁,则实际上是资源泄漏<代码>删除对象
如果在对象仍被选择到DC中时调用它(可能)会失败。然而,在程序结束时,这可能无关紧要——但这不是一个好的做法。删除它的正确时间应该是程序结束时。是什么让操作系统删除它而不是显式删除它成为一种不好的做法?但这与原来的问题相切。@immibis删除明确性意味着您知道自己在做什么,而不是依赖默认行为来整理。如果随后更改了代码,则默认行为可能不再合适,并且在何时何地不再需要您分配的资源也不明显。