Newsgroup: it.comp.programmare.win32
Titolo: Losing DC handle in rendering function?

Hello to all!
I have a problem with compatible DC. 
I use MSVC++(5.0) and mfc4.2, and I need to draw bitmaps over and over in
a specific window, to simulate an animation. I can't use AVIs or any 
similar thing 'cause the animation is being custom created by the user.
I use a compatible DC and the StretchDIBits function, and delete the DC 
just after that.
Problem is, after a certain number of passes, the application crashes.. 
some heavy duty debugging told me that for some reason, after a certain 
amounts of passes, there's no more free HDC handles, so the software (and 
every other application open at that time) 'crashes', or better just 
stops repainting.
I delete the compatible DC via the DeleteDC function, which gives success 
as a result. The handle does not change between creation and deletion and 
even commenting ALL the code between creation and deletion, the problem 
doesn't get fixed.
Anyone can help me out on that? I really have no clue about what's going 
on.Commenting out all the function there save for the CreateCompatibleDC 
and 
DeleteDC calls doesn't solve the problem.
Thank you all...
[The code of the "criminal" function follows]
bool CFontDescriptor::DrawString(HDC hDC, POINT Orig, LPCSTR szStr, BYTE 
bOp)
{
	// Draw string on specified DC
	bool fResult;
	UINT bOpCode[] = { SRCCOPY,NOTSRCCOPY,SRCAND,SRCPAINT,SRCINVERT };
	HBITMAP hOldBmp;
	CBitmap ColorBmp;
	CDC 	 CompDC;
	LPSTR    lpDIBHdr;            // Pointer to BITMAPINFOHEADER
	LPSTR    lpDIBBits;           // Pointer to DIB bits
 
	UINT	 iChar;
	BOOL     bSuccess=FALSE;      // Success/fail flag
	HPALETTE hPal=NULL;           // Our DIB's palette
	HPALETTE hOldPal=NULL;        // Previous palette
 
	// Check for valid DIB handle
	ASSERT(m_hBitmap);
	// Lock down the DIB, and get a pointer to the beginning of the 
	// bit buffer
	lpDIBHdr  = (LPSTR) ::GlobalLock((HGLOBAL) m_hBitmap);
	lpDIBBits = (lpDIBHdr + *(LPDWORD)lpDIBHdr + 
	(((LPBITMAPINFOHEADER)lpDIBHdr)->biClrUsed * sizeof(RGBQUAD)));
	// Make sure to use the stretching mode best for color pictures
	::SetStretchBltMode(hDC, COLORONCOLOR);
	// Create a compatible DC - this is my desperate try, when all 
	// the rest failed I moved it all to MFC, I had direct API calls
	{
		CDC DummyDC;
		DummyDC.Attach(hDC);
		CompDC.CreateCompatibleDC(&DummyDC);
		DummyDC.Detach();
	}
	// The code here has been commented out... another try, it doesn't 
	// help any though :(
/*
	if (CompDC)
	{
		ColorBmp.LoadBitmap(IDB_COLORBITMAP);
		// Begin string drawing here
		iChar = 0;
		while(fResult && szStr[iChar])
		{
			CRect Src,Dst;
 
			// Prepare Destination Rect
			Dst.left   = 0;
			Dst.top    = 0;
			Dst.right  = m_abCharSize[szStr[iChar]];
			Dst.bottom = m_bCharHeight;
			Dst.OffsetRect(Orig.x,Orig.y);
			Scale(Dst);	// Scale just scales the rect 2:1
			Orig.x += m_abCharSize[szStr[iChar]];
			// Prepare Source Rect
			// I fetch bitmap from a proprietary proportional 
			// font I need to place Src rect accordingly
			Src.left  = szStr[iChar]*m_bCharWidth;
			Src.right = Src.left+m_abCharSize[szStr[iChar]];
			Src.top    = 0;
			Src.bottom = m_bCharHeight;
 
			// Draw Character
			bSuccess = ::StretchDIBits(hDC,	// hDC
			Dst.left,Dst.top,	// Destination Rect Origin
			Dst.Width(),Dst.Height(),	// Extent
			Src.left,Src.top,		// Source Rect Orgin
			Src.Width(),Src.Height(),	// Source Rect Extent
			lpDIBBits,			// Bits 
	   		(LPBITMAPINFO)lpDIBHdr,	// Bitmap Header 
			DIB_RGB_COLORS,		// Bitmap Usage
			bOpCode[bOp]);		// Raster Op
	// Select color bitmap (I need the string in a certain color)
	hOldBmp = (HBITMAP)CompDC.SelectObject((HBITMAP)ColorBmp);
	// Bitblt Colorbmp on the source - it's a solid yellow bitmap
	BitBlt(hDC,Dst.left,Dst.top,Dst.Width(),Dst.Height(),(HDC)CompDC,0
		,0,SRCAND);
	// Reselect old object
	CompDC.SelectObject(hOldBmp);
 
	fResult = (bSuccess == m_bCharHeight);
	iChar++;
	}	
 
	ColorBmp.DeleteObject();
*/
	// Another last-hope try: beep if it doesn't get deleted
	if (!CompDC.DeleteDC())
		MessageBeep(MB_OK);
	// It never beeps, but it still fails to open the DC after a 
	// while, and every other application fails too (total screen 
	// corruption)
//	}
	::GlobalUnlock((HGLOBAL) m_hBitmap);
	return (fResult);
}

 lpDIBHdr  = (LPSTR) ::GlobalLock((HGLOBAL) m_hBitmap);
Questa mi sembra una trovata un po' "violenta"... io userei i metodi
tradizionali per estrarre informazioni/dati da un DIB.
--
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/