GDI内存泄露解析

GDI内存泄露解析

  (2007-03-30 17:13:03)
转载
  分类: C/VC
感受了这段时间的内存泄露,终于了解了GUI的内存泄露方法。
总结一下
首先贴一段正确的代码
    ::SetClassLong(GetSafeHwnd(),GCL_STYLE,::GetClassLong(m_hWnd,GCL_STYLE) | CS_DBLCLKS); \
 CDialog::OnEraseBkgnd(pDC); \
 BITMAP bm;     \
 CDC  dcMem;    \
 CBitmap Bitmap;    \
 Bitmap.LoadBitmap(unbitmap);  \
 VERIFY(Bitmap.GetObject(sizeof(BITMAP), &bm));  \
 dcMem.CreateCompatibleDC(pDC);      \
 CBitmap *pOldBmp = (CBitmap *)dcMem.SelectObject(&Bitmap);   \
 pDC->StretchBlt( x, y,width ,height, &dcMem, 0, 0, width, height , SRCCOPY ); \
 dcMem.SelectObject(pOldBmp); \
 Bitmap.DeleteObject();    \
 DeleteObject(&dcMem);
找的一段代码,写入 OnEraseBkgnd中,就可以进行简易的皮肤。开始一直怀疑这段代码有内存泄露,结果经过长时间的测试发现。这个代码相当的好,
原因有几个
   1 有SelectObject的地方,都有DeleteObject了。要不然你就等着漏吧。所以这是很重要的。
    2 创建的图片有CreateCompatibleDC,使用以后,利用DeleteObject释放。这也是必要的。这个CreateCompatibleDC可是容易引起泄露的。因为它创建出的东东是需要释放的阿。
   3 如果是系统的CDC,这个时候是不需要释放的。因为系统会帮你释放的。所以这里是不需要释放的。傻傻的我去释放了。结果显然了,崩溃,比较勤劳也不好。
然后需要补充几点,
1 如果你是通过GetWindowDC,或者GetDC,或者 BeginPaint,取到必须释放。释放方法是ReleaseDC,这时不放你的程序不会崩溃,但是却会泄露,约来越大。
2 按钮上可以直接加载图片的,Bitmap图片,这本来很好,但是你一定只能LoadBitmap一次,再LoadBitmap一次就会漏了,这时怎么办啊,很简单。把  LoadBitmap存入局部变量HBITMAP啊,这样就没问题了,只是把指针放入其中。以后调用指针就可以,不用重复加载。
最后说一下 OnCtlColor
这个东东不错,但是在使用画刷的时候要小心。
因为想要在这次用你创建的画刷,那么你就不能释放。所以必须在下一次释放。
这个是我想的方法。不知道好不好哦
反正是功能实现了,也没有漏,应该可以吧。

if(m_hbr != NULL) {
        DeleteObject((HGDIOBJ)m_hbr);
        m_hbr = NULL;
    }

 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  pDC->SetTextColor(); 
  pDC->SetBkColor();
        m_hbr=(HBRUSH)GetStockObject(10);  //  
  m_hbr=CreateSolidBrush();  
         return m_hbr;

贴一下就可以了,方便得很。

然后的问题就是如果Debug。

开始就是发现漏,也不知道谁在漏,怎么办呐,可以利用资源管理器阿,绝对的好东东阿。把GDI 对象调出来,看看句柄数就o了。剩下的以后想法子解决啊。哈哈

你可能感兴趣的:(测试,null)