Link to home
Start Free TrialLog in
Avatar of Morten from Eliten
Morten from Eliten

asked on

Getting a CBitmap from a HBITMAP, using FromHandle()

I need to get a CBitmap from a HBITMAP, and to be able to delete my CBitmap again, when I need to.

My code looks like this:

class SomeClass
{
   CBitmap *m_bmpBitmap;

   SomeFunction();
   ~SomeClass();
};


SomeClass::SomeFunction()
{
HBITMAP hBitmap;

hBitmap=(HBITMAP) LoadImage(NULL, "BitmapName.Bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
m_bmpBitmap=new CBitmap();
m_bmpBitmap=CBitmap::FromHandle(hBitmap);
}

SomeClass::SomeClass()
{
   delete m_bmpBitmap;
}

My problem is that when I come to the Destructor, and want to delete the m_bmpBitmap again, my program crashes, becourse the CBitmap is attached to a HBITMAP, and I don't know how to detach it again.

How do delete my m_bmpBitmap in a proper way (So that it won't cause the program to crash) ?
Avatar of Norbert
Norbert
Flag of Germany image

Not rearly clear what your problem is but
You should initialisize pointers to 'valid' value
Constructor:
SomeClass::SomeClass()
{
    m_bmpBitmap=NULL;
}
Destructor:
SomeClass::~SomeClass()
{
  if(m_bmpBitmap)
         delete m_bmpBitmap;
}
now SomeFunction
SomeClass::SomeFunction()
{
HBITMAP hBitmap;

hBitmap=(HBITMAP) LoadImage(NULL, "BitmapName.Bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
//m_bmpBitmap=new CBitmap(); NOT NEEDED and Produces MEMORY LEAKS !!!!
if(m_bmpBitmap)
    delete m_bmpBitmap;
m_bmpBitmap=CBitmap::FromHandle(hBitmap);
}

Some OtherFunction
SomeClass::OtherFunction()
{
     if(bmpNoMoreNeeded)
    {
        if(m_bmpBitmap)
        {
            delete m_bmpBitmap
            m_bmpBitmap=NULL;
        }
    }
}

that should prevent double deleting the same pointer
Regarding Norbert's code, don't delete m_bmpBitmap returned by CBitmap::FromHandle. It will be deleted automatically at idle time. So, the pointer returned by CBitmap::FromHandle may be invalid outside SomeClass::SomeFunction(). You can do it in this way.

class SomeClass
{
   CBitmap *m_bmpBitmap;

   SomeFunction();
   ~SomeClass();
};


SomeClass::SomeFunction()
{
HBITMAP hBitmap;

hBitmap=(HBITMAP) LoadImage(NULL, "BitmapName.Bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
m_bmpBitmap=new CBitmap();
m_bmpBitmap->Attach(hBitmap);
}

SomeClass::~SomeClass()
{
   ::DeleteObject(m_bmpBitmap->Detach());
   delete m_bmpBitmap;
}

To be safer, remember to check the return value of each function called.
Avatar of Morten from Eliten
Morten from Eliten

ASKER

Hey, chensu !
Propose that as an answer, and you've earned yourself 30 points.

That was great !
ASKER CERTIFIED SOLUTION
Avatar of chensu
chensu
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial