
Memory leak when using Memory DC
Hello friends,
Here is code I am using to draw bitmaps. It gives memory problem
when called again and again. It works fine without Memory DC. Please
help to sort out the problem :
//-----------------------------------------------------------------------------
//Function : DrawImage.
//
//Arguments : 1)CDC *pDC : Pointer to DC in which the image will be
drawn.
// 2)CRect crect: Client area of DC.
// 3)CRect &crectToView : Reference to rect that contains the
area
// of image to view.
//
//Purpose : This function will draw the bitmap on client area of the
// main window.To create flicker free drawing first a memory dc
is
// created.It is first painted with window color of current
window
// setings. Then the bitmap is drawn on memory dc.Then the
memory
// is drawn on screen dc.
//
//Return : TRUE if sucessful.
//-----------------------------------------------------------------------------
BOOL CImage::DrawImage(CDC *pDC, CRect& crect, CRect& crectToView)
{
int nImageWidth = GetWidth(); //Get image width.
int nImageHeight = GetHeight(); //Get image height.
_ASSERT(pDC);
//Check if memory DC is required.
if(IsMemDCRequired(crect, crectToView)){
CDC cdcMem; //Memory dc compatible with screen dc.
CBitmap cbmpComp; //Handle to bitmap compatible with
//screen dc.
CBrush cbrush; //Handle to brush.
CBrush cbrushOld; //Handle to old brush which is used
//to select it again in device context.
CBitmap *cbmpOld; //To hold the old bitmap in the hdc.
//Create compatible DC and bitmap.
cdcMem.CreateCompatibleDC(pDC) ;
//Create compatible bitmap from main DC.
cbmpComp.CreateCompatibleBitmap(pDC,
max((int)(nImageWidth * m_fZoomRatio), crect.right),
max((int)(nImageHeight * m_fZoomRatio), crect.bottom));
cbmpOld = cdcMem.SelectObject(&cbmpComp);
//To paint memory dc with system window color.
BOOL chk = cbrush.CreateSolidBrush(GetSysColor(COLOR_WINDOW));
//To paint background of memory DC.
RECT rtTemp;
rtTemp.left = rtTemp.top = 0;
rtTemp.right = max((int)(nImageWidth * m_fZoomRatio),
crect.right);
rtTemp.bottom = max((int)(nImageHeight * m_fZoomRatio),
crect.bottom);
//Paint the background with the system window color.
cdcMem.FillRect(&rtTemp, &cbrush);
//Select the palette for the image in the memory DC.
HPALETTE hOldPalMemDC =
::SelectPalette(cdcMem.GetSafeHdc(),m_hPalette, FALSE);
::RealizePalette(cdcMem.GetSafeHdc());
//Draw bitmap on memory dc.
if(m_pBits != NULL ){
//Call a function to draw the image on memory DC.
SetBitsToDC(&cdcMem, crectToView);
}
//Copy the contains of memory dc to screen dc.
pDC->BitBlt( 0 , 0 ,
max((int)(nImageWidth * m_fZoomRatio), crect.right),
max((int)(nImageHeight * m_fZoomRatio), crect.bottom),
&cdcMem, 0, 0, SRCCOPY);
//Select old objects.
cdcMem.SelectObject(&cbmpOld);
::SelectPalette(cdcMem.GetSafeHdc(),hOldPalMemDC,FALSE);
}
//If memory DC is not required.
else{
//Call a fucntion that will draw the image on screen or printer
//DC( DC other than the Memory DC.
SetBitsToDC(pDC, crectToView);
}
return TRUE;
Quote:
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Function :SetBItsToDC.
//
//Arguments:1)CDC *pDC : Pointer to device contest on which the iamge
is drawn.
// 2)CRect &crectToView :ROI of image.
//
//Purpose :This fuction sets the pixel bits on the device context.
//
//Returns :TRUE.
//-----------------------------------------------------------------------------
BOOL CImage::SetBitsToDC(CDC* pDC, CRect &crectToView)
{
_ASSERT(pDC);
//If image is to be shown in unzoomed condition.
if(m_fZoomRatio == 1){
::SetDIBitsToDevice(pDC->GetSafeHdc(),
0 ,
0,
crectToView.right - crectToView.left,
crectToView.bottom,
crectToView.left,
m_pBitmapInfo->bmiHeader.biHeight -
crectToView.bottom,
0,
m_pBitmapInfo->bmiHeader.biHeight -
crectToView.top,
m_pBits,
m_pBitmapInfo,
DIB_PAL_COLORS);
}// if the image is to be displayed zoomed.
else {
::StretchDIBits(pDC->GetSafeHdc(),
0,
0,
(int)(m_pBitmapInfo->bmiHeader.biWidth *m_fZoomRatio),
(int)(m_pBitmapInfo->bmiHeader.biHeight *m_fZoomRatio),
0,
0,
m_pBitmapInfo->bmiHeader.biWidth,
m_pBitmapInfo->bmiHeader.biHeight,
m_pBits,
m_pBitmapInfo,
DIB_PAL_COLORS,
SRCCOPY);
}
return TRUE;
Quote:
}
//-----------------------------------------------------------------------------
CMemoryState's object shows no memory leak but still my machine gets
hanged saying that short of memory.
I shall be grateful to the reply.
With regards,
Sunil