MFC App becomes corrupt after 10-20 minutes

Started by
5 comments, last by ApochPiQ 14 years, 9 months ago
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==Color1) result=15;
						else
						if (ptPixels==Color2) result=25;
						else
						if (result==-1)
							if (ptPixels==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]
Advertisement
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

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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 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 :))
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).
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? :(
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.
Please do not mark threads as "solved" in the General Programming forum.

Thanks! [smile]

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement