Sign in to follow this  
EGD Eric

I have a message handling problem. (C++, win32)

Recommended Posts

You know, when you've got a WndProc, but its not global? You have to have a msg Router to pass the buck on to your own custom WndProc? Here's an example:
//Application message router.
//This message router just passes the buck over to WndProc.
LRESULT CALLBACK ApplicationGL::msgRouter(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	ApplicationGL *app = 0;
	if(message == WM_NCCREATE)
	{
		// retrieve Window instance from window creation data and associate
		//it with our class
		app = (ApplicationGL *)((LPCREATESTRUCT)lParam)->lpCreateParams;
//		SetWindowLong(hwnd, GWL_USERDATA, reinterpret_cast<long>(app));
		SetWindowLong(hwnd, GWL_USERDATA, (long)(app));
	}
	else
	{
		// retrieve associated Window instance (its possible to have more than one window, even though this app only has one)
		app = reinterpret_cast<ApplicationGL *>(GetWindowLong(hwnd, GWL_USERDATA));
		//app = (ApplicationGL *)(GetWindowLong(hwnd, GWL_USERDATA));

	}
	return app->WndProc(hwnd, message, wParam, lParam); //call default message procedure
}

Without any code changes in this area, the code just stopped working. he "app" variable crashes the program because I'm trying to use a junk or NULL pointer. But... I've used this code a hundreds of times in the past, I don't know what's wrong now. I've noticed through debugging this one and another project where it doesn't crash that the first time msg router is called, the if statement always evaluates to false, and therefore this code is called: app = (ApplicationGL *)(GetWindowLong(hwnd, GWL_USERDATA)); And when looking at app's values (in debug), all of its member values evaluate to: ???, unknown, etc.. But that's the same here, and the same in the earlier project that works. Its like its always been using a junk pointer, but only just realised it now, and decides to crash. Like Wile E. Coyote falling off the cliff. the second time, it evaluates to true, calling this code: app = (ApplicationGL *)((LPCREATESTRUCT)lParam)->lpCreateParams; SetWindowLong(hwnd, GWL_USERDATA, (long)(app)); You're probably wondering: "Why don't you just go back to the previous project that works?" Well, the answer is: The other project is bloated with tons of stuff I don't need. It took me hours to get rid of it all, so that I could have a base to work with. This new, simpler project was working until it inexplicably stopped. By the way, how do I do that "textbox" thing again? so that the code is actually readable? [Edited by - EGD Eric on November 24, 2004 12:57:06 PM]

Share this post


Link to post
Share on other sites

class Window
{
public:
Create()
{
m_hWnd = CreateWindow....... //
SetWindowLong( m_hWnd, GWL_USERDATA, reinterpret_cast<long>(this));
}

static LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
Window* pThis = reinterpret_cast<Window*>(GetWindowLong( hWnd, GWL_USERDATA ));
if( pThis )
{
... // Handle messages here
}
}
private:
HWND m_hWnd;
};



Something like this should work.
Also, I remember seeing a tutorial about this kind of stuff here on gamedev some time ago.

Hope I helped

Share this post


Link to post
Share on other sites
Yeah, that's what my Wrapper class was based on. That same article. I decided to read through it again, and early on I realised one difference between my project now, and the previous "working one". The WndProc is virtual. While re-doing my framework, I was looking at the OpenGL game programming book, thinking of improving it by using inheritance, but then changed my mind, leaving the virtual there. Does anyone have any idea why "virtual" would make it crash?

BTW: Thanks for the FAQ, I was looking for it, but couldn't find the link to it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this