如何正确使用 LoadImage 和 DeleteObject?

Posted

技术标签:

【中文标题】如何正确使用 LoadImage 和 DeleteObject?【英文标题】:How to use LoadImage and DeleteObject properly? 【发布时间】:2012-04-11 19:18:44 【问题描述】:

我正在使用 C++ 开发 Windows 应用程序。我使用 LoadImage 将 bmp 文件加载到 DC,它正确显示。但是,当我调用 DeleteObject 时,内存似乎没有被释放。 (我使用windows任务管理器来跟踪内存使用情况)

在 WM_INITDIALOG 部分我这样做:

static HBITMAP hBitmap = 0;
char* tempPath = "tabView.bmp";  
hBitmap = (HBITMAP)LoadImage(NULL,
                             tempPath,  // file containing bitmap
                             IMAGE_BITMAP,  // type = bitmap
                             0, 0,      // original size
                             LR_LOADFROMFILE);      // get image from a file
if(hBitmap)

    SendMessage(GetDlgItem(hwndDlg, IDC_PICTURE),
                STM_SETIMAGE,         // message to send
                (WPARAM)IMAGE_BITMAP, // bitmap type
                (LPARAM)hBitmap);     // bitmap handle

所以图片显示在 DC 中,内存增加。在一个按钮中我会这样做:

int result = DeleteObject(hBitmap);

当我按下按钮时,我检查了结果,它是一个非零值,这就是成功。但是 IDC_PICTURE 仍然会显示图片,并且内存保持不变。我想知道 SendMessage() 是否会增加 hBitmap 上的引用计数...

所以我的问题是:清理的正确方法是什么?

【问题讨论】:

任务管理器不适合检查您是否泄漏。把它放在一个永远运行的循环中,看看你是否内存不足。 【参考方案1】:

您没有提到您使用的 Windows 版本。无论如何,如果您阅读STM_SETIMAGE 的“重要”部分,您将看到下一个:

在 Windows XP 中,如果在 STM_SETIMAGE 消息中传递的位图包含具有非零 alpha 的像素,则静态控件会获取该位图的副本。这个复制的位图由下一个 STM_SETIMAGE 消息返回。客户端代码可以独立跟踪传递给静态控件的位图,但如果它不检查并释放从 STM_SETIMAGE 消息返回的位图,就会泄露位图。

也许这不仅适用于 Windows XP,也适用于更高版本的 Windows。希望这会对你有所帮助。

【讨论】:

谢谢!!这正是正在发生的事情。但是,处理资源的这种奇怪方式......“这个复制的位图由下一个 STM_SETIMAGE 消息返回”。如果我不想再发送一个 STM_SETIMAGE 怎么办? 您可以记住原始返回值,并在准备好删除图像时将其发回。

以上是关于如何正确使用 LoadImage 和 DeleteObject?的主要内容,如果未能解决你的问题,请参考以下文章

loadimage没有与参数列表匹配的重载函数 解决方案

loadimage没有与参数列表匹配的重载函数 解决方案

如何正确替换全局new和delete运算符

用C++在Win32中用LoadImage()绘制HBITMAP的二维数组

如何正确释放类成员?

LoadImage() 返回 NULL 并且 GetLastError() 返回 0