Thread: cards.dll and evil blue screens

  1. #1
    Registered User
    Join Date
    Feb 2002
    Posts
    465

    cards.dll and evil blue screens

    i have this simple card game i always wanted to program, and i finally decided to look for some info on cards.dll ( the cards drawing library microsoft uses in solitaire, free cell, etc ). i understand it (its pretty simple) and i had it working without any problems. now, suddenly i am getting stack corruption around the class that is drawing the cards when i am lucky, and an ugly blue screen when im not.

    i have commented out 90% of my code, and ive narrowed it to the following. its either in the constructor or destructor of my display class.

    here is my constructor :

    Code:
    Display::Display(HWND hW)
    {
    	hCardDLL = LoadLibrary( "cards.dll" );
    
    	hWnd = hW;
    
    	GetClientRect( hWnd, &client );
    
    	// set up the device context
    	hdc = GetDC( hWnd );
    
    	memdc = CreateCompatibleDC( hdc );
    
    	bmp = CreateCompatibleBitmap( hdc, client.right, client.bottom );
    
    	origBmp = (HBITMAP)SelectObject( memdc, bmp );
    
    	// set up the cards.dll function pointers
    	cdInit = (pfInit) GetProcAddress( hCardDLL, "cdtInit" );
    	cdDraw = (pfDraw) GetProcAddress( hCardDLL, "cdtDraw" );
    	cdDrawEx = (pfDrawEx) GetProcAddress( hCardDLL, "cdtDrawEx" );
    	cdAnimate = (pfAnimate) GetProcAddress( hCardDLL, "cdtAnimate" );
    	cdTerm = (pfTerm) GetProcAddress( hCardDLL, "cdtTerm" );
    
    	cdInit( &cardSizeX, &cardSizeY );
    
    }

    and here is my destructor:

    Code:
    Display::~Display(void)
    {
    	cdTerm();
    	FreeLibrary( hCardDLL );
    
    	SelectObject( memdc, origBmp );
    	DeleteObject( bmp );
    
    	if ( ! DeleteDC( memdc ) )
    		MessageBox( NULL, "Could Not Delete Memory Device Context", "Error", MB_OK );
    
    	ReleaseDC( hWnd, hdc );
    }

    the only other code of any significance is my draw function, which i have commented down to the following:

    Code:
    void Display::DrawCards()
    {
    	// paint the background
    	HBRUSH grn = CreateSolidBrush(RGB(0, 255, 0));
    	FillRect( memdc, &client, grn );
    	DeleteObject( grn );
    	
    	BitBlt( hdc, 0, 0, client.right, client.bottom, memdc, 0, 0, SRCCOPY );
    }

    and just for the heck of it, here is my message loop in winmain:

    Code:
    // the display class
    	Display d( hWnd );
    
    	while ( true )
    	{
    		if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
    		{
    			if ( msg.message == WM_QUIT )
    				break;
    
    			TranslateMessage( &msg );
    			DispatchMessage( &msg );
    		}
    
    		d.DrawCards();
    	}


    i cant figure out whats going wrong, and im hoping someone here might be able to pin it down. if you want to help but dont know anything about the cards.dll library, here is some documentation:

    http://www.catch22.org.uk/tuts/cardtut.asp




    using VS.NET and windows XP.
    I came up with a cool phrase to put down here, but i forgot it...

  2. #2
    Registered User
    Join Date
    Feb 2002
    Posts
    329
    Try checking the return values from your functions. You're assuming that Loadlibrary(), etc.. goes well...What if it's not?

  3. #3
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You're using a poor excuse for an OS and you are trying to draw several hundred times a second to the screen with GDI. What do you expect?

    Uh sorry, I thought you were using Win9x. You're getting blue screens in XP?

    Anyway, unless you have good reason maybe you should consider using a GetMessage loop and drawing in WM_PAINT. Otherwise, you at least need some sort of Sleep in the loop.

  4. #4
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    well, first off, i do have error checks on every single function i call in the constructor. i cut them out for the sake of saving space.

    second, i had it working before, and almost without changing anything ( all the things i changed, i changed back ) it stopped working...

    and yes, i am getting blue screens... they arent the same blue screens as 9x, but this is the first time i have ever seen them. figures, the first time XP breaks is my fault...


    [edit]

    i reduced the framerate of my program and that seems to get rid of the ugly blue screens, but im still getting "stack corruption around the variable 'd' " when my destructor gets called.
    Last edited by ...; 10-15-2003 at 08:33 PM.
    I came up with a cool phrase to put down here, but i forgot it...

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    second, i had it working before, and almost without changing anything ( all the things i changed, i changed back ) it stopped working...
    How frustrating is this? If my experience is anything to go on, it will start working in a day or two after you've put in twenty hours trying to figure out the problem. Again, for no apparent reason...

    Just wondering, is this valid when hWnd has been destroyed? Maybe you have to call it before the window is destroyed. It shouldn't cause a crash anyway.
    ReleaseDC( hWnd, hdc );

    Also, you will be calling DrawCards after the WM_DESTROY message. Again, this should not cause a crash but you could try a IsWindow() call at the start.

    Otherwise, use the debugger, or MessageBox calls between each function call to locate the offending line.

  6. #6
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    ive narrowed it down and found out that it is bombing on the ReleaseDC function in my destructor, but i put an error check in my draw function to check for an hdc, and it exists there. i dont use it anywhere else, and so it should still be there by the time it hits my destructor.

    [edit]

    here is the new tail end of my destructor. the first two checks pass, but the last one fails... im dumbfounded

    Code:
    if ( ! hWnd )
    	MessageBox( NULL, "Missing Handle to Window", "Error", MB_OK );
    if ( ! hdc )
    	MessageBox( NULL, "Missing Hardware Device Context", "Error", MB_OK );
    
    
    if ( !ReleaseDC( hWnd, hdc ) )
    	MessageBox( NULL, "Error Releasing Hardware Device Context", "Error", MB_OK );
    Last edited by ...; 10-15-2003 at 09:02 PM.
    I came up with a cool phrase to put down here, but i forgot it...

  7. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Since your class is linked to the lifetime of the window, why don't you create it in WM_CREATE and delete it in WM_DESTROY?

  8. #8
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    huh.. that seems to have worked, but i had to move my constructor and destructor code to seperate functions.

    i had to create a bool and set it to true in my de-initialization function also, because from how i have it set up now, the draw function gets called once after the de-initialization is called.

    thanks for the tips.
    I came up with a cool phrase to put down here, but i forgot it...

  9. #9
    Registered User
    Join Date
    Jan 2002
    Location
    Vancouver
    Posts
    2,212
    Originally posted by ...
    [B]
    and yes, i am getting blue screens... they arent the same blue screens as 9x, but this is the first time i have ever seen them. figures, the first time XP breaks is my fault...

    Blue screens are never your fault. If the computer requires a reboot (this isn't supposed to happen), it's either a microsoft or hardware problem.

  10. #10
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Stack corruptions are hard to pin down as the corruption might not be noticable until later on in the code.

    My first point of concern would be the typedef you are uising for the GetProcAddress. If you stipulate the wrong calling convention then that is a sure way to corrupt your stack. Are you definately using the WINAPI specifier in your typedef?

  11. #11
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    yes, i am.

    i did a lot of research before getting started on this, so i found adequate documentation on how to typedef the function pointers.

    dont worry, though, its all working now.
    I came up with a cool phrase to put down here, but i forgot it...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Anyone a Resident Evil fan?
    By SlyMaelstrom in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 12-02-2005, 08:21 PM
  2. Resident Evil: The Evil Begins-Coder Needed
    By ^Tomala^ in forum Projects and Job Recruitment
    Replies: 8
    Last Post: 01-04-2005, 05:37 PM
  3. The Evil, Evil Game
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 35
    Last Post: 06-01-2004, 11:08 AM
  4. Evil Fish
    By RoD in forum A Brief History of Cprogramming.com
    Replies: 29
    Last Post: 07-10-2003, 10:27 AM
  5. evil evil empirical authority....
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 03-25-2003, 04:33 PM