strange bug

Started by
1 comment, last by phresnel 14 years, 10 months ago
hello everyone! I have developed a game in c++ using only win32 API (no dx at all). Game runs fine but after an hour or so, it draws a single frame on desktop that stays there no matter what i do. Game keeps working fine after that and there are no other problems whatsoever, except the fact that strange frame stays on desktop covering icons. This happens mainly when i switch between different windows during the gameplay but also when i run game in full screen mode. The strange thing is that it happens after so much time (an hour) and that game still works fine after that. I have excluded possibilities of memory leaks or wrong window handles. If anyone had this kind of problem or knows what caused it please let me know.
Advertisement
I haven't solved this problem yet. It seems that application somehow, somewhere gets a wrong DC (the screen DC) and starts rendering on top of all other windows. The game window still recieves the input but animation and all graphics are rendered outside window. I cant think of any other thing that could cause this except using wrong DC.
I belive there is no way my code could mess up DCs, but here is some code i use:

// BACKBUFFER CLASS//==================class BackBuffer {private:	HWND mhWnd;                // Window handle	HDC mhDC;                  // DC handle	HBITMAP mhSurface;         // Surface bitmap	HBITMAP mhOldObject;       // Previous bitmap	int mWidth;                // Bitmap width	int mHeight;               // Bitmap height                .....public:	// CONSTRUCTOR	//============	BackBuffer( HWND hWnd, int width, int height ) {		mhWnd = hWnd;		mWidth = width;		mHeight = height;		HDC hWndDC = GetDC( hWnd );		mhDC = CreateCompatibleDC( hWndDC );		mhSurface = CreateCompatibleBitmap( hWndDC, width, height );		ReleaseDC( hWnd, hWndDC );		mhOldObject = (HBITMAP)SelectObject( mhDC, mhSurface );		HBRUSH White = (HBRUSH)GetStockObject( LTGRAY_BRUSH );		HBRUSH OldBrush = (HBRUSH)SelectObject( mhDC, White );		Rectangle( mhDC, 0, 0, mWidth, mHeight );		SelectObject( mhDC, OldBrush );	};	// PRESENT BUFFER	//===============	void Present() {		HDC hWndDC = GetDC( mhWnd );		BitBlt( hWndDC, 0, 0, mWidth, mHeight, mhDC, 0, 0, SRCCOPY );		ReleaseDC( mhWnd, hWndDC );	};        // GET DC FUNCTION        //=============        HDC GetHDC() { return mhDC; };        ......        // SOME OTHER FUNCTIONS        ......};// SPRITE CLASS//=============class Sprite {private:	HINSTANCE mhAppInstance;  // Application handle	HBITMAP mhImage;          // Bitmap image handle	HBITMAP mhMask;           // Bitmap mask handle	BITMAP mImageBM;          // Bitmap image	BITMAP mMaskBM;           // Bitmap mask	RECT mBitmapRect;         // Bitmap rectangle	POINT mCenterPosition;    // Bitmap center	int ImageID;              // Bitmap image IDpublic:	// CONSTRUCTOR	//============	Sprite( HINSTANCE hAppInstance, int imageID, int maskID, POINT pos ) {		mhAppInstance = hAppInstance;		ImageID = imageID;		mCenterPosition.x = pos.x;		mCenterPosition.y = pos.y;		mhImage = LoadBitmap( hAppInstance, MAKEINTRESOURCE(imageID) );		mhMask = LoadBitmap( hAppInstance, MAKEINTRESOURCE(maskID) );		GetObject( mhImage, sizeof(BITMAP), &mImageBM );		GetObject( mhMask, sizeof(BITMAP), &mMaskBM );		assert(mImageBM.bmWidth  == mMaskBM.bmWidth);		assert(mImageBM.bmHeight == mMaskBM.bmHeight);		mBitmapRect.right = mCenterPosition.x + GetWidth()/2;		mBitmapRect.bottom = mCenterPosition.y + GetHeight()/2;		mBitmapRect.left = mCenterPosition.x - GetWidth()/2;		mBitmapRect.top = mCenterPosition.y - GetHeight()/2;	};        // SOME OTHER FUNCTIONS        ......	// DRAW SPRITE FUNCTION	//=====================	virtual void Draw( HDC hBackBufferDC, HDC hSpriteDC ) {		int w = GetWidth();		int h = GetHeight();		int x = mCenterPosition.x - (w/2);		int y = mCenterPosition.y - (h/2);		HGDIOBJ oldObj = SelectObject(hSpriteDC, mhMask);		BitBlt(hBackBufferDC, mBitmapRect.left, mBitmapRect.top,     mBitmapRect.right, 			   mBitmapRect.bottom, hSpriteDC, 0, 0, SRCAND); 		SelectObject(hSpriteDC, mhImage);		BitBlt(hBackBufferDC, mBitmapRect.left, mBitmapRect.top, mBitmapRect.right, 			   mBitmapRect.bottom, hSpriteDC, 0, 0, SRCPAINT);		SelectObject(hSpriteDC, oldObj);	};};// GAME CLASS//===========class Game {private:        HWND hMainWnd;                          // Window handle	BackBuffer* pBackBuffer;                // Pointer to backbuffer	HDC hSpriteDC;                          // Sprite dc        Sprite* Background;                     // example sprite        .....        // DRAW FRAME FUNCTION        //====================        void DrawFrame( double deltaTime ) {		HDC dc = pBackBuffer->GetHDC();                // draw sprites using dc like:                Background->Draw( dc, hSpriteDC );                .....        };public:        .....        // INITIALIZE GAME FUNCTION        //=========================        int GCInitialize( HINSTANCE hInstance ) {                .....                // SOME OTHER STUFF                .....		hSpriteDC = CreateCompatibleDC(0);		pBackBuffer = new BackBuffer( hMainWnd, Width, Height );        };        // GAME (MESSAGE) LOOP        //====================        int GameLoop() {		MSG Message;		ZeroMemory( &Message, sizeof(MSG) );		// CALCULATE TIME PASSED                ......		while( Message.message != WM_QUIT )		{			if( PeekMessage( &Message, 0, 0, 0, PM_REMOVE ) )			{			     TranslateMessage( &Message );			     DispatchMessage( &Message );			}			else			{			     if( timeElapsed >= 0.07 )			     { 				DrawFrame( deltaTime );				pBackBuffer->Present();				timeElapsed = 0.0;			     }			     lastTime = currTime;			}		}                .....         };};


I think there is no way this code could render on desktop but something wrong happens after an hour of play. I forgot to say that after 5 minutes or so, it gets back to normal again (it starts rendering correctly - no more desktop frames).

Here is the screenshot of bug: screenshot

if anyone has any idea what can be wrong, please tell me.
Clicky.

This topic is closed to new replies.

Advertisement