diehardii
March 29th, 2005, 08:13 PM
Hi everyone,
I've got a big, big memory leak. Its occurring in the CreateOffScreeenGraphics function below. I'm relatively new at GDI+, so I'm not sure what the problem is, I'm just trying to get this double buffering to work. Thanks for the help.
cHist::cHist(CWnd* pParent /*=NULL*/)
: CDialog(cHist::IDD, pParent)
{
for(int i = 0; i<16;i++)
{
histogram[i] = i;
}
m_pMemBitmap = NULL;
m_pCachedBitmap = NULL;
m_pMemGraphics = NULL;
m_bdirty = false;
}
cHist::~cHist()
{
}
void cHist::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(cHist, CDialog)
ON_WM_SIZING()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_DESTROY()
END_MESSAGE_MAP()
// cHist message handlers
void cHist::OnSizing(UINT fwSide, LPRECT pRect)
{
CDialog::OnSizing(fwSide, pRect);
m_bdirty = true;
Invalidate();
// TODO: Add your message handler code here
}
void cHist::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
m_bdirty = true;
Invalidate();
// TODO: Add your message handler code here
}
void cHist::OnPaint()
{
CPaintDC dc(this); // device context for painting
RECT rect;
GetClientRect(&rect);
int nWidth = rect.right - rect.left + 1;
int nHeight = rect.bottom - rect.top + 1;
Graphics graphics(dc.m_hDC);
if ( ! m_pMemBitmap || m_bdirty)
{
CreateOffScreeenGraphics(nWidth, nHeight, &graphics);
m_bdirty = false;
}
// draw from cached bitmap to window
if ( graphics.DrawCachedBitmap(m_pCachedBitmap, 0, 0) != Ok )
{
// make bitmap again (display parameters are changed)
CreateOffScreeenGraphics(nWidth, nHeight, &graphics);
graphics.DrawCachedBitmap(m_pCachedBitmap, 0, 0);
}
// Graphics graphics2(dc);
//Pen pen(Color(255, 0, 0, 255));
//graphics2.DrawLine(&pen, 0, 0, 200, 100);
}
BOOL cHist::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
//return CDialog::OnEraseBkgnd(pDC);
return TRUE;
}
BOOL cHist::OnInitDialog()
{
CDialog::OnInitDialog();
CClientDC dc(this); // device context for painting
//Initialize GDI+
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void cHist::OnDestroy()
{
CDialog::OnDestroy();
//Shutdown GDI+
if ( m_pMemGraphics )
delete m_pMemGraphics;
if ( m_pMemBitmap )
delete m_pMemBitmap;
if ( m_pCachedBitmap )
delete m_pCachedBitmap;
GdiplusShutdown(m_gdiplusToken);
// TODO: Add your message handler code here
}
// create off-screen graphics and draw to it
void cHist::CreateOffScreeenGraphics(int nWidth, int nHeight, Graphics* pGraphics)
{
// Create off-screen bitmap
if(m_pMemBitmap)
{
delete m_pMemBitmap;
m_pMemBitmap = NULL;
}
m_pMemBitmap = new Bitmap(nWidth, nHeight);
// Create off-screen graphics
m_pMemGraphics = Graphics::FromImage(m_pMemBitmap);
// draw to off-screen graphics
Draw(m_pMemGraphics, nWidth, nHeight);
// Create cashed bitmap
if(m_pCachedBitmap)
{
delete m_pCachedBitmap;
m_pCachedBitmap = NULL;
}
m_pCachedBitmap = new CachedBitmap(m_pMemBitmap, pGraphics);
}
// draw lines to Graphics
void cHist::Draw(Graphics* pGraphics, int nWidth, int nHeight)
{
// fill background
SolidBrush solidBrush(Color(255, 255, 255));
pGraphics->FillRectangle(&solidBrush, 0, 0, nWidth, nHeight);
Pen pen(Color(255, 0, 0, 255));
int nStep, i;
int nLines = 2;
// draw horizontal lines
nStep = nHeight / nLines;
for ( i = 0; i < nLines; i++ )
{
pGraphics->DrawLine(&pen, 0, nStep*i, nWidth, nStep*i);
}
// draw vertical lines
nStep = nWidth / nLines;
for ( i = 0; i < nLines; i++ )
{
pGraphics->DrawLine(&pen, nStep*i, 0, nStep*i, nHeight);
}
}
I've got a big, big memory leak. Its occurring in the CreateOffScreeenGraphics function below. I'm relatively new at GDI+, so I'm not sure what the problem is, I'm just trying to get this double buffering to work. Thanks for the help.
cHist::cHist(CWnd* pParent /*=NULL*/)
: CDialog(cHist::IDD, pParent)
{
for(int i = 0; i<16;i++)
{
histogram[i] = i;
}
m_pMemBitmap = NULL;
m_pCachedBitmap = NULL;
m_pMemGraphics = NULL;
m_bdirty = false;
}
cHist::~cHist()
{
}
void cHist::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(cHist, CDialog)
ON_WM_SIZING()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_DESTROY()
END_MESSAGE_MAP()
// cHist message handlers
void cHist::OnSizing(UINT fwSide, LPRECT pRect)
{
CDialog::OnSizing(fwSide, pRect);
m_bdirty = true;
Invalidate();
// TODO: Add your message handler code here
}
void cHist::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
m_bdirty = true;
Invalidate();
// TODO: Add your message handler code here
}
void cHist::OnPaint()
{
CPaintDC dc(this); // device context for painting
RECT rect;
GetClientRect(&rect);
int nWidth = rect.right - rect.left + 1;
int nHeight = rect.bottom - rect.top + 1;
Graphics graphics(dc.m_hDC);
if ( ! m_pMemBitmap || m_bdirty)
{
CreateOffScreeenGraphics(nWidth, nHeight, &graphics);
m_bdirty = false;
}
// draw from cached bitmap to window
if ( graphics.DrawCachedBitmap(m_pCachedBitmap, 0, 0) != Ok )
{
// make bitmap again (display parameters are changed)
CreateOffScreeenGraphics(nWidth, nHeight, &graphics);
graphics.DrawCachedBitmap(m_pCachedBitmap, 0, 0);
}
// Graphics graphics2(dc);
//Pen pen(Color(255, 0, 0, 255));
//graphics2.DrawLine(&pen, 0, 0, 200, 100);
}
BOOL cHist::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
//return CDialog::OnEraseBkgnd(pDC);
return TRUE;
}
BOOL cHist::OnInitDialog()
{
CDialog::OnInitDialog();
CClientDC dc(this); // device context for painting
//Initialize GDI+
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void cHist::OnDestroy()
{
CDialog::OnDestroy();
//Shutdown GDI+
if ( m_pMemGraphics )
delete m_pMemGraphics;
if ( m_pMemBitmap )
delete m_pMemBitmap;
if ( m_pCachedBitmap )
delete m_pCachedBitmap;
GdiplusShutdown(m_gdiplusToken);
// TODO: Add your message handler code here
}
// create off-screen graphics and draw to it
void cHist::CreateOffScreeenGraphics(int nWidth, int nHeight, Graphics* pGraphics)
{
// Create off-screen bitmap
if(m_pMemBitmap)
{
delete m_pMemBitmap;
m_pMemBitmap = NULL;
}
m_pMemBitmap = new Bitmap(nWidth, nHeight);
// Create off-screen graphics
m_pMemGraphics = Graphics::FromImage(m_pMemBitmap);
// draw to off-screen graphics
Draw(m_pMemGraphics, nWidth, nHeight);
// Create cashed bitmap
if(m_pCachedBitmap)
{
delete m_pCachedBitmap;
m_pCachedBitmap = NULL;
}
m_pCachedBitmap = new CachedBitmap(m_pMemBitmap, pGraphics);
}
// draw lines to Graphics
void cHist::Draw(Graphics* pGraphics, int nWidth, int nHeight)
{
// fill background
SolidBrush solidBrush(Color(255, 255, 255));
pGraphics->FillRectangle(&solidBrush, 0, 0, nWidth, nHeight);
Pen pen(Color(255, 0, 0, 255));
int nStep, i;
int nLines = 2;
// draw horizontal lines
nStep = nHeight / nLines;
for ( i = 0; i < nLines; i++ )
{
pGraphics->DrawLine(&pen, 0, nStep*i, nWidth, nStep*i);
}
// draw vertical lines
nStep = nWidth / nLines;
for ( i = 0; i < nLines; i++ )
{
pGraphics->DrawLine(&pen, nStep*i, 0, nStep*i, nHeight);
}
}