Click here to get back home

custom CBitmap class

 HomeNewsGroups | Search | About
 microsoft.public.smartphone.developer    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
custom CBitmap class Lisa Pearlson 07-18-2005
Posted by Lisa Pearlson on July 18, 2005, 3:50 am
Please log in for more thread options
In an effort to make it easier for me to work with bitmaps, without MFC or
ATL, I created this class.
Nothing spectacular, but I'm wondering if this leaks memory or needs
improvement.

The thing I find most ugly in writing classes to use with native code, is
the HINSTANCE required for many functions.. getting this HINSTANCE seems to
be done by storing this in a global variable and refencing it.
I store it in

HINSTANCE g_hInst;

This isn't very portable, because my classes then need to reference to this
by defining

extern HINSTANCE g_hInst;

Shouldn't there be a way to get the instance handle through some API's
instead ?

Anyway, most important is to make sure this class is usable and doesn't leak
any memory.

Lisa



// Bitmap.h: interface for the CBitmap class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_BITMAP_H__14C7E26D_7024_4B10_A80A_CB4789F4F6E0__INCLUDED_)
#define AFX_BITMAP_H__14C7E26D_7024_4B10_A80A_CB4789F4F6E0__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CBitmap
{
public:
HBITMAP GetBitmapHandle();
BITMAP* GetBitmapPtr();
BOOL DrawBitmap(int x, int y);
BOOL LoadImageResource(UINT nResourceId);
void Detach();
BOOL Attach(HDC hDC);
CBitmap();
virtual ~CBitmap();

protected:
BITMAP m_Bitmap;
HDC m_hMemDC;
HDC m_hDC;
HBITMAP m_hBitmap;
};

#endif //
!defined(AFX_BITMAP_H__14C7E26D_7024_4B10_A80A_CB4789F4F6E0__INCLUDED_)



// Bitmap.cpp: implementation of the CBitmap class.
//
//////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <windowsx.h>
#include <aygshell.h>
#include "Bitmap.h"

extern HINSTANCE g_hInst;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBitmap::CBitmap()
: m_hBitmap(NULL), m_hMemDC(NULL)
{

}

CBitmap::~CBitmap()
{
if (m_hMemDC)
Detach();
}

BOOL CBitmap::Attach(HDC hDC)
{
if (m_hMemDC)
Detach();
m_hDC = hDC;
m_hMemDC = ::CreateCompatibleDC(hDC);
return (BOOL) m_hMemDC;
}

void CBitmap::Detach()
{
::DeleteObject(m_hMemDC);
m_hMemDC = NULL;
}

BOOL CBitmap::LoadImageResource(UINT nResourceId)
{
if (m_hBitmap)
::DeleteObject(m_hBitmap);
m_hBitmap = ::SHLoadImageResource(g_hInst, nResourceId);
::GetObject(m_hBitmap, sizeof(BITMAP), &m_Bitmap);
return (BOOL) m_hBitmap;
}

BOOL CBitmap::DrawBitmap(int x, int y)
{
if (!m_hMemDC || !m_hBitmap)
return FALSE;
HGDIOBJ hOld = ::SelectObject(m_hMemDC, m_hBitmap);
::BitBlt(m_hDC, x, y, m_Bitmap.bmWidth, m_Bitmap.bmHeight,
m_hMemDC, 0, 0, SRCCOPY);
::SelectObject(m_hMemDC, hOld);
return TRUE;
}

BITMAP* CBitmap::GetBitmapPtr()
{
return &m_Bitmap;
}

HBITMAP CBitmap::GetBitmapHandle()
{
return m_hBitmap;
}




Posted by riki on July 18, 2005, 3:33 pm
Please log in for more thread options
Lisa Pearlson wrote:
> Shouldn't there be a way to get the instance handle through some API's
> instead ?
GetModuleHandle(NULL);
works if the code is in the .exe, if it's in a dll, you need to pass in
the dll name, which is icky.

> CBitmap::CBitmap()
> : m_hBitmap(NULL), m_hMemDC(NULL)
why not:
: m_hBitmap(NULL), m_hMemDC(NULL), hDC(NULL)

> CBitmap::~CBitmap()
> {
> if (m_hMemDC)
> Detach();
> }
why not:
if (m_hBitmap) {
DeleteObject(m_hBitmap);
m_hBitmap =0;
}
I assume the bitmap lives longer than this class? Personally i like to
have the class that creates a resource, destroy/clean it up too.
Does m_Bitmap need to be cleaned up? i can't remember and don't have a
good reference on my desk.

> BOOL CBitmap::Attach(HDC hDC)
> {
> if (m_hMemDC)
> Detach();
> m_hDC = hDC;
> m_hMemDC = ::CreateCompatibleDC(hDC);
> return (BOOL) m_hMemDC;
> }
>
> void CBitmap::Detach()
> {
> ::DeleteObject(m_hMemDC);
shouldn't this be DeleteDC()

> m_hMemDC = NULL;
> }

riki



Small minds discuss people,Average minds discuss events,Great minds
discuss ideas.
By Night:
ThemeChanger for Smartphone : http://homepages.inspire.net.nz/~gambit/
AbstractStart for Smartphone :
http://homepages.inspire.net.nz/~gambit/AbstractStart/
By Day: http://www.EmbeddedFusion.com


Posted by Lisa Pearlson on July 18, 2005, 5:40 am
Please log in for more thread options
I don't think the bitmap is supposed to live beyond that class.. the bitmap
lives in the resource. The CBitmap loads the image from resource, so I think
that this class should also be responsible for unloading (destroying) all
that is related to loading it.

I don't think BITMAP needs to be cleaned up.. I think it's just a struct
that gets filled in, pointing to the bitmap data somewhere in memory, to
which HBITMAP points to.. The BITMAP structure doesn't contain any data that
needs deletion. It has a pointer to the bitmap bits, but doesn't copy these
bits. All the data gets deleted when the bitmap handle is deleted, I think..

I don't know about the DeleteObject versus DeleteDC on the DC.
When I run my project in debug mode, and close the application, shouldn't
the IDE report memory leaks? Or are GDI resources tricky?



> Lisa Pearlson wrote:
>> Shouldn't there be a way to get the instance handle through some API's
>> instead ?
> GetModuleHandle(NULL);
> works if the code is in the .exe, if it's in a dll, you need to pass in
> the dll name, which is icky.
>
>> CBitmap::CBitmap()
>> : m_hBitmap(NULL), m_hMemDC(NULL)
> why not:
> : m_hBitmap(NULL), m_hMemDC(NULL), hDC(NULL)
>
>> CBitmap::~CBitmap()
>> {
>> if (m_hMemDC)
>> Detach();
>> }
> why not:
> if (m_hBitmap) {
> DeleteObject(m_hBitmap);
> m_hBitmap =0;
> }
> I assume the bitmap lives longer than this class? Personally i like to
> have the class that creates a resource, destroy/clean it up too.
> Does m_Bitmap need to be cleaned up? i can't remember and don't have a
> good reference on my desk.
>
>> BOOL CBitmap::Attach(HDC hDC)
>> {
>> if (m_hMemDC)
>> Detach();
>> m_hDC = hDC;
>> m_hMemDC = ::CreateCompatibleDC(hDC);
>> return (BOOL) m_hMemDC;
>> }
>>
>> void CBitmap::Detach()
>> {
>> ::DeleteObject(m_hMemDC);
> shouldn't this be DeleteDC()
>
>> m_hMemDC = NULL;
>> }
>
> riki
>
>
>
> Small minds discuss people,Average minds discuss events,Great minds
> discuss ideas.
> By Night:
> ThemeChanger for Smartphone : http://homepages.inspire.net.nz/~gambit/
> AbstractStart for Smartphone :
> http://homepages.inspire.net.nz/~gambit/AbstractStart/
> By Day: http://www.EmbeddedFusion.com




Posted by riki on July 18, 2005, 3:54 pm
Please log in for more thread options
Lisa Pearlson wrote:
> I don't think BITMAP needs to be cleaned up.. I think it's just a struct
> that gets filled in, pointing to the bitmap data somewhere in memory, to
> which HBITMAP points to.. The BITMAP structure doesn't contain any data that
> needs deletion. It has a pointer to the bitmap bits, but doesn't copy these
> bits. All the data gets deleted when the bitmap handle is deleted, I think..
yeah, thats whats in my mind too.

> I don't know about the DeleteObject versus DeleteDC on the DC.
> When I run my project in debug mode, and close the application, shouldn't
> the IDE report memory leaks? Or are GDI resources tricky?

if only it was that easy! you need to use entrek to track that kinda
stuff. for a simple test see if DeleteObject is returning an error, but
i believe you need to use DeleteDC()

riki



"Sweater, n.: A garment worn by a child when its mother feels chilly."
By Night:
ThemeChanger for Smartphone : http://homepages.inspire.net.nz/~gambit/
AbstractStart for Smartphone :
http://homepages.inspire.net.nz/~gambit/AbstractStart/
By Day: http://www.EmbeddedFusion.com


Posted by Lisa Pearlson on July 18, 2005, 6:26 am
Please log in for more thread options
>> I don't know about the DeleteObject versus DeleteDC on the DC.
>> When I run my project in debug mode, and close the application, shouldn't
>> the IDE report memory leaks? Or are GDI resources tricky?
>
> if only it was that easy! you need to use entrek to track that kinda
> stuff. for a simple test see if DeleteObject is returning an error, but i
> believe you need to use DeleteDC()
>
> riki


You're right, I need to call DeleteDC.
I think a "GetDC" must be followed with "ReleaseDC", a "SelectObject" with a
"DeleteObject" and a "CreateDC" with a "DeleteDC"

As for memory leaks.. it used to be that if I created objects with "new"
operator and didn't delete them, that the debugger would dump memory leaks..
Perhaps I am mistaken with Visual C++ 6 for desktop development, but I
thought eVC 3 had it too, and so I'm sure eVC 4 does also. Doesn't detect
everything, but some things it did.

"Memory leak detected! Dumping object -> " or something would it say.
Uh well.

Thanks for your help :)
Lisa




Similar ThreadsPosted
Class not registered May 14, 2008, 5:05 am
FileSystemWatcher class for NetFramework2 August 11, 2005, 12:52 am
Can’t override BACK key with Class Specified March 1, 2006, 7:32 pm
Class: method or internal procedure ??? May 17, 2007, 11:43 am
Re: Why does this Backlight turn on/off class not work on my device March 29, 2007, 7:57 am
Activate previous instance and delay/dialog class name December 13, 2005, 7:48 am
Using AlternateView class works for Windows Mobile but not Blackbe October 12, 2007, 3:46 pm
Custom Setup.dll July 6, 2005, 9:26 pm
launch custom.cpl.xml February 14, 2007, 4:13 pm
Custom ring tone June 5, 2005, 10:50 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap