没有打电话给ReleaseDC会发生什么坏事?

时间:2011-08-28 07:37:43

标签: c++ winapi opengl graphics device-context

使用C ++进行编程,一旦我们通过GetDC获取上下文设备即可使用。如果我们在没有调用ReleaseDC的情况下退出程序会发生什么不好的事情?

3 个答案:

答案 0 :(得分:4)

来自the docs

  

ReleaseDC函数释放设备上下文(DC),释放它   由其他应用程序使用。 ReleaseDC功能的效果   取决于DC的类型。它只释放普通和窗口DC。它有   对班级或私人DC没有影响。

如您所见,如果其他应用程序可以访问同一DC,则 可能

无论如何,最好使用C ++ RAII idiom来做这类事情。考虑这个课程:

class ScopedDC
{
   public:
      ScopedDC(HDC handle):handle(handle){}
      ~ScopedDC() { ReleaseDC(handle); }
      HDC get() const {return handle; }
   //disable copying. Same can be achieved by deriving from boost::noncopyable
   private:
      ScopedDC(const ScopedDC&);
      ScopedDC& operator = (const ScopedDC&); 

   private:
      HDC handle;
};

通过这门课,你可以这样做:

{
   ScopedDC dc(GetDC());
   //do stuff with dc.get();
}  //DC is automatically released here, even in case of exceptions

答案 1 :(得分:4)

与GDI相关的资源泄漏的应用程序可能会在连续运行一段时间后停止绘制任何内容。尽管内部GDI调用返回成功,但所有应用程序窗口都保持为空。 “应用程序停止绘制” - 这是Windows编程留言板中的标准问题,当程序有资源泄漏时。

答案 2 :(得分:2)

  

如果我们退出程序而不调用ReleaseDC会发生什么不好的事情?

退出程序会自动释放所有分配的资源,所以我同意David Heffernan和Hans Passant的评论:没有什么不好的事情发生。

退出使用GetDC的例程是另一回事。正如Armen Tsirunyan已经指出的那样,ReleaseDCmúst在获取公共和窗口DC的设备上下文之后被调用,否则程序可能会在 out of resources 异常中运行,因为这些DC的系统特殊缓存增长。

现在,您获取DC的窗口是公共窗口还是窗口DC可能很方便。获取此信息的一种方法是查看窗口是否具有私有设备上下文。请参阅有关Display Device Contexts的文档:

  

私有设备上下文

     

...私有设备上下文不是系统缓存的一部分,因此无需在使用后释放。 ...应用程序通过在初始化WNDCLASS结构的样式成员并调用RegisterClass时首先指定CS_OWNDC窗口类样式来创建私有设备上下文...

因此,当窗口类设置了CS_OWNDC标志时,您不必担心释放DC,因为它由窗口本身而不是系统缓存管理。您可以致电GetClassInfo(Ex)来获取此设置。

但请注意,释放GetDC获得的DC对类或私有DC没有影响,因此在ReleaseDC之后调用GetDC 始终是明智的