Jump to content

  • Log In with Google      Sign In   
  • Create Account

Muhammad Haggag

Member Since 22 Sep 2000
Offline Last Active Oct 02 2013 06:02 AM

Posts I've Made

In Topic: Can I break a Visual C++ program when a certain address of memory is written?

05 December 2011 - 05:57 PM

Solved it!!!!
It was bloody SVN shell extension.
Still one question remains: if the SVN shell extension I installed corrupts memory, how come it does not crash Windows Explorer itself?

You're probably running into a corner case in the extension where it's not expecting to be invoked as part of the open file dialog. The dialog runs as part of your process, and so your process crashes.

In Topic: Debugger visualizers for time classes (autoexp.dat)

16 August 2010 - 07:33 PM

Can you post your attempts? Which version of Visual Studio are you using?

In Topic: CreateWindowW strips caption to single character!!

16 August 2010 - 07:30 PM

The last time I ran into this, I was calling DefWindowProcA instead of DefWindowProcW.

In Topic: weird win32 GDI bug

01 July 2010 - 02:23 PM

The problem manifests because of the MoveBall call:
pe = gpBall->MoveBall(*gpPlayerOne, *gpPlayerTwo);

You're dereferencing pointers. That'd have been fine if MoveBall took Player references (Player&), but it doesn't:
PlayerEnum Ball::MoveBall(Player argP1, Player argP2)

What happens is:
1. The MoveBall call copy-constructs two copies of players one and two. That'd have been fine if you'd implemented proper copy construction and assignment on the Player class, but you didn't, so the compiler-generated ones were used.
2. The compiler-generated copy constructor does a shallow copy of the instances (i.e. copies all members), so argP1 and argP2 both end up with handles to the player bitmaps (mhbmpPaddle).
3. At the end of MoveBall, both argP1 and argP2 are destroyed, and your destructor releases mhbmpPaddle, leaving gpPlayerOne and gpPlayerTwo with invalid mhbmpPaddle handles.
4. You SelectObject() with an invalid handle, which fails. You try to draw the paddles, but you're drawing with whatever object was selected before your drawing.

There are several good things to learn from this:
1. If your class manages resources (i.e. releases them in the destructor), either write a proper copy constructor and assignment operator, or suppress the compiler from generating them. You can do this by declaring them private:
Player(const Player&);
Player& operator=(const Player&);

2. Avoid jumping to early conclusions while debugging. The problem has nothing to do with height at all. The first thing I did when debugging was to paint the paddles blue, with thin yellow and red stripes at the top and bottom. They still showed up as white, which confirmed that the bitmaps aren't being painted at all when the bug manifests, which pointed to either corruption of the bitmaps or their handles (since they were drawn fine at startup).

3. Always check for return values. If you were checking the return values of SelectObject(), you'd notice that it returns NULL for players right after you unpause the game. After suspecting the bitmaps, I replaced all calls to SelectObject() with a CheckedSelectObject() that breaks in the debugger if SelectObject() fails:
inline HGDIOBJ CheckedSelectObject(HDC dc, HGDIOBJ obj)
HGDIOBJ result = SelectObject(dc, obj);
if (!result || result == HGDI_ERROR)
OutputDebugString("SelectObject failed");

return result;

Once I related the bug to unpausing the game, I quickly isolated the MoveBall call as culprit.

4. Don't pass objects by value. By default, pass them as const references. You avoid painful bugs like this, as well as object slicing bugs (which are equally hairy to locate).

In Topic: Brunhilda and the Dark Crystal - Open Beta

13 May 2010 - 12:04 PM

That looks beautiful. I'll give it a try when I get home. Consider posting it to the Image of the Day gallery.