通常,如果程序将对象选择到设备上下文中,或者更改其属性,则应在释放设备上下文之前将其更改回来。如果没有会发生什么?
让我说我这样做:
HDC hdc = GetDC(some_window);
SelectObject(hdc, some_font);
SetTextColor(hdc, 0x123456);
SetBkColor(hdc, 0xFEDCBA);
SetROP2(hdc, R2_XORPEN);
ReleaseDC(some_window, hdc);
和some_window
的窗口类没有CS_OWNDC
或CS_CLASSDC
标志。会发生什么?
答案 0 :(得分:3)
在您列出的功能中,如果未取消选择对象(通过选择原始对象),SelectObject
是唯一会导致问题的功能。这会导致some_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);
作为MSDN notes:
这些函数中的每一个都返回一个标识新对象的句柄。 在应用程序检索句柄后,它必须调用 SelectObject 函数替换默认对象。但是,应用程序应保存标识默认对象的句柄 在不再需要时使用此句柄替换新对象。 当应用程序使用新对象完成绘制时,它必须 通过调用 SelectObject 函数来恢复默认对象 然后通过调用 DeleteObject 删除新对象 功能。无法删除对象会导致严重的性能 问题。
答案 1 :(得分:0)
无法恢复原始字体对象会导致句柄泄漏。操作系统将保留some_font的句柄。如果重复执行此代码,则每次都会泄漏另一个句柄。您将在任务管理器中看到Handles计数。如果这种情况持续很长时间,那么最终会出现一种看似垃圾的绘画失败。