【问题标题】:What bad things may happen without calling to ReleaseDC?如果不调用 ReleaseDC,可能会发生什么坏事?
【发布时间】:2011-11-05 09:16:12
【问题描述】:

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

【问题讨论】:

  • 大多数情况下你只需要处理随之而来的恶业
  • 没什么,Windows 在终止进程时会清理垃圾。然而,持有设备上下文几乎总是错误的。例如,当窗口大小发生变化时,它将无效。创建设备上下文非常便宜,不要过早优化。

标签: c++ winapi opengl graphics gdi


【解决方案1】:

来自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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      如果我们退出程序而不调用 ReleaseDC,可能会发生什么坏事?

      退出程序会自动释放所有分配的资源,所以我同意 David Heffernan 和 Hans Passant 的 cmets:不会发生任何坏事。

      退出您使用GetDC 的例程是另一回事。正如Armen Tsirunyan 已经指出的,ReleaseDC 必须在获得 common 和 window DC 的设备上下文后调用,否则程序可能会由于系统的增长而在 out of resources 异常中运行这些 DC 的特殊缓存。

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

      私有设备上下文

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

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

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

      【讨论】:

      • 其实我的评论是开玩笑的!我总是努力把事情做好!
      • @David 我同意!但它有一些意义。
      猜你喜欢
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多