iks1
asked on
Memory DC + BitBlt to Screen...
I have an object Cbla and it has two methods: PaintToMemDC and PaintFromMemDCToScreen:
CDC memDC is protected member of Cbla.
void Cbla::PaintToMemDC(CPaintD C *pdc){
memDC.CreateCompatibleDC(p dc);
CBitmap bitmap;
bitmap.CreateCompatibleBit map(pdc, 100, 100);
CBitmap *oldBitmap = (CBitmap*)memDC.SelectObje ct(&bitmap );
memDC.MoveTo(0,0); memDC.LineTo(100,100);
//memDC.SelectObject(oldBi tmap);
}
And:
void Cbla::PaintFromMemDCToScre en(CPaintD C *pdc)
{
pdc->BitBlt(rand()%150, rand()%150, 100, 100, &memDC, 0, 0, MERGECOPY);
}
I hope that names tells enough.
Obvioulsy since "memDC.SelectObject(oldBit map);" is commented it will gain a memory leak. But this is the only way I can get that everything on the screen works right: memDCs are sucesfully created in PaintToMemDC method and loaded to the screen in PaintFromMemDCToScreen.
As soon as I uncomment there is no more memory leak but PaintFromMemDCToScreen draws black or random color objects. So something goes totally wrong.
How can I fix this? I just want create some glyphs in PaintToMemDC, save them in memory (CDC or whatever possible) and draw them laterer using PaintFromMemDCToScreen.
Thanks,
-Andrej
CDC memDC is protected member of Cbla.
void Cbla::PaintToMemDC(CPaintD
memDC.CreateCompatibleDC(p
CBitmap bitmap;
bitmap.CreateCompatibleBit
CBitmap *oldBitmap = (CBitmap*)memDC.SelectObje
memDC.MoveTo(0,0); memDC.LineTo(100,100);
//memDC.SelectObject(oldBi
}
And:
void Cbla::PaintFromMemDCToScre
{
pdc->BitBlt(rand()%150, rand()%150, 100, 100, &memDC, 0, 0, MERGECOPY);
}
I hope that names tells enough.
Obvioulsy since "memDC.SelectObject(oldBit
As soon as I uncomment there is no more memory leak but PaintFromMemDCToScreen draws black or random color objects. So something goes totally wrong.
How can I fix this? I just want create some glyphs in PaintToMemDC, save them in memory (CDC or whatever possible) and draw them laterer using PaintFromMemDCToScreen.
Thanks,
-Andrej
A agree with AlexFM. The CBitmap on which you have done your drawing will be destroyed upon exiting the PaintToMemDC() function. That is equivallent to drawing on a sketchpad, then throwing the top page into the trash... and then wondering why you can no longer see your lovely sketch :-)
If the CBitmap persists... normally by making it part of your class object -- then your drawing will continue to exist when you want to transfer it to the screen. Once you have blitted to the screen, you can use
m_bitmap.DeleteObject()
to avoid the memory leak.
If the CBitmap persists... normally by making it part of your class object -- then your drawing will continue to exist when you want to transfer it to the screen. Once you have blitted to the screen, you can use
m_bitmap.DeleteObject()
to avoid the memory leak.
ASKER
Hi guys,
Thank you for the answers...
So I changed my methods to:
void Cbla::PaintFromMemDCToScre en(CPaintD C *pdc)
void Cbla::PaintToMemDC(CPaintD C *pdc)
and I agree that this is a good idea.
I also moved:
CDC m_memDC
CBitmap m_bitmap
CBitmap *m_pOldMemDCBitmap
under private class declarations and my both methods now look like this:
void Cbla::PaintToMemDC(CDC *pdc){
m_memDC.CreateCompatibleDC (pdc);
m_bitmap.CreateCompatibleB itmap(pdc, 100, 100);
m_oldBitmap = (CBitmap*)m_memDC.SelectOb ject(&m_bi tmap);
m_memDC.MoveTo(0,0); m_memDC.LineTo(100,100);
//memDC.SelectObject(oldBi tmap);
}
And:
void Cbla::PaintFromMemDCToScre en(CDC *pdc)
{
pdc->BitBlt(rand()%150, rand()%150, 100, 100, &m_memDC, 0, 0, SRCCOPY);
}
This code works just like it worked before (in my first post) and is still leading to a memory leak although I also do m_bitmap.DeleteObject() in my own Cbla::Destroy() method and in Cbla::~Cbla() destructor.
In this case I would really like to destroy everything in my Destroy() method... So what can I do?
And I can't move memDC.CreateCompatibleDC(p dc) to constructor since I am making an array of this objects like this:
void CTestDraw1Dlg::OnPaint(){
CPaintDC dc(this); // Device context for painting
...
Cbla *bla;
bla=new Cbla[500];
...
for (i=0; i<500;i++){
bla[i].PaintToMemDC(&dc);
}
...
}
Thanks again,
-Andrej
Thank you for the answers...
So I changed my methods to:
void Cbla::PaintFromMemDCToScre
void Cbla::PaintToMemDC(CPaintD
and I agree that this is a good idea.
I also moved:
CDC m_memDC
CBitmap m_bitmap
CBitmap *m_pOldMemDCBitmap
under private class declarations and my both methods now look like this:
void Cbla::PaintToMemDC(CDC *pdc){
m_memDC.CreateCompatibleDC
m_bitmap.CreateCompatibleB
m_oldBitmap = (CBitmap*)m_memDC.SelectOb
m_memDC.MoveTo(0,0); m_memDC.LineTo(100,100);
//memDC.SelectObject(oldBi
}
And:
void Cbla::PaintFromMemDCToScre
{
pdc->BitBlt(rand()%150, rand()%150, 100, 100, &m_memDC, 0, 0, SRCCOPY);
}
This code works just like it worked before (in my first post) and is still leading to a memory leak although I also do m_bitmap.DeleteObject() in my own Cbla::Destroy() method and in Cbla::~Cbla() destructor.
In this case I would really like to destroy everything in my Destroy() method... So what can I do?
And I can't move memDC.CreateCompatibleDC(p
void CTestDraw1Dlg::OnPaint(){
CPaintDC dc(this); // Device context for painting
...
Cbla *bla;
bla=new Cbla[500];
...
for (i=0; i<500;i++){
bla[i].PaintToMemDC(&dc);
}
...
}
Thanks again,
-Andrej
ASKER
Sorry (copy/paste problem):
So I changed my methods to:
void Cbla::PaintFromMemDCToScre en(CDC *pdc)
void Cbla::PaintToMemDC(CDC *pdc)
Thanks,
-Andrej
So I changed my methods to:
void Cbla::PaintFromMemDCToScre
void Cbla::PaintToMemDC(CDC *pdc)
Thanks,
-Andrej
>> And I can't move memDC.CreateCompatibleDC(p dc) to constructor.
Why?
Why?
ASKER
AlexFM,
Sorry I am pretty much new to C so this could be done differently but I dont know how...
I am creating an array of my Cbla objects like this:
Cbla *bla;
bla=new Cbla[500];
...
for (i=0; i<500;i++){
bla[i].PaintToMemDC(&dc);
}
and as I change my default contructor from Cbla::Cbla() to Cbla::Cbla(CDC *pdc) the compiler complains:
>> error C2512: 'Cbla' : no appropriate default constructor available...
So shuld I leave this constructor alone and create another one with (CDC *pdc) and call it later? Isnt it pretty much the same then if I call PaintToMemDC later?
Or is there a chance to call this new constructor in my case?
Maybe I got all this array of objects initialization wrong...
Thanks again,
-Andrej
Sorry I am pretty much new to C so this could be done differently but I dont know how...
I am creating an array of my Cbla objects like this:
Cbla *bla;
bla=new Cbla[500];
...
for (i=0; i<500;i++){
bla[i].PaintToMemDC(&dc);
}
and as I change my default contructor from Cbla::Cbla() to Cbla::Cbla(CDC *pdc) the compiler complains:
>> error C2512: 'Cbla' : no appropriate default constructor available...
So shuld I leave this constructor alone and create another one with (CDC *pdc) and call it later? Isnt it pretty much the same then if I call PaintToMemDC later?
Or is there a chance to call this new constructor in my case?
Maybe I got all this array of objects initialization wrong...
Thanks again,
-Andrej
ASKER
Okay,
Cbla bla[10]={&dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc};
might be also okay but how do I do this for like 500 times? :)
Thanks,
-Andrej
Cbla bla[10]={&dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc};
might be also okay but how do I do this for like 500 times? :)
Thanks,
-Andrej
OK, leave constructor empty and change PaintToMemDC so that it initializes data first time when called:
void Cbla::PaintToMemDC(CDC *pdc)
{
if ( ! m_memDC.m_hDC )
{
m_memDC.CreateCompatibleDC (pdc);
m_bitmap.CreateCompatibleB itmap(pdc, 100, 100);
m_oldBitmap = (CBitmap*)m_memDC.SelectOb ject(&m_bi tmap);
}
m_memDC.MoveTo(0,0); m_memDC.LineTo(100,100);
}
Restore old bitmap in class destructor.
void Cbla::PaintToMemDC(CDC *pdc)
{
if ( ! m_memDC.m_hDC )
{
m_memDC.CreateCompatibleDC
m_bitmap.CreateCompatibleB
m_oldBitmap = (CBitmap*)m_memDC.SelectOb
}
m_memDC.MoveTo(0,0); m_memDC.LineTo(100,100);
}
Restore old bitmap in class destructor.
BTW, &dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc, &dc 500 times is good idea, I like it :)
ASKER
AlexFM,
I did what you suggested... but it is still leaking :(
If I don't do:
m_memDC.SelectObject(m_old Bitmap)
in the same method that I did:
m_bitmap.CreateCompatibleB itmap(pdc, xx, yy);
m_oldBitmap = (CBitmap*)m_memDC.SelectOb ject(&bitm ap);
then I got a fancy huge memory leak that sometimes don't release all the allocated memory even then when I close the application...
But if I do it (m_memDC.SelectObject(m_ol dBitmap)) - my glyphs are painted randomly :)
Is there any other way to quickly draw something on screen DC from memory? Maybe from some int array or something? Because theese bitmaps are driving me crazy...
Thanks,
-Andrej
I did what you suggested... but it is still leaking :(
If I don't do:
m_memDC.SelectObject(m_old
in the same method that I did:
m_bitmap.CreateCompatibleB
m_oldBitmap = (CBitmap*)m_memDC.SelectOb
then I got a fancy huge memory leak that sometimes don't release all the allocated memory even then when I close the application...
But if I do it (m_memDC.SelectObject(m_ol
Is there any other way to quickly draw something on screen DC from memory? Maybe from some int array or something? Because theese bitmaps are driving me crazy...
Thanks,
-Andrej
Post your code again: class and client code.
ASKER
Hi,
Here it goes:
--- bla.h -----------------------
#if !defined(AFX_BLA_H__E7A016 EB_4474_4D 53_BD4B_F9 225B307E48 __INCLUDED _)
#define AFX_BLA_H__E7A016EB_4474_4 D53_BD4B_F 9225B307E4 8__INCLUDE D_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// bla.h : header file
//
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
// Cbla window
class Cbla : public CWnd
{
// Construction
public:
Cbla();
void PaintFromMemDCToScreen(CDC *pdc);
void Destroy();
void PaintToMemDC(CDC *pdc);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(Cbla)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~Cbla();
CDC m_memDC;
CBitmap m_bitmap;
CBitmap *m_pOldMemDCBitmap;
// Generated message map functions
protected:
//{{AFX_MSG(Cbla)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_BLA_H__E7A016 EB_4474_4D 53_BD4B_F9 225B307E48 __INCLUDED _)
--------------- end of bla.h ----
--- bla.cpp ---------------------
// bla.cpp : implementation file
//
#include "stdafx.h"
#include "testdraw1.h"
#include "bla.h"
#include <Wingdi.h>
#include <Windows.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
// Cbla
Cbla::Cbla(){
}
void Cbla::PaintFromMemDCToScre en(CDC *pdc)
{
//------------------------ ---------- ---------- ------
pdc->BitBlt(rand()%150, rand()%150, 100, 100, &m_memDC, 0, 0, SRCCOPY);
//------------------------ ---------- ---------- ------
}
Cbla::~Cbla()
{
m_memDC.SelectObject(m_pOl dMemDCBitm ap);
}
void Cbla::PaintToMemDC(CDC *pdc){
CRect rcClient(0,0,100,100);
if (!m_memDC.m_hDC)
{
m_memDC.CreateCompatibleDC (pdc);
m_bitmap.CreateCompatibleB itmap(pdc, rcClient.Width(), rcClient.Height());
m_pOldMemDCBitmap = (CBitmap*)m_memDC.SelectOb ject(&m_bi tmap);
}
//------------------------ ---------- ---------- ------
m_memDC.Rectangle(CRect(0, 0,100,100) );
m_memDC.MoveTo(16,16); m_memDC.LineTo(99,99);
m_memDC.MoveTo(99,1); m_memDC.LineTo(1,99);
CString to; to.Format(_T("%d"),rand()% 100);
m_memDC.SetBkMode(TRANSPAR ENT);
m_memDC.DrawText(to, CRect (3,2,98,98), DT_NOCLIP);
//------------------------ ---------- ---------- ------
}
void Cbla::Destroy(){
m_memDC.SelectObject(m_pOl dMemDCBitm ap);
}
BEGIN_MESSAGE_MAP(Cbla, CWnd)
//{{AFX_MSG_MAP(Cbla)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
// Cbla message handlers
--------------- end of bla.cpp --
Client app - Test dialog:
--- TDlg2.h ---------------------
#if !defined(AFX_TDLG2_H__73B8 CE73_EE51_ 439A_B1F0_ 8E0060E84C AB__INCLUD ED_)
#define AFX_TDLG2_H__73B8CE73_EE51 _439A_B1F0 _8E0060E84 CAB__INCLU DED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TDlg2.h : header file
//
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
// TDlg2 dialog
class TDlg2 : public CDialog
{
// Construction
public:
TDlg2(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(TDlg2)
enum { IDD = IDD_DIALOG1 };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(TDlg2)
public:
virtual void OnFinalRelease();
protected:
virtual void DoDataExchange(CDataExchan ge* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(TDlg2)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(TDlg2)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_TDLG2_H__73B8 CE73_EE51_ 439A_B1F0_ 8E0060E84C AB__INCLUD ED_)
--------------- end of TDlg2.h --
--------------- end of TDlg2.cpp-
// TDlg2.cpp : implementation file
//
#include "stdafx.h"
#include "testdraw1.h"
#include "TDlg2.h"
#include "bla.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
// TDlg2 dialog
TDlg2::TDlg2(CWnd* pParent /*=NULL*/)
: CDialog(TDlg2::IDD, pParent)
{
EnableAutomation();
//{{AFX_DATA_INIT(TDlg2)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void TDlg2::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CDialog::OnFinalRelease();
}
void TDlg2::DoDataExchange(CDat aExchange* pDX)
{
CDialog::DoDataExchange(pD X);
//{{AFX_DATA_MAP(TDlg2)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(TDlg2, CDialog)
//{{AFX_MSG_MAP(TDlg2)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(TDlg2, CDialog)
//{{AFX_DISPATCH_MAP(TDlg2 )
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_ITDlg2 to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {041D574B-9525-4FF1-9A66-D B406E3A656 B}
static const IID IID_ITDlg2 =
{ 0x41d574b, 0x9525, 0x4ff1, { 0x9a, 0x66, 0xdb, 0x40, 0x6e, 0x3a, 0x65, 0x6b } };
BEGIN_INTERFACE_MAP(TDlg2, CDialog)
INTERFACE_PART(TDlg2, IID_ITDlg2, Dispatch)
END_INTERFACE_MAP()
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
// TDlg2 message handlers
void TDlg2::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
Cbla bla[300];
int i=0;
dc.DrawText(_T("PaintToMem DC... "),
CRect (2,2,98,98), DT_NOCLIP);
Sleep(1000);
for (i=0; i<300;i++){
bla[i].PaintToMemDC(&dc);
}
dc.DrawText(_T("PaintFromM emDCToScre en... "),
CRect (2,2,98,98), DT_NOCLIP);
Sleep(1000);
for (i=0; i<300;i++){
bla[i].PaintFromMemDCToScr een(&dc);
}
dc.DrawText(_T("Destroy... "),
CRect (2,2,98,98), DT_NOCLIP);
Sleep(1000);
/*for (i=0; i<300;i++){
bla[i].Destroy();
}*/
// Do not call CDialog::OnPaint() for painting messages
}
--- TDlg2.cpp -------------------
Thank you again,
-Andrej
Here it goes:
--- bla.h -----------------------
#if !defined(AFX_BLA_H__E7A016
#define AFX_BLA_H__E7A016EB_4474_4
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// bla.h : header file
//
//////////////////////////
// Cbla window
class Cbla : public CWnd
{
// Construction
public:
Cbla();
void PaintFromMemDCToScreen(CDC
void Destroy();
void PaintToMemDC(CDC *pdc);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(Cbla)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~Cbla();
CDC m_memDC;
CBitmap m_bitmap;
CBitmap *m_pOldMemDCBitmap;
// Generated message map functions
protected:
//{{AFX_MSG(Cbla)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_BLA_H__E7A016
--------------- end of bla.h ----
--- bla.cpp ---------------------
// bla.cpp : implementation file
//
#include "stdafx.h"
#include "testdraw1.h"
#include "bla.h"
#include <Wingdi.h>
#include <Windows.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////
// Cbla
Cbla::Cbla(){
}
void Cbla::PaintFromMemDCToScre
{
//------------------------
pdc->BitBlt(rand()%150, rand()%150, 100, 100, &m_memDC, 0, 0, SRCCOPY);
//------------------------
}
Cbla::~Cbla()
{
m_memDC.SelectObject(m_pOl
}
void Cbla::PaintToMemDC(CDC *pdc){
CRect rcClient(0,0,100,100);
if (!m_memDC.m_hDC)
{
m_memDC.CreateCompatibleDC
m_bitmap.CreateCompatibleB
m_pOldMemDCBitmap = (CBitmap*)m_memDC.SelectOb
}
//------------------------
m_memDC.Rectangle(CRect(0,
m_memDC.MoveTo(16,16); m_memDC.LineTo(99,99);
m_memDC.MoveTo(99,1); m_memDC.LineTo(1,99);
CString to; to.Format(_T("%d"),rand()%
m_memDC.SetBkMode(TRANSPAR
m_memDC.DrawText(to, CRect (3,2,98,98), DT_NOCLIP);
//------------------------
}
void Cbla::Destroy(){
m_memDC.SelectObject(m_pOl
}
BEGIN_MESSAGE_MAP(Cbla, CWnd)
//{{AFX_MSG_MAP(Cbla)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////
// Cbla message handlers
--------------- end of bla.cpp --
Client app - Test dialog:
--- TDlg2.h ---------------------
#if !defined(AFX_TDLG2_H__73B8
#define AFX_TDLG2_H__73B8CE73_EE51
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TDlg2.h : header file
//
//////////////////////////
// TDlg2 dialog
class TDlg2 : public CDialog
{
// Construction
public:
TDlg2(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(TDlg2)
enum { IDD = IDD_DIALOG1 };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(TDlg2)
public:
virtual void OnFinalRelease();
protected:
virtual void DoDataExchange(CDataExchan
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(TDlg2)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
// Generated OLE dispatch map functions
//{{AFX_DISPATCH(TDlg2)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_DISPATCH
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_TDLG2_H__73B8
--------------- end of TDlg2.h --
--------------- end of TDlg2.cpp-
// TDlg2.cpp : implementation file
//
#include "stdafx.h"
#include "testdraw1.h"
#include "TDlg2.h"
#include "bla.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////
// TDlg2 dialog
TDlg2::TDlg2(CWnd* pParent /*=NULL*/)
: CDialog(TDlg2::IDD, pParent)
{
EnableAutomation();
//{{AFX_DATA_INIT(TDlg2)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void TDlg2::OnFinalRelease()
{
// When the last reference for an automation object is released
// OnFinalRelease is called. The base class will automatically
// deletes the object. Add additional cleanup required for your
// object before calling the base class.
CDialog::OnFinalRelease();
}
void TDlg2::DoDataExchange(CDat
{
CDialog::DoDataExchange(pD
//{{AFX_DATA_MAP(TDlg2)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(TDlg2, CDialog)
//{{AFX_MSG_MAP(TDlg2)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(TDlg2, CDialog)
//{{AFX_DISPATCH_MAP(TDlg2
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
// Note: we add support for IID_ITDlg2 to support typesafe binding
// from VBA. This IID must match the GUID that is attached to the
// dispinterface in the .ODL file.
// {041D574B-9525-4FF1-9A66-D
static const IID IID_ITDlg2 =
{ 0x41d574b, 0x9525, 0x4ff1, { 0x9a, 0x66, 0xdb, 0x40, 0x6e, 0x3a, 0x65, 0x6b } };
BEGIN_INTERFACE_MAP(TDlg2,
INTERFACE_PART(TDlg2, IID_ITDlg2, Dispatch)
END_INTERFACE_MAP()
//////////////////////////
// TDlg2 message handlers
void TDlg2::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
Cbla bla[300];
int i=0;
dc.DrawText(_T("PaintToMem
CRect (2,2,98,98), DT_NOCLIP);
Sleep(1000);
for (i=0; i<300;i++){
bla[i].PaintToMemDC(&dc);
}
dc.DrawText(_T("PaintFromM
CRect (2,2,98,98), DT_NOCLIP);
Sleep(1000);
for (i=0; i<300;i++){
bla[i].PaintFromMemDCToScr
}
dc.DrawText(_T("Destroy...
CRect (2,2,98,98), DT_NOCLIP);
Sleep(1000);
/*for (i=0; i<300;i++){
bla[i].Destroy();
}*/
// Do not call CDialog::OnPaint() for painting messages
}
--- TDlg2.cpp -------------------
Thank you again,
-Andrej
ASKER
Oooops, last comments:
--------------- end of TDlg2.cpp-
and
--- TDlg2.cpp -------------------
are mistaken... Sorry :)
-Andrej
--------------- end of TDlg2.cpp-
and
--- TDlg2.cpp -------------------
are mistaken... Sorry :)
-Andrej
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Okay thanks...
I am on eMbedded VC4 and can't find CrtSetBreakAlloc function... So I was always checking for a leak using Remote Performance Monitor (WCE420) -> CE Memory Statistics -> Memory Load...
So do you have any idea how to check memory usage here?
Cbla is not derived from CWnd any more and was because I copied it out from a different project just to show the leak...
Okay you helped me enough :)
Thanks for everything...
-Andrej
I am on eMbedded VC4 and can't find CrtSetBreakAlloc function... So I was always checking for a leak using Remote Performance Monitor (WCE420) -> CE Memory Statistics -> Memory Load...
So do you have any idea how to check memory usage here?
Cbla is not derived from CWnd any more and was because I copied it out from a different project just to show the leak...
Okay you helped me enough :)
Thanks for everything...
-Andrej
You are still using CreateCompatibleBitmap without deleting the previous one. That causes a memeory leak as you overwrite one HBITMAP with another. Somewhere in your code, you need:
if ( m_bitmap.m_hObject != 0 ) {
m_bitmap.DeleteObject();
m_bitmap.m_hObject= 0;
}
This belongs in the code at a location very near to, and just before, the place where you call:
m_bitmap.CreateCompatibleB itmap(pdc, rcClient.Width(), rcClient.Height());
if ( m_bitmap.m_hObject != 0 ) {
m_bitmap.DeleteObject();
m_bitmap.m_hObject= 0;
}
This belongs in the code at a location very near to, and just before, the place where you call:
m_bitmap.CreateCompatibleB
BTW, it is better to change PaintFromMemDCToScreen to:
void Cbla::PaintFromMemDCToScre