什么是,为什么我必须在清理时将位图 hdc 或内存 dc 恢复到默认状态? [复制]

Posted

技术标签:

【中文标题】什么是,为什么我必须在清理时将位图 hdc 或内存 dc 恢复到默认状态? [复制]【英文标题】:What is, and why do I have to restore bitmap hdc or memory dc to the default state when cleaning up? [duplicate] 【发布时间】:2021-03-04 22:23:27 【问题描述】:

当我查看 BitBlt() 示例时,我注意到几乎所有示例都为位图保存了 hdc 的默认状态,然后在清理时使用 SelectObject() 将 hdc 恢复到默认状态。包括 Windows 版 Nethack 的源代码。

除了其中一个没有这样做,只是像我一样清理 hdc 和位图。我看不出将 hdc 恢复到默认状态与内存泄漏有什么关系。仅仅删除hdc还不够吗?当您将 SelectObject() 加载到必须恢复它以清理它的位图时,hdc 是否会加载数据或其他内容?

【问题讨论】:

SelectObject 转让所有权。在两个方向。您选择到设备上下文中的对象归设备上下文所有。从设备上下文中选择的对象的责任交给您。几十年前,这就是设备上下文的设计方式。几十年后,大量的错误代码迫使操作系统实施不虔诚的兼容性修复,这让您几乎没有明智的选择来违反合同。 【参考方案1】:

除了@IInspectable 所说的,您不必恢复 DC;您只需“取消选择”您从该 DC 分配的 GDI 对象。否则,您无法删除当前选择到任何DC 中的对象。

SelectObject() API 方便地返回给您之前选择的对象,因此您可以在完成该DC 后重新选择它。

另外,澄清一下,这些问题会导致资源泄漏(非内存泄漏)。这可能会更糟,因为资源的限制非常低(例如 10,000 个句柄,IIRC)。

【讨论】:

以上是关于什么是,为什么我必须在清理时将位图 hdc 或内存 dc 恢复到默认状态? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

更改与 HDC 关联的位图大小后,有没有办法更新 Graphics 对象?

将窗口内容显示为位图

用于位图管理的 C++ STL 类

Java 清理步骤

我的 hdc/hbitmap 的内存泄漏在哪里?

如何使刷新时画面不闪烁