GDI 对象的释放与内存泄漏的问题研究

GDI 对象的释放与内存泄漏的问题研究

最近写了一个GDI 绘图的程序,过程中遇到一个奇怪的问题,就是 定时器定时一会GDI绘的图就消失了。。后来经过分析,原来是 GDI对象数量过多 ,即GDI对象超过10000个 导致内存泄漏的问题。找到了问题所在,就好解决了,就是及时释放GDI对象。

在创建GDI对象的时候,遵循以下规则:

GetDC 得到的DC要用 ReleaseDC
CreateCompatibleDC 要用 DeleteDC

例如:
BOOL  CLogicChartCtrl::DrawBmp( CDC* pDC, CRect rect, HBITMAP hBitmap )
{
	BITMAP bm;
	GetObject(hBitmap,sizeof(bm),(VOID*)&bm);
	INT nWidth = bm.bmWidth;
	INT nHeight = bm.bmHeight;
	CDC memdc;
	memdc.CreateCompatibleDC(pDC);
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
	memdc.SelectObject(hBitmap);

	BLENDFUNCTION bf = {AC_SRC_OVER,0,255,1};
	pDC->AlphaBlend(rect.left,rect.top,nWidth,nHeight,&memdc,0,0,nWidth,nHeight,bf);
	m_bmp.Detach();
	
	DeleteObject(hBitmap);
	DeleteObject(bitmap);
	DeleteDC(memdc);

	return TRUE;
}

  所以总结使用GDI应注意GDI对象、内存泄漏、对象的释放等问题,这样可以避免很多问题,因尽量做到:

1.Create出来的gdi对象,一定要用DeleteObject来释放,释放顺序是先Create的后释放,后Create的先释放.
这里的Create指的是以它为开头的gdi函数,比如,CreateDIBitmap,CreateFont等等,最后都要调用DeleteObject来释放.

2.Create出来的dc要用DeleteDC来释放,Get到的要用ReleaseDC释放.

3.确保释放DC的时候DC中的各gdi对象都不是你自己创建的;确保个gdi对象在释放的时候不被任何dc选中使用.