最近寫了一個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選中使用.