WndProc in a class not compiling

Started by
8 comments, last by _Sigma 17 years, 5 months ago
Well, after many failed attempts (yet learning a ton!) and finally getting a laptop so I can work at uni, I am attempting to write a game (engine)that doesn't suck. So I am reusing some of my old code, and something that used to work is no longer working for me. So without further ado, here is the code:

class ParvusKernel
{
public:
	LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
	
	bool initialize(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow);
...

private:
...
	//main handle
	HWND main_window_handle;

	//window instance
	HINSTANCE main_instance;

	WNDCLASSEX winclass; // this will hold the class we create
	HWND	   hwnd;	 // generic window handle
	MSG		   msg;		 // generic message

};


bool ParvusKernel::initialize(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
	main_window_handle = NULL;
	main_instance = NULL;

	// first fill in the window class structure
	winclass.cbSize         = sizeof(WNDCLASSEX);
	winclass.style			= CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	winclass.lpfnWndProc	= &ParvusKernel::WindowProc;
	winclass.cbClsExtra		= 0;
	winclass.cbWndExtra		= 0;
	winclass.hInstance		= hinstance;
	winclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	winclass.hCursor		= LoadCursor(NULL, IDC_ARROW);
	winclass.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
	winclass.lpszMenuName	= NULL;
	winclass.lpszClassName	= WINDOW_CLASS_NAME;
	winclass.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);		


	switch(windowType)
	{
	case 0:
		{
			// register the window class
			RegisterClassEx(&winclass);				

			// create the window
			hwnd = CreateWindowEx(NULL, // extended style
				WINDOW_CLASS_NAME,     // class
				"Parvus Alpha 1", // title
				WS_POPUP | WS_VISIBLE,
				0,0,	    // initial x,y
				400,400,  // initial width, height
				NULL,	    // handle to parent 
				NULL,	    // handle to menu
				hinstance,// instance of this application
				NULL);// extra creation params

			//save the handle and instance
			main_window_handle = hwnd;
			main_instance = hinstance;

			break;

		}
	case 1:
		{
			//TODO: Add full screen creation code here.
			break;
		}
	}
}

with winclass.lpfnWndProc = &ParvusKernel::WindowProc; erroring with the error:


1>\parvus_kernel.cpp(18) : error C2440: '=' : cannot convert from 'LRESULT (__stdcall ParvusKernel::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
1>        There is no context in which this conversion is possible

This used to work...any ideas? Visual studio 2005 pro is my IDE.. Cheers
Advertisement
Make WindowProc a static function.
Quote:
This used to work...any ideas? Visual studio 2005 pro is my IDE..

I don't believe you, unless you recently removed a "static" from WindowProc's declaration in ParvusKernel.

A pointer to a function is not the same as a pointer to a member function (remember there is an implicit 'this' parameter that must be handled somehow, and whole host of other interesting tidbits). winclass.lpfnWndProc expects a pointer to a function, but &ParvusKernel::WindowProc is a pointer to a member function. Those two types are not compatible, thus the error.
Hmm.. Fancy that!
Quote:
I don't believe you, unless you recently removed a "static" from WindowProc's declaration in ParvusKernel.

Fair enough. I'll explain. I had a game engine actually working, but there were a few fundamental design flaws with it, so it just became too much to work with. As well, I just didn't have the experience to follow through with the project, so I gave up. I didn't touch the code for hm...I'm thinking about a year or so. When I went to compile it the other day, it wouldn't compile, massive amounts of errors, etc. Very strange says I, as I remeber it compiling. So now, year (or year and a half maybe), 2nd year cmpt sci, so I am going to give it another go, now that I know way more. So, I am reusing a lot of the code, just because I'm a lazy bugger, and don't feel like rewriting some portions of the code. So how it worked previous I have no idea. Must have fiddled, broken the code, gave up, then forgotten. Anyways, works fine (well it compiles, but doesn't do anything :P),

@jpetrie: if you felt like it, I'd love a PM explaing all the other "Tidbits" of things that make that not work! Only if you want tho...

Thanks!
If you are interested in a method you can use to get what you are trying to do to actually work, the mightly Oluseyi has written a very good article on how to use a static MessageRouter to ship messages out to a member function WndProc.

There is some work involved but the end result is roughly what we all wish we could just do the way you have tried.

Borland offer an extension __closure function pointer that can be assigned either free or member functions but these special function pointers need the capacity to also store the object having the method called upon which a normal C/C++ function pointer does not.
Thanks for the link, i'll check it out.

Is there a reason that my way is bad?
Quote:Original post by _Sigma
Is there a reason that my way is bad?


Don't really understand the question. The way you've posted above won't compile, so I'd say that is fairly bad [smile]. Sorry if I misunderstood.

The WndProc pointer in a window class is of type WNDPROC, which is a pointer to a free function. You can't assign a non-static member function to a free function pointer since a non-static member function is a completely different type to a free function, even if the return type and parameter types are identical.
Sorry man. Let me rephrase.

Once I add the static, she compiles. So, you're reply above seemed to imply that doing it this way was broken(after adding the static), thus you posted Oluseyi's code, which I took to mean "You're way is broken, do it this way instead". Thus, my question.
Quote:Original post by _Sigma
Sorry man. Let me rephrase.

Once I add the static, she compiles. So, you're reply above seemed to imply that doing it this way was broken(after adding the static), thus you posted Oluseyi's code, which I took to mean "You're way is broken, do it this way instead". Thus, my question.

No, that's not what he meant. His post says that if you want to be able to route window procedure calls to non-static member functions, which is useful if you plan to have multiple instances of your Window class that are of the same wndclass, then take a look at my article (static message router, which then calls a member function after retrieving the object from the window handle).
ohhh gotcha. Sorry for being silly!

Cheers

This topic is closed to new replies.

Advertisement