释放MFC中使用Image.load方法分配的内存
在MFC中,我加载了一个.PNG图像,然后用静态控件显示它,如下所示:释放MFC中使用Image.load方法分配的内存,mfc,Mfc,在MFC中,我加载了一个.PNG图像,然后用静态控件显示它,如下所示: CImage Img; Img.Load(_T(abc.png")); CBitMap Bmp; Bmp.Attach(Img.Detach()); CStatic dispImg; dispImg.SetBitmap(Bmp); void CPNGTestDlg::ChangePic(Cstring img) { CImage Img; Img.Load(img); CBitmap Bmp; Bmp.Attach(Img
CImage Img;
Img.Load(_T(abc.png"));
CBitMap Bmp;
Bmp.Attach(Img.Detach());
CStatic dispImg;
dispImg.SetBitmap(Bmp);
void CPNGTestDlg::ChangePic(Cstring img)
{
CImage Img;
Img.Load(img);
CBitmap Bmp;
Bmp.Attach(Img.Detach());
HBITMAP hBmp=m_pic.SEtBitmap(Bmp);
if(hBmp!=NULL) DeleteObject(hBmp);
}
void CPNGTest::OnBnClickedChngPic()
{
if(SetBlueImg)
{
ChangePic(_T("Blue.png"));
SetBlueImg=false;
}
else
{
ChangePic(_T("Red.png"));
SetBlueImg=true;
}
}
通过这种方式,我有几个图像,我用静态控件重复显示
这导致我的应用程序内存严重泄漏。我通过谷歌搜索找到了一些线索,但我无法决定释放内存的最佳选择。谁能告诉我最好的方法
正如xMRi所建议的,我正在释放CStatic::SetBitmap返回的HBITMAP句柄。在我的测试应用程序中,有一个CStatic控件成员m_pic,一个方法ChangePic,它设置一个位图和一个按钮控件,用于根据布尔变量SetBlueImg的值更改图像。ChangePic的定义如下:
CImage Img;
Img.Load(_T(abc.png"));
CBitMap Bmp;
Bmp.Attach(Img.Detach());
CStatic dispImg;
dispImg.SetBitmap(Bmp);
void CPNGTestDlg::ChangePic(Cstring img)
{
CImage Img;
Img.Load(img);
CBitmap Bmp;
Bmp.Attach(Img.Detach());
HBITMAP hBmp=m_pic.SEtBitmap(Bmp);
if(hBmp!=NULL) DeleteObject(hBmp);
}
void CPNGTest::OnBnClickedChngPic()
{
if(SetBlueImg)
{
ChangePic(_T("Blue.png"));
SetBlueImg=false;
}
else
{
ChangePic(_T("Red.png"));
SetBlueImg=true;
}
}
按钮的点击事件定义如下:
CImage Img;
Img.Load(_T(abc.png"));
CBitMap Bmp;
Bmp.Attach(Img.Detach());
CStatic dispImg;
dispImg.SetBitmap(Bmp);
void CPNGTestDlg::ChangePic(Cstring img)
{
CImage Img;
Img.Load(img);
CBitmap Bmp;
Bmp.Attach(Img.Detach());
HBITMAP hBmp=m_pic.SEtBitmap(Bmp);
if(hBmp!=NULL) DeleteObject(hBmp);
}
void CPNGTest::OnBnClickedChngPic()
{
if(SetBlueImg)
{
ChangePic(_T("Blue.png"));
SetBlueImg=false;
}
else
{
ChangePic(_T("Red.png"));
SetBlueImg=true;
}
}
SetBlueImg=true的初始值,在OnInitDialog()中我调用了ChangePic(_T(“Red.png”)
我运行应用程序并不断单击按钮以更改当前图像,但仍然可以通过windows任务管理器看到内存泄漏。点击按钮40/50次或有时不可预测后,内存会增加4KB。请指出导致泄漏的地方。为了在用另一个图像替换静态控件上的一个图像时消除重叠图像,我最初遵循以下步骤:
对话框被破坏时,必须删除HBITMAP对象
void CMFCAppDlg::OnDestroy()
{
CDialogEx::OnDestroy();
DeleteObject(m_pic.GetBitmap());
}
我在你的代码片段中没有看到内存泄漏。请给出一个SSCCE。请考虑代码片段在一个循环内,因为我正在根据一些事件加载不同的图像。但是,只有显示图像的静态控件对象dispImg在循环外声明。实际上,我已经看到循环的每一次迭代都会增加4KB的内存消耗。如果您显示的代码与您的代码不同(例如关于对象生命周期),那么您希望我们如何提供帮助?因此,如前所述,sscce请。对不起!我不能在这里展示一切。我只是给了你一个样本,告诉你我想做什么。唯一有争议的事情是在循环之外。其他事情如我在文章中提到的。在我的项目中,我使用了一个静态控件并声明了一个成员变量dispImg,用于根据不同的事件设置不同的png图像。相同的dispImg用于在应用程序生命周期的不同时间显示不同的图像。我错说dispImg在循环中;实际上,在一个方法中,我通过CImage加载不同的图像(一次加载一个,取决于某个设备的状态),并获取CBitMap对象以使用dispImg对其进行设置。该方法在事件发生时调用。据我所知,每次释放SetBitmap返回的HBITMAP不会留下任何内存泄漏。您必须释放SetBitmap返回的位图。当你问问题时,如果你能更详细地描述问题,那将是很有帮助的。谢谢xMRI的帮助。我会应用你的建议,然后回来。按照xMRi建议的方式,我用旧的图像替换PNG图像,但图像重叠。我在背景上附加了一个PNG图像,然后在背景上显示了另一个PNG图像,现在当我试图用较小的图像替换第二个图像时,第三个图像将显示在第二个图像上。我只想在背景上显示第三个图像。有人能给我提个建议吗?