关于内存释放的问题

sup_ace 2013-04-21 01:37:40
我想在对话框上做一个加载jpg的static
当鼠标移动到static上的时候 static高亮(变色)

我用子类化的方法自绘了static

我在onpaint中实现画
在onmousemove中进行判断
当鼠标在static上的时候就Invalidate

当我多次刷底色后 程序就崩了 我在资源管理器中看到 内存变得好大然后就崩了


这是我在onpaint中进行的自绘
void CmyStatic::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CStatic::OnPaint()
GetClientRect(&rect);
m_h = rect.Height();
m_w = rect.Width()/5;


img.Load(L"D:\\1.jpg"); // filename 是要加载的文件名(包含路径) 7056k
hbitmap = img.Detach();


BITMAP m_bm;
CDC memDC;//
CBitmap memBitmap;
CDC *pDC = GetDC();
memDC.CreateCompatibleDC(NULL);//创建与目标DC相兼容的内存DC,
memBitmap.CreateCompatibleBitmap(pDC,rect.Width(), rect.Height());//根据目标DC创建位图,为什么?看后面
memDC.SelectObject(&memBitmap);//把位图选入内存DC

memDC.SetBkMode(TRANSPARENT);
if(flag == 0)
{
memDC.FillSolidRect(rect,RGB(0, 255, 0));
memDC.SetTextColor(RGB(0,0,0));
memDC.TextOut(m_w*1,m_h/3,L"2012 3/12");
}
if(flag == 1)
{
memDC.FillSolidRect(rect,RGB(0, 0, 255));
memDC.SetTextColor(RGB(255,255,255));
memDC.TextOut(m_w*1,m_h/3,L"2012 3/12");
}

GetObject(hbitmap, sizeof BITMAP, &m_bm);
CPen *pen=new CPen(PS_SOLID, 1,RGB(128, 128, 128));

CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
dcMem.SelectObject(hbitmap);
//DeleteObject(hbitmap);
memDC.SelectObject(pen);
pen->DeleteObject();
delete pen;
memDC.MoveTo(0,0);
memDC.LineTo(m_w*5,0);
memDC.MoveTo(0,m_h-1);
memDC.LineTo(m_w*5,m_h-1);

memDC.StretchBlt(m_w*4, 3, m_w, m_h-6, &dcMem, 0, 0, m_bm.bmWidth, m_bm.bmHeight, SRCCOPY);

//dcMem.Detach();
dcMem.DeleteDC();

pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),&memDC, 0, 0,SRCCOPY);

img.Destroy();
ReleaseDC(pDC);
//memDC.Detach();
memDC.DeleteDC();
}



我单步调试程序的时候 我发现我加载的图片虽然只有几十K
但是我load的时候,我在资源管理器中看到总是会加将近一千多k的内存
在img.Destroy的地方内存并没有减少

然后后边在刷的时候 内存就一直增加没有减少

那位大神可以给我分析分析 我上面这段代码内存会增加 和会减少的地方?
还有我申请的那些内存到底该如何释放?
...全文
160 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
sup_ace 2013-04-21
  • 打赏
  • 举报
回复
引用 5 楼 sup_ace 的回复:
引用 2 楼 Mackz 的回复:东抄抄,西抄抄,代码乱糟糟…… 这个过程我不是很清楚。。。。 我只是有个大概的轮廓 在内存中创建一张图 把要画的东西画好 然后再 贴在对应的控件上 至于过程的细节 我不是很清楚。。。
有没有详细一点的介绍的文章 或者博客
sup_ace 2013-04-21
  • 打赏
  • 举报
回复
引用 2 楼 Mackz 的回复:
东抄抄,西抄抄,代码乱糟糟……
这个过程我不是很清楚。。。。 我只是有个大概的轮廓 在内存中创建一张图 把要画的东西画好 然后再 贴在对应的控件上 至于过程的细节 我不是很清楚。。。
sup_ace 2013-04-21
  • 打赏
  • 举报
回复
引用 3 楼 Mackz 的回复:
你那个img变量是什么类型的?CImage? 引用 楼主 sup_ace 的回复:我想在对话框上做一个加载jpg的static 当鼠标移动到static上的时候 static高亮(变色) 我用子类化的方法自绘了static 我在onpaint中实现画 在onmousemove中进行判断 当鼠标在static上的时候就Invalidate ……
恩 。。。。
菜牛 2013-04-21
  • 打赏
  • 举报
回复
你那个img变量是什么类型的?CImage?
引用 楼主 sup_ace 的回复:
我想在对话框上做一个加载jpg的static 当鼠标移动到static上的时候 static高亮(变色) 我用子类化的方法自绘了static 我在onpaint中实现画 在onmousemove中进行判断 当鼠标在static上的时候就Invalidate 当我多次刷底色后 程序就崩了 我在资源管理器中看到 内存变得好大然后就崩了 ……
菜牛 2013-04-21
  • 打赏
  • 举报
回复
东抄抄,西抄抄,代码乱糟糟……
shiter 2013-04-21
  • 打赏
  • 举报
回复
路过学习一下
辰岡墨竹 2013-04-21
  • 打赏
  • 举报
回复
你不要OnPaint时再Load,只用Load一次就够了,可以放在窗体创建时。 另外你的位图比如hbitmap为什么不销毁呢? 你应该在第一次SelectObject时,将SelectObject返回的对象用个变量保存起来,用完后要将原来的对象重新选回DC,才能删除位图,然后再释放DC,这是正确顺序。 CBitmap *pOldBitmap = memdc.SelectObject(&bitmap); memdc.SelectObject(pOldBitmap); 然后才能销毁bitmap和DC
菜牛 2013-04-21
  • 打赏
  • 举报
回复
调用:
CPictureCtrl m_Picture;
...
m_Picture.LoadImage(_T("C:\\...\\武林外传.jpg"));
菜牛 2013-04-21
  • 打赏
  • 举报
回复
我的简化版:
class CPictureCtrl : public CStatic
{
DECLARE_DYNAMIC(CPictureCtrl)
public:
CPictureCtrl();
virtual ~CPictureCtrl();
protected:
DECLARE_MESSAGE_MAP()
afx_msg void OnSize(UINT nType, int cx, int cy);
void ReSize(int cx, int cy);
public:
bool LoadImage(LPCTSTR pszImageFile = NULL);
afx_msg void OnPaint();
protected:
CString m_ImageFile;
CString m_Title;
CTime m_Time;
CSize m_Size;
CImage m_Thumbnail;
CRect m_ImageRect;
};

// CPictureCtrl

IMPLEMENT_DYNAMIC(CPictureCtrl, CStatic)

CPictureCtrl::CPictureCtrl()
: m_ImageFile(_T(""))
{
}

CPictureCtrl::~CPictureCtrl()
{
}

BEGIN_MESSAGE_MAP(CPictureCtrl, CStatic)
ON_WM_PAINT()
ON_WM_SIZE()
END_MESSAGE_MAP()

// CPictureCtrl 消息处理程序

bool CPictureCtrl::LoadImage(LPCTSTR pszImageFile)
{
ASSERT(GetSafeHwnd());

if (pszImageFile == NULL)
{
if (m_ImageFile.IsEmpty())
{
return false;
}
}
else
{
m_ImageFile = pszImageFile;
}
if (!PathFileExists(m_ImageFile))
{
return false;
}

m_Title = PathFindFileName(m_ImageFile);
WIN32_FILE_ATTRIBUTE_DATA fa = {0};
if (GetFileAttributesEx(m_ImageFile, GetFileExInfoStandard, &fa))
{
m_Time = fa.ftLastWriteTime;
}

RECT rc;
GetClientRect(&rc);
ReSize(rc.right - rc.left, rc.bottom - rc.top);
return true;
}

void CPictureCtrl::ReSize(int cx, int cy)
{
CImage img;
if (FAILED(img.Load(m_ImageFile))){
return;
}
m_Size.cx = img.GetWidth();
m_Size.cy = img.GetHeight();

m_ImageRect.SetRect(0, 0, cx, cy);
m_ImageRect.DeflateRect(5, 5);
m_ImageRect.right = m_ImageRect.left + (int)(((float)m_Size.cx / (float)m_Size.cy) * (float)m_ImageRect.Height());

m_Thumbnail.Destroy();
m_Thumbnail.Create(m_ImageRect.Width(), m_ImageRect.Height(), img.GetBPP());
RECT rc = { 0, 0, m_ImageRect.Width(), m_ImageRect.Height()};
img.Draw(m_Thumbnail.GetDC(), rc, Gdiplus::InterpolationModeDefault);
m_Thumbnail.ReleaseDC();
img.Destroy();
}

void CPictureCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CStatic::OnPaint()
CRect rc;
GetClientRect(&rc);
dc.Rectangle(rc);

rc = m_ImageRect;
rc.InflateRect(1, 1);
dc.Rectangle(rc);
m_Thumbnail.BitBlt(dc, m_ImageRect, CPoint(0, 0));

CFont* pOldFont = (CFont*)dc.SelectStockObject(DEFAULT_GUI_FONT);
dc.TextOut(m_ImageRect.right + 5, m_ImageRect.top, m_Title);
CString temp;
temp = m_Time.Format(_T("%Y年%m月%d日"));
dc.SelectStockObject(DEFAULT_GUI_FONT);
dc.TextOut(m_ImageRect.right + 5, m_ImageRect.top + 20, temp);
temp.Format(_T("宽:%d,高:%d"), m_Size.cx, m_Size.cy);
dc.TextOut(m_ImageRect.right + 5, m_ImageRect.top + 35, temp);
dc.SelectObject(pOldFont);
}

void CPictureCtrl::OnSize(UINT nType, int cx, int cy)
{
CStatic::OnSize(nType, cx, cy);

// TODO: 在此处添加消息处理程序代码
ReSize(cx, cy);
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧