如果不调用ReleaseDC,会发生什么不好的事情

What bad things may happen without calling to ReleaseDC?

本文关键字:什么 ReleaseDC 调用 如果不      更新时间:2023-10-16

用c++编程,一旦得到上下文设备就由GetDC来使用。如果我们在没有调用ReleaseDC的情况下退出程序,会发生什么不好的事情?

From the docs

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

可以看到,如果其他应用程序可以访问同一个DC,则可能需要

在任何情况下,使用c++ RAII习语处理这类事情都是一个好主意。考虑这个类:

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

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

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

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

退出使用GetDC的例程是另一回事。正如Armen Tsirunyan已经指出的那样,ReleaseDC múst应该在获得通用DC和窗口DC的设备上下文之后调用,否则程序可能会因为这些DC的系统专用缓存的增长而在资源不足异常中运行。

现在,您从中获取DC的窗口是普通DC还是窗口DC可能很方便知道。获取此信息的一种方法是查看窗口是否具有专用设备上下文。请参阅有关显示设备上下文的文档:

专用设备上下文

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

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

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