如何在纯 C++ 中高效快速地清理我的 GDI 对象 - winapi(不是 .net,c#)?

Posted

技术标签:

【中文标题】如何在纯 C++ 中高效快速地清理我的 GDI 对象 - winapi(不是 .net,c#)?【英文标题】:How to clean my GDI objects efficiently and quikcly in pure C++ - winapi (not .net, c#)? 【发布时间】:2018-03-31 15:25:44 【问题描述】:

我正在用纯 C++ - winapi(不是 .net,c#)编写程序。程序有很多HWND对象,如按钮、checkautobox、图标(LoadImage())、编辑和tab控件等,总数在300左右,大部分是全局定义的,也有很多字符串对象也是。

我从任务管理器查看GDI对象编号,一开始显示1865,在程序中多次切换我的不同选项卡控件后迅速达到10,000,因此导致GDI泄漏。程序用灰色很烂。

现在,我该如何解决这个问题?我应该为每个图标使用DestroyIcon(icon),还应该使用DeleteObject(hwnditem) 函数在创建或使用后删除每个对象(全部在WM_CREATE 块中创建)?此操作会减少我的 GDI 对象数量并且不会导致 GDI 泄漏吗?有什么快速的方法来解决这个问题吗?这里是用 GDIView 程序给出的 GDI 对象编号筛选图像。

【问题讨论】:

实际上是 GDI 泄漏导致了巨大的 GDI 计数器值。您应该使用 RAII 惯用语来管理 GDI 和其他资源,并仔细控制它们的生命周期和所有权。 @VTT :这是一个答案,而不是评论。 (实际上,这是 答案。) 抱歉 - 试图嵌入图像 - 但它不可读。 好吧,你已经知道问题出在哪里了。您创建的每个 GDI 对象都必须再次销毁。当您使用 SelectObject() 将绘图对象选择到设备上下文中时,您必须存储返回值。所以你可以在设备上下文被销毁之前选择它。不遵守这些规则会导致对象泄漏。 您的程序中有一个(或许多)错误。我们看不到它。这不会产生建设性的反馈。 minimal reproducible example 必填。 【参考方案1】:

我通过在我的绘图和添加图标代码块的适当位置添加DeleteObject(x)DestroyIcon(y) 方法解决了我的问题。现在,GDI 对象的数量几乎是稳定的,没有增加。

【讨论】:

以上是关于如何在纯 C++ 中高效快速地清理我的 GDI 对象 - winapi(不是 .net,c#)?的主要内容,如果未能解决你的问题,请参考以下文章

C++ GDI+如何从资源中获取和加载图像?

使用 c++ 和 GDI 分析屏幕截图以获得屏幕的平均颜色

C++ 中的 GDI+ 双缓冲

如何高效地为室友电脑清理 C 盘?

如何在 C++ 中编写高效的遗传算法

快速高效地获取屏幕(视图)黑色像素