Do away with WndProc() in the msg loop?

Started by
11 comments, last by Erzengeldeslichtes 17 years, 9 months ago
I might be a little(...) sleep deprived, but I was rethinking my program design in whole, and I was wondering why precisely I need WndProc(). As I see it, the windows message loop is like this:
while(msg.message!=WM_QUIT)  {
	if(PeekMessage(&msg,0,0,0,PM_REMOVE))  {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	Process();//or render or whatever you may want to do
}
So if there's a message, you remove it from windows' internal queue, translate and dispatch it so that windows can call your little personal function. Why not just call PeekMessage() and TranslateMessage() (translate only if you want the character messages), and then instead of dispatching, just process the message within your WinMain() or whatever, and assign 0 to WNDCLASS::lpfnWndProc when calling RegisterClass()? Is it just more standard? Or is there a technical reason that I overlooked? For example-
while(msg.message!=WM_QUIT)  {
	if(PeekMessage(&msg,0,0,0,PM_REMOVE))  {
		switch(msg.message)  {
		}
	}
	Process();//or render or whatever you may want to do
}
Edit - Anyone notice how the time zones etc for posts are different from those of the edits? Something I've seen for a while now, just curious if anyone else has. [Edited by - CrazyCamel on July 21, 2006 4:27:32 AM]
Grab life by the cord.
Advertisement
One reason is that Windows will send you lots more messages than you'll actually process in your switch structure, and Windows will need to know this and do some processing itself. For instance, how is Windows supposed to know when someone pressed the minimize button (or moved your window) if you just throw the message away?

You don't need the message handling code in a switch statement, if that's what's bothering you. You could register a map structure with callback functions for each message you would like to process, thus cutting drastically on internal dependencies.
2 + 2 = 5 for extremely large values of 2
Well for the messages I don't process, I'd call DefWindowProc() like most do in their normal window procedure callback function.

The thing that's "bothering" me isn't the switch statement. I have no problem with c++ syntax =). It just strikes me as a bit odd that everyone is putting their msg loop to a whole other function (ie WndProc), and that function is supported by msdn and is a callback function and everything... I dunno, it just seems silly and overcomplicated.

Edit- Also, after a bit more googling, it strikes me as odd that no one has stopped to ask this before? (as far as I have found yet)
Grab life by the cord.
Interesting concept, this will also mean that wrapping your game window in a class will also be easier, as you do not have WndProc() to deal with.

The thing is will Windows allow a window to be created with WndProc() set to NULL. Never tried it myself.
Try, try and fucking try again.
Windows will send a bunch of messages to your WndProc, that it doesn't hand you through Get/PeekMessage().

Any message sent using SendMessage() (instead of PostMessage()) will be dispatched directly to the WndProc, instead of going through the message pump.
enum Bool { True, False, FileNotFound };
Talib-
Well it should; the only place windows calls your WndProc is when you call Dispatch message. If RegisterClass() or any other function fails because of a NULL function pointer, just give it a pointer to this:
LRESULT CALLBACK WndProc(HWND hwnd,unsigned int msg,WPARAM wParam,LPARAM lParam){return 0;}
*Waves goodbye to WndProc()*

hplus0603-
Is SendMessage() the only thing that has wndproc called directly? If it is, then (depending on specific application) ways could be found to work around that.

Edit - Also, if there happens to be a SendMessage() sent by another program or whatever, you could just return DefWindowProc() from the bogus WndProc function instead of 0, which would handle the basics. Anything other than basics would be specific... and specifics are hard to discuss unless talking about a specific specific... wait a minute... yes, that makes sense.
Grab life by the cord.
Quote:Original post by CrazyCamel
Is SendMessage() the only thing that has windows call wndproc? If it is, then (depending on specific application) ways could be found to work around that.
Windows may well call your wndproc directly for various things (I can't think of any offhand though). And I'm fairly sure components other than your application will call SendMessage(), meaning you'd have to have some sort of code in your WndProc.

Even if it seems to work, the effort of testing it properly (I.e. for every single combination of window message) will outweigh the benifits of not having a seperate function.

Also, your program is far less likely to work on future versions of Windows.
Hm, what if you set WNDCLASS::lpfnWndProc to DefWindowProc? You give all the direct calls of WndProc to default, and you process all the others, right?

What other components would send messages to my application? Does anyone know any of the "various things" windows may call my WndProc for?

Edit - I don't mean to sound rude; I'm really curious as to whether any of this is viable.
Grab life by the cord.
Well, if you are not using any other components IE a DX game, you fairly have major control of what is being sent in your application. Might still be viable.

Not that I am going to rewrite the my current method of wrapping my game window in a class and it's current use of messages (unless there are major speed advantages). It works perfectly as is.
Try, try and fucking try again.
What about messages that require you to return certain values to indicate success or failure and so on? I don't believe the MSG structure contains any capacity for a return value, not is there any way to return values directly without a WndProc as far as I can see.

Plus, as has been said, Microsoft are within their rights to assume that legacy code is using a WndProc and make changes in the future that do depend on it, even if it is not necessary at the moment.

This topic is closed to new replies.

Advertisement