-
January 19th, 2015, 08:57 AM
#1
[RESOLVED] [win32 and GUID/GUID+] - how avoid memory leaks?
i understand that everytime, that i create an object, i must destroy it:
HCURSOR with LoadImage() - DestroyCursor()
until here fine.
i'm doing an image class, but i have some memory leaks and i don' understand how resolve them
before continue 1 have 1 question: if the class destructor is called when the class is destroyed, why i lose the image(on menus), if i DeletObject() HBITMAP on destructor? for me, don't make sence
i'm confused why i get memory leaks, but see the class:
Code:
class image
{
private:
ULONG_PTR m_gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
HDC hdcimage=CreateCompatibleDC(NULL);
HGDIOBJ obj=NULL;
HBITMAP btBitmap;
Gdiplus::Graphics *graphic;
Image *img;
int imageheight=0;
int imageweight=0;
int framecount=0;
int intSelectFrame=0;
int framedelay=0;
string strfilename="";
Gdiplus::Color clrBackColor=Gdiplus::Color::Transparent;
HDC hdcwindow;
bool blnTransparent=true;
public:
image()
{
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
btBitmap=CreateCompatibleBitmap(hdcimage,1,1);
obj = SelectObject(hdcimage, btBitmap);
}
image(HDC hdcWindow)
{
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
hdcwindow=hdcWindow;
}
image(int width, int height)
{
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
hdcimage = CreateCompatibleDC(NULL);
btBitmap = CreateCompatibleBitmap(hdcimage,width,height);
obj = SelectObject(hdcimage, btBitmap);
framecount=1;
}
image( const string & filename)
{
strfilename=filename;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
if(toupper(filename[filename.size()-3])=='C' && toupper(filename[filename.size()-2])=='U' && toupper(filename[filename.size()-1])=='R')
{
//create the transparent icon handle
HCURSOR hicon = (HCURSOR)LoadImage(NULL, filename.c_str(), IMAGE_CURSOR, imageweight, imageheight, LR_LOADFROMFILE|LR_SHARED|LR_DEFAULTSIZE|LR_LOADTRANSPARENT);
ICONINFO ii;
BOOL fResult = GetIconInfo(hicon, &ii);
if (fResult)
{
BITMAP bm;
fResult = GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm);
if (fResult)
{
imageweight= bm.bmWidth;
imageheight= ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
}
if (ii.hbmMask) DeleteObject(ii.hbmMask);
if (ii.hbmColor) DeleteObject(ii.hbmColor);
}
btBitmap=CreateBitmap(imageweight,imageheight,1,32,NULL);//create the bitmap with icon size
obj = SelectObject(hdcimage, btBitmap);//add the bitmap to memory DC
DrawIconEx(hdcimage,0,0,hicon,imageweight,imageheight,0,0,DI_NORMAL);//draw the icon to DC with right size
//seems the DrawIcon(), always, draw it with 32X32 size
framecount=1;
DestroyCursor(hicon);
}
else
{
Gdiplus::Image img2(towstring(filename).c_str());
btBitmap=CreateBitmap(img2.GetWidth(),img2.GetHeight(),1,32,NULL);
obj = SelectObject(hdcimage, btBitmap);
Gdiplus::Graphics graphics(hdcimage);
graphics.DrawImage(&img2, 0, 0, img2.GetWidth(), img2.GetHeight());
imageweight=img2.GetWidth();
imageheight=img2.GetHeight();
UINT count = 0;
count = img2.GetFrameDimensionsCount();
GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
img2.GetFrameDimensionsList(pDimensionIDs, count);
framecount=img2.GetFrameCount(&pDimensionIDs[0]);
if (framecount>1)
framedelay =img2.GetPropertyItemSize(PropertyTagFrameDelay);
else
framedelay =0;
img=new Image(towstring(filename).c_str());
free(pDimensionIDs);
}
}
image (const image &cSource)
{
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
framecount=cSource.framecount;
framedelay=cSource.framedelay;
clrBackColor=cSource.clrBackColor;
img=cSource.img->Clone();
imageweight=cSource.imageweight;
imageheight=cSource.imageheight;
strfilename=cSource.strfilename;
btBitmap=CreateBitmap(imageweight,imageweight,1,32,NULL);
obj = SelectObject(hdcimage, btBitmap);
BitBlt(hdcimage,0,0,imageweight,imageheight,cSource.hdcimage,0,0,SRCCOPY);
}
image& operator= (const image &cSource)
{
framecount=cSource.framecount;
framedelay=cSource.framedelay;
intSelectFrame=cSource.intSelectFrame;
clrBackColor=cSource.clrBackColor;
imageweight=cSource.imageweight;
imageheight=cSource.imageheight;
btBitmap=CreateBitmap(imageweight,imageweight,1,32,NULL);
obj = SelectObject(hdcimage, btBitmap);
BitBlt(hdcimage,0,0,imageweight,imageheight,cSource.hdcimage,0,0,SRCCOPY);
return *this;
}
property <int> SelectFrame
{
Get(int)
{
return intSelectFrame;
},
Set(int selectframe)
{
intSelectFrame=selectframe;
UINT count = 0;
count = img->GetFrameDimensionsCount();
GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
img->GetFrameDimensionsList(pDimensionIDs, count);
img->SelectActiveFrame(&pDimensionIDs[0],intSelectFrame);
graphic=new Graphics(hdcimage);
graphic->Clear(clrBackColor);
graphic->DrawImage(img, 0, 0, img->GetWidth(), img->GetHeight());
free(pDimensionIDs);
}
};
property<int> FramesCount
{
Get(int)
{
return framecount;
}
};
property<string> FileName
{
Get(string)
{
return strfilename;
},
Set(string filename)
{
strfilename=filename;
if(toupper(filename[filename.size()-3])=='C' && toupper(filename[filename.size()-2])=='U' && toupper(filename[filename.size()-1])=='R')
{
//create the transparent icon handle
HCURSOR hicon = (HCURSOR)LoadImage(NULL, filename.c_str(), IMAGE_CURSOR, imageweight, imageheight, LR_LOADFROMFILE|LR_SHARED|LR_DEFAULTSIZE|LR_LOADTRANSPARENT);
ICONINFO ii;
BOOL fResult = GetIconInfo(hicon, &ii);
if (fResult)
{
BITMAP bm;
fResult = GetObject(ii.hbmMask, sizeof(bm), &bm) == sizeof(bm);
if (fResult)
{
imageweight= bm.bmWidth;
imageheight= ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
}
if (ii.hbmMask) DeleteObject(ii.hbmMask);
if (ii.hbmColor) DeleteObject(ii.hbmColor);
}
btBitmap=CreateBitmap(imageweight,imageheight,1,32,NULL);//create the bitmap with icon size
obj = SelectObject(hdcimage, btBitmap);//add the bitmap to memory DC
DrawIconEx(hdcimage,0,0,hicon,imageweight,imageheight,0,0,DI_NORMAL);//draw the icon to DC with right size
//seems the DrawIcon(), always, draw it with 32X32 size
framecount=1;
DestroyCursor(hicon);
}
else
{
Gdiplus::Image img2(towstring(filename).c_str());
btBitmap=CreateBitmap(img2.GetWidth(),img2.GetHeight(),1,32,NULL);
obj = SelectObject(hdcimage, btBitmap);
Gdiplus::Graphics graphics(hdcimage);
graphics.DrawImage(&img2, 0, 0, img2.GetWidth(), img2.GetHeight());
imageweight=img2.GetWidth();
imageheight=img2.GetHeight();
UINT count = 0;
count = img2.GetFrameDimensionsCount();
GUID* pDimensionIDs = (GUID*)malloc(sizeof(GUID)*count);
img2.GetFrameDimensionsList(pDimensionIDs, count);
framecount=img2.GetFrameCount(&pDimensionIDs[0]);
framedelay =img2.GetPropertyItemSize(PropertyTagFrameDelay);
img=new Image(towstring(filename).c_str());
free(pDimensionIDs);
}
}
};
property<Gdiplus::Color> Backcolor
{
Get(Gdiplus::Color)
{
return clrBackColor;
},
Set(Gdiplus::Color bkcolor)
{
clrBackColor = bkcolor;
SetDCBrushColor(hdcimage,clrBackColor.ToCOLORREF());
}
};
void draw(HDC control)
{
//if (clrBackColor.GetValue() == Gdiplus::Color::Transparent)
if (clrBackColor.GetValue()== Gdiplus::Color::Transparent)
{
TransparentBlt(control, 0, 0,width(),height(),hdcimage, 0, 0,width(), height(), GetPixel(hdcimage,width()-1,height()-1));
}
else
{
BitBlt(control,0,0,width(),height(),hdcimage,0,0,SRCCOPY);
}
//InvalidateRect(WindowFromDC(control),NULL,false);
}
operator HBITMAP()
{
return btBitmap;
}
int height()
{
return imageheight;
}
int width()
{
return imageweight;
}
operator HDC()
{
return hdcimage;
}
~image()
{
delete btBitmap;
DeleteObject(obj);
delete img;
Gdiplus::GdiplusShutdown(m_gdiplusToken);
//DeleteObject(btBitmap);//don't show me the image
DeleteDC(hdcimage);
}
};
what anyone can tell me?
-
January 19th, 2015, 09:11 AM
#2
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
Originally Posted by Cambalinho
i'm confused why i get memory leaks, but see the class:
Code:
class image
{
...
property <int> SelectFrame
{
Get(int)
{
return intSelectFrame;
},
Set(int selectframe)
{
...
graphic=new Graphics(hdcimage);
graphic->Clear(clrBackColor);
graphic->DrawImage(img, 0, 0, img->GetWidth(), img->GetHeight());
free(pDimensionIDs);
}
};
~image()
{
delete btBitmap;
DeleteObject(obj);
delete img;
Gdiplus::GdiplusShutdown(m_gdiplusToken);
//DeleteObject(btBitmap);//don't show me the image
DeleteDC(hdcimage);
}
};
what anyone can tell me?
You create graphic with new but never delete it.
You do NOT create btBitmap with new.So why do you delete it?
Victor Nijegorodov
-
January 19th, 2015, 09:18 AM
#3
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
Originally Posted by VictorN
You create graphic with new but never delete it.
You do NOT create btBitmap with new.So why do you delete it?
i understand what you mean, but see the destructor with comments:
Code:
~image()
{
delete btBitmap;//don't give me problems..
delete graphic; //memory leak, when i excute the aplication
DeleteObject(obj);
delete img;
Gdiplus::GdiplusShutdown(m_gdiplusToken);
//DeleteObject(btBitmap);//don't show me the image on menus, when i execute the aplication
DeleteDC(hdcimage);
}
so where is the problem?
-
January 19th, 2015, 09:33 AM
#4
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
Originally Posted by Cambalinho
i understand what you mean, but see the destructor with comments:
Code:
~image()
{
delete btBitmap;//don't give me problems..
delete graphic; //memory leak, when i excute the aplication
DeleteObject(obj);
delete img;
Gdiplus::GdiplusShutdown(m_gdiplusToken);
//DeleteObject(btBitmap);//don't show me the image on menus, when i execute the aplication
DeleteDC(hdcimage);
}
so where is the problem?
1. It doesn't matter whether deleting something that you did not new gives you any problem in this particular code. You must not delete what you did not new delete. Point.
2. If you still get the leaks because of the graphic despite you do
Code:
delete graphic; //memory leak, when i excute the aplication
in the dtor, then you, probably create more than onc of the B]graphic[/B] objects but you delete only one of them.
Set break point on the
Code:
graphic=new Graphics(hdcimage);
line, start debugging and see how many times it will be called for the same .image object.
Victor Nijegorodov
-
January 19th, 2015, 10:00 AM
#5
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
everytime, before i change the btBitmap,after the constructos, i delete the HBITMAP objects:
Code:
//on FileName property
//......
Set(string filename)
{
delete graphic;
delete img;
DeleteObject(btBitmap);
DeleteObject(obj);
//.....................
but on destructor i can't delete the graphic,but i changed it. i don't use the new keyword now. and if i delete the object btBitmap, the image isn't showed.
so the problem isn't the times that i use the new keyword.
Last edited by Cambalinho; January 19th, 2015 at 10:04 AM.
-
January 19th, 2015, 10:06 AM
#6
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
ok... you have right. now i don't need delete the graphic, because i don't use the new keyword. but why i can't delete the objetc btBitmap?(i lose the image)
-
January 19th, 2015, 10:13 AM
#7
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
Originally Posted by Cambalinho
everytime, before i change the btBitmap,after the constructos, i delete the HBITMAP objects:
Code:
//on FileName property
//......
Set(string filename)
{
delete graphic;
delete img;
DeleteObject(btBitmap);
DeleteObject(obj);
//.....................
but on destructor i can't delete the graphic,but i changed it. i don't use the new keyword now.
... and there is no more memory leaks?
Originally Posted by Cambalinho
if i delete the object btBitmap, the image isn't showed.
so the problem isn't the times that i use the new keyword.
Sure it won't be shown since you have deleted the bitmap to be shown!
PS. Do you also have the resource leaks?
Victor Nijegorodov
-
January 19th, 2015, 10:20 AM
#8
Re: [win32 and GUID/GUID+] - how avoid memory leaks?
Originally Posted by VictorN
... and there is no more memory leaks?
Sure it won't be shown since you have deleted the bitmap to be shown!
PS. Do you also have the resource leaks?
i did more tests, with diferent images, and no more more leaks.
thanks for all
Last edited by Cambalinho; January 19th, 2015 at 10:37 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|