Sign in to follow this  
KiLLeR13iii

MFC App becomes corrupt after 10-20 minutes

Recommended Posts

Hello, Here it goes. I have a MFC dialog app that checks portions of screen for specific colors. In the MFC dialog i use a timer and call a function AnalizeArea a lot of times (aprox 3 times a second,if not even more=the timer is set to 100ms, but because i use Sleep in some functions the time varies). After about 15-20 minutes of usage the app becomes corrupt(does not crash, but looses it`s XP looks and the AnalizeArea function returns garbage). I come to identify it`s this function as the program runs 2 hours without being corrupt commenting the instructions inside the function and returning one result. Here it`s the function:
int MainDlg::AnalizeArea(HBITMAP hBmp,RECT area)
{
//	HBITMAP RetBmp=NULL;
	int result =-1;
//	COLORREF Color=0x00rrggbb;
//      COLORREF Color=0x00000000;
	COLORREF Color1=0x00fffbff; //White
	COLORREF Color2=0x00008eff;//Blue
	COLORREF Color3=0x00ce0021;//Red
	if (hBmp)
	{	
		HDC BufferDC=CreateCompatibleDC(NULL);	// DC for Source Bitmap
		if (BufferDC)
		{
			BITMAP bm;
			GetObject(hBmp, sizeof(bm), &bm);

//			SelectObject(BufferDC,hBmp);
			int datasize = bm.bmWidth*bm.bmHeight*bm.bmPlanes;
			COLORREF* ptPixels = (COLORREF*)LocalAlloc(LPTR, datasize * sizeof(COLORREF));
			DWORD ds = GetBitmapBits(hBmp, datasize * sizeof(COLORREF), ptPixels);
			// here BufferDC contains the bitmap
			for (int i=((bm.bmWidth*bm.bmHeight)-1);i>=0;i--)
		    {
			//for (int j=0;j<area.right-area.left;j++)
			//	for (int i=0;i<area.bottom-area.top;i++)
			//	{
			//		Color=GetPixel(BufferDC,j,i);     TOO SLOW
					if (ptPixels[i]==Color1) result=15;
						else
						if (ptPixels[i]==Color2) result=25;
						else
						if (result==-1)
							if (ptPixels[i]==Color3) result=10;
				}
			
		}
		// BufferDC is now useless
		DeleteDC(BufferDC);
	}
	return result;
}





I don`t know why else the application corrupts itself. So if you spot any mistake or memory issue i should be aware of please let me know. Thank you for your time. [Edited by - ApochPiQ on July 22, 2009 11:13:26 AM]

Share this post


Link to post
Share on other sites
1)
Only call DeleteDC with a valid HDC (you call it with NULL as well)

2)
The error you have sounds like a resource leak. You however don't seem to create anything.
You even commented the SelectObject (why?)

If you call SelectObject, always store the old object (the return value) and select that back in once you're done with the HDC

Share this post


Link to post
Share on other sites
Thnx for the quick replay

SelectObject(BufferDC,hBmp); was used for the GetPixel method which is so DAMN SLOW :((.

I use DWORD ds = GetBitmapBits(hBmp, datasize * sizeof(COLORREF), ptPixels);
to get the adress to the first pixel data in hBmp.
Then i just compare ptPixels[i] with the value i search for.

Think i spotted the problem.
I use LocalAlloc but never free that memory.(never knew that i have to free the memory for LocalAlloc too :| )
I`ll use LocalFree to free that memory.
I`ll try to see what happens.
Posting on the forum always opens my eyes. I would have never seen that looking at the VS2005 window :))

Share this post


Link to post
Share on other sites
Quote:

You can also turn on some extra columns in task manager, which will let you see if you have a handle leak (E.g. your GDI Objects might steadily increase).

Hey this really helped.
From what i see now the GDI Object number increases when actually getting the area of the screen to be analyzed. So i guess i was wrong that the AnalizeArea(I will rename this AnalyzeArea :P) is the problem.
The GDI Object counter increases by 1 when calling this:


HBITMAP MainDlg::CaptureArea(RECT area)
{
HDC hScrDC, hMemDC; // screen DC and memory DC

int nX, nY, nX2, nY2; // coordinates of rectangle to grab
int nWidth, nHeight; // DIB width and height
int xScrn, yScrn; // screen resolution

HGDIOBJ hOldBitmap , hBitmap;

hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
hMemDC = CreateCompatibleDC(hScrDC); // get points of rectangle to grab

nX = area.left;
nY = area.top;
nX2 = area.right;
nY2 = area.bottom; // get screen resolution

xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);

//make sure bitmap rectangle is visible

if (nX < 0)
nX = 0;

if (nY < 0)
nY = 0;

if (nX2 > xScrn)
nX2 = xScrn;

if (nY2 > yScrn)
nY2 = yScrn;

nWidth = nX2 - nX;
nHeight = nY2 - nY;

// create a bitmap compatible with the screen DC

hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);

// select new bitmap into memory DC

hOldBitmap = SelectObject (hMemDC, hBitmap);

// bitblt screen DC to memory DC

BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);

// select old bitmap back into memory DC and get handle to
// bitmap of the screen

hBitmap = SelectObject(hMemDC, hOldBitmap);

// clean up

DeleteObject(hOldBitmap);
DeleteDC(hScrDC);
DeleteDC(hMemDC);

// return handle to the bitmap

return (HBITMAP)hBitmap;

}




I cannot delete hBitmap as i have to return that value. What am I missing here?

LE: It is clear. After running the application for just 1 minute the GDI Object counter reached 1000 GDI Objects. This is the cause of the corruption. But what is wrong with that function? :(

Share this post


Link to post
Share on other sites
I got to the bottom of this:

I create hBitmap objects in the CaptureArea function

hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);

and need them in the AnalyzeArea function.
So after use them in the AnalyzeArea function i thought why not delete them here?

So at the end of AnalizeArea(HBITMAP hBmp,RECT area) i inserted a DeleteObject(hBmp) and guess what .. no more leaks.

Ty for the help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this