bool CMyDlg::PicDraw(int nID, Gdiplus::Image* pImage,const CString strName)
{
ASSERT(pImage);
  CWnd* pWnd = GetDlgItem(nID);     // IDC_STATIC1 specified
switch(nID)
{
case IDC_PICA:
strPicTitle[0] = strName;
break;
case IDC_PICB:
strPicTitle[1] = strName;
break;
case IDC_PICC:
strPicTitle[2] = strName;
break;
case IDC_PICD:
strPicTitle[3] = strName;
break;
case IDC_PICE:
strPicTitle[4] = strName;
break;
case IDC_PICF:
strPicTitle[5] = strName;
break;
}

RECT rc;
pWnd->GetClientRect(&rc);

UINT x = pImage->GetWidth();
UINT y = pImage->GetHeight();

if (x != 0)
{
long w = rc.right-rc.left;
long h = rc.bottom-rc.top; pImage->GetThumbnailImage(w,y * w / x,NULL,NULL); CDC* pDC = pWnd->GetDC(); //pWnd->SetRedraw();
using namespace Gdiplus;
if (pImage!=NULL)
{
Graphics graphics= pDC->m_hDC ;
graphics.DrawImage(pImage, 0, 0, w , y * w  / x);
graphics.ReleaseHDC(pDC->m_hDC);
}
pWnd->ReleaseDC(pDC);
return true;
}
else
return false;
}是pWnd应该释放资源呢?还是Graphics没有释放资源?Gdiplus::Image* pImage这个传入的参数,我每次在调用的
时候,都用
using namespace Gdiplus; 
//在此代码段中,重点是GDI+要用宽字符串,所以你要用USES_CONVERSION 和 A2W
USES_CONVERSION;
Image* m_pImage1=Image::FromFile(A2W((LPCTSTR)strJpgName),FALSE);
PicDraw(IDC_PIC,m_pImage1,strJpgName);
delete m_pImage1;不知那个地方,没有释放资源?

解决方案 »

  1.   

    你这块是完整的程序吗?
    看不大出来,好像没有泄漏。如果有泄漏,应该是Graphics 的问题
      

  2.   

    是啊,是Graphics 的问题吗,那怎么解决?
    我就是没能明白,这个Graphics怎么释放资源?
    还有,声明一个CWnd指针,没有内存泄漏的问题吗?
      

  3.   

    void CMyDlg::OnBnClickedGrab()
    {
    // TODO: 在此添加控件通知处理程序代码
    lPicCnt += 1;
    CString strPicName;
    strPicName.Format("%d",lPicCnt);
    CString strName = "c:\\";
    CString strBmp = ".bmp";
    strPicName = strName + strPicName + strBmp;

    m_strBmpName = strPicName; CString strJpg = ".jpg";
    CString strJpgName;
    strJpgName.Format("%d",lPicCnt); strJpgName = strName + strJpgName + strJpg; m_strJpgName = strJpgName;

    CListBox* pLB = (CListBox*) GetDlgItem(IDC_LIST);
    pLB->InsertString(-1, (LPCTSTR)strJpgName);

    CStatic* pST = (CStatic*) GetDlgItem(IDC_PICNUM);
    CString strTitle;
    strTitle.Format("图片 %d 张",lPicCnt);
    pST->SetWindowText((LPCTSTR)strTitle); //TS_GrabImageFile ((LPTSTR)(LPCTSTR)strPicName);
    //long bufsize = 1050 * 1050;
    //char *pbuf = new char[bufsize];
    //TS_GrabImage(pbuf, bufsize);
    //CFile file;
    //file.Open("test.bmp",  CFile::modeCreate | CFile::modeReadWrite);
    //file.Write(pbuf, bufsize);
    //file.Close();
    // TS_GrabImageFile ((LPTSTR)(LPCTSTR)m_strBmpName); MSG message; m_nTimer = SetTimer(1, 100, NULL); // 1/10 second
    ASSERT(m_nTimer != 0);
    volatile int nTemp;
    for (m_nCount = 0; m_nCount < nMaxCount; m_nCount++) 
    {
    for (nTemp = 0; nTemp < 10000; nTemp++) 
    {
    // uses up CPU cycles
    }
    if (::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) 
    {
    ::TranslateMessage(&message);
    ::DispatchMessage(&message);
    }
    //while (::GetMessage(&message, NULL, 0, 0))
    //{
    // ::TranslateMessage(&message);
    // ::DispatchMessage(&message);
    //}
    }
    KillTimer(m_nTimer);
    //Invalidate();
    using namespace Gdiplus; 
    //在此代码段中,重点是GDI+要用宽字符串,所以你要用USES_CONVERSION 和 A2W USES_CONVERSION; Image* m_pImage1=Image::FromFile(A2W((LPCTSTR)m_strJpgName),FALSE);
    PicDraw(IDC_PIC,m_pImage1,m_strJpgName); switch (lPicCnt % 6)
    {
    case 1:
    PicDraw(IDC_PICA,m_pImage1,strJpgName);
    delete m_pImage1;
    break;
    case 2:
    PicDraw(IDC_PICB,m_pImage1,strJpgName);
    delete m_pImage1;
    break;
    case 3:
    PicDraw(IDC_PICC,m_pImage1,strJpgName);
    delete m_pImage1;
    break;
    case 4:
    PicDraw(IDC_PICD,m_pImage1,strJpgName);
    delete m_pImage1;
    break;
    case 5:
    PicDraw(IDC_PICE,m_pImage1,strJpgName);
    delete m_pImage1;
    break;
    case 0:
    PicDraw(IDC_PICF,m_pImage1,strJpgName);
    delete m_pImage1;
    break;
    } CScrollBar* pSB = (CScrollBar*) GetDlgItem(IDC_SCROLLBAR);
    pSB->SetScrollRange(0, lPicCnt);
    pSB->SetScrollPos(lPicCnt);
    }
    这是抓图的程序,我用Windows资源管理器,看着内存每次都增长,
    画图的时候也是.
      

  4.   

    仔细检查你的程序中所有用到new关键字的地方,看使用new关键字申明的的内存是不是最终都调用了相应的delete?通常你在一个函数中使用了new申明了一块内存,并将指向该内存的指针传给其他函数,经过一系列传来传去的操作后,却都忘记释放该内存了!总是使用new或malloc申明的内存一定要作相应的内存释放操作,不然的话就出现Memory Leak!另外,通过按F5运行工程,运行你认为可能会出现Memory Leak的地方,等程序退出后,Vistual Studio的Output窗口一般会告诉你在什么地方出现了Leak!
    如:
    Detected memory leaks!
    Dumping objects ->
    D:\Program Files\Microsoft Visual Studio\MyProjects\MyOwerDrawCtrl\SDI1\SDI1View.cpp(230) : {204} client block at 0x00376910, subtype 0, 64 bytes long.
    a CButton object at $00376910, 64 bytes long
    Object dump complete.
    双击D:\Program Files.....这行即可看见出现Leak的地方!
      

  5.   

    对了,是在Visual Studio的Debug窗口! :)
      

  6.   

    1 :Image* m_pImage1=Image::FromFile(A2W((LPCTSTR)m_strJpgName),FALSE);
    2 :PicDraw(IDC_PIC,m_pImage1,m_strJpgName);
    3 :delete m_pImage1;
    我用windows任务管理器观察,单步调试,
    执行过1行时,内存没增加,当执行完
    第二行时内存增加,
    执行完第三行时,内存没有再减少。
    所以PicDraw(int nID, Gdiplus::Image* pImage,const CString strName)
    里一定有内存没释放的地方,是不是?
    可我又看不出哪里没释放。
      

  7.   

    在PicDraw(int nID, Gdiplus::Image* pImage,const CString strName)
    这个函数里,
    pImage->GetThumbnailImage(w,y * w / x,NULL,NULL);
    这句是产生内存泄漏的根本原因。
    正确用法:
    Image* pThumbnail = pImage->GetThumbnailImage(w,y * w / x,NULL,NULL);   
       delete pThumbnail;GetThumbnailImage函数返回的是Image*,所以在内存里消耗了资源,应该释放。