Jump to content
  • Advertisement
Sign in to follow this  
Sepiantum

Pros/Cons towards providing a giant switch statement for handling Win32 Messages

This topic is 2584 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm simply curious as to if this is the most efficient way of doing it. Inside a window wrapper class, I have these functions:


virtual LRESULT CALLBACK onNull (WPARAM wParam, LPARAM lParam); //Called on WM_NULL
virtual LRESULT CALLBACK onCreate (WPARAM wParam, LPARAM lParam); //Called on WM_CREATE
virtual LRESULT CALLBACK onDestroy (WPARAM wParam, LPARAM lParam); //Called on WM_DESTROY
virtual LRESULT CALLBACK onMove (WPARAM wParam, LPARAM lParam); //Called on WM_MOVE
virtual LRESULT CALLBACK onSize (WPARAM wParam, LPARAM lParam); //Called on WM_SIZE
virtual LRESULT CALLBACK onActivate (WPARAM wParam, LPARAM lParam); //Called on WM_ACTIVATE
virtual LRESULT CALLBACK onSetFocus (WPARAM wParam, LPARAM lParam); //Called on WM_SETFOCUS
virtual LRESULT CALLBACK onKillFocus (WPARAM wParam, LPARAM lParam); //Called on WM_KILLFOCUS
...


And I'm linking to them inside HandleMessage which is called by WndProc:


LRESULT CALLBACK ExtendedWindowsAPI::ExtendedWindows::CWindow::HandleMessage(UINT Msg, WPARAM wParam, LPARAM lParam){
//The switch statement simply delegates the message to be processed
//By one of the many message processors

switch(Msg){
case WM_NULL:
return this->onNull(wParam, lParam);
case WM_CREATE:
return this->onCreate(wParam, lParam);
case WM_DESTROY:
return this->onDestroy(wParam, lParam);
case WM_MOVE:
return this->onMove(wParam, lParam);
case WM_SIZE:
return this->onSize(wParam, lParam);
case WM_ACTIVATE:
return this->onActivate(wParam, lParam);
case WM_SETFOCUS:
return this->onSetFocus(wParam, lParam);
case WM_KILLFOCUS:
return this->onKillFocus(wParam, lParam);
...
}


Should I modify HandleMessage so that it looks up each function via a large function pointer table, or should I just delete everything and leave it for the user to decide how each message should be handled?

Share this post


Link to post
Share on other sites
Advertisement
The switch statement is traditional, since the individual cases can take the WPARAM and LPARAM arguments and convert them to something actually meaningful for each individual function. Ex: WM_SIZE can split the LPARAM into height and width rather than dumping that duty on the handler function.

Share this post


Link to post
Share on other sites
Not as they are. There's no reason to pass any arguments to your onNull() function. For that matter there's not much point to having an onNull() function because the application is supposed to not do anything in response to getting a WM_NULL. Similarly, for WM_CREATE the WPARAM should be ignored and the LPARAM might as well be cast to a CREATESTRUCT pointer.

Share this post


Link to post
Share on other sites
So you're saying that I should rewrite each function to have more useful parameters and cast wParam and lParam into useful objects upon receiving each message?

EDIT: Perhaps I need to be more clear. I'm simply worried that all the cases inside the switch statement will eventually lead to a lot of CPU overhaul. Should I be worried? If yes, then I will place every function inside a function pointer table and call each message handler from there. If no, what would be the best way to do it? A lot of the messages will be forwarded to DefWindowProc because nobody really gives a crap. Should I leave HandleMessage() alone and have the user write his own, or should I create a bunch of onMessage() functions?

Share this post


Link to post
Share on other sites

EDIT: Perhaps I need to be more clear. I'm simply worried that all the cases inside the switch statement will eventually lead to a lot of CPU overhaul.


No, this is a brutal example of premature optimization.

Cross that bridge *if* you ever reach it. If you do have a bottleneck, the switch isn't going to be the cause. If you have a long running transaction that is hanging the message handling, you will deal with it in a different manner.

Don't worry about performance right now and worry instead about readable and maintainable code.

Share this post


Link to post
Share on other sites

So rewrite each handler function to accept smarter parameters or leave everything as is right now?


My immediate suggestion would be to make each OnWhatever take only the information it needs and handle the deciding what gets trimmed within your switch statement. As SiCrane said earlier, no sense passing parameters to say [color="#1C2837"]WM_CREATE that it doesn't need. Instead your OnCreate would have a signature like OnCreate([color="#1C2837"]CREATESTRUCT *) and your switch will handle massaging WPARM and LPARAM into the appropriate values.
[color="#1C2837"]
[color="#1C2837"]
[color="#1C2837"]Operationally, a few casts are nothing, and that processing will only happen if the handler is going to be called anyways, so this is a operationally neutral operation from a performance perspective... not that that aspect matters right now! ;)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!