   [WIN32] Function Pointers and Best Practices
  I'm wondering if it's an acceptable practice to do the following in your window procedure: instead of a big (ugly) switch statement, maintain a map of UINT message values to function pointers and, for each UINT message, call the function pointer mapped to it.  Are there any glaring disadvantages to this approach?  Thanks.   
  Hey,Great idea - I can't see a whole lot of problems - and most UI frameworks ultimately are doing this under the hood. MFC, for example, catches the messages and routes them through an event map that binds them to virtual and non-virtual functions in a CWnd-derived class. I suspect Winforms does the same.The disadvantages I can see are short:1. switch statements, when used with cases that are sequential, or sequential enough, usually compile down to a jump table so the execution speed will be faster than a map. In the case of windows messages, so much work is done inside the message handler that it usually dwarfs the performance cost of the map lookup. Not a concern.2. Memory footprint will be smaller with switch, but really - by bytes only. Not a concern.3. When you have a map full of functions, instead of a switch statement, your message handling code is decentralised, and can be harder to debug and just get your head around. I would suggest putting all the handlers in a common place so at least you have OnShowWindow( wparam, lparam, etc ) near OnMoveWindow( wParam, lParam, etc). Not really a concern - just organise your code wisely (and you do that anyways, right?)I say GO FOR IT.S.;  I don't think there would be any problem with it. I think Oluseyi did it when he created his window class. Linky. If nothing else his article can give you further ideas.   ;  With using a map of function pointers (unless I'm misunderstanding something), there's one thing you can do that you can't do with a switch: Replace them dynamically. Another simple thing is adding new message handlers (i.e. registerHandler(msg, func) just do funcMap[msg] = func. Or, if you're feeling gutsy, funcMap[msg].push_back(func) with a map of vectors of function pointers, then in the message loop just go through the vector and call each one).   ;  The only disadvantage I can think of (and this is a bit weak) is that I prefer to translate my WPARAM and LPARAM into more meaningful parameters to a handler function, and a simple switch in WndProc is a convenient place to do this. Daft example:void OnMouseDown(HWND Hw,int X,int Y){  // obvious what the parameters are}LRESULT CALLBACK WndProc(HWND Hw,UINT Msg,WPARAM wParam,LPARAM lParam){    switch(Msg)   {   case WM_LBUTTONDOWN: OnMouseDown(Hw,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); return 0;   }    return DefWindowProc(Hw,Msg,wParam,lParam);}Using a function pointer map would require two functions per message to use this approach or require you to translate the parameters inside the actual handler function, which I find less clear.I'm sure there are clever ways to work round this though.   ;Quote:Original post by AardvajkThe only disadvantage I can think of (and this is a bit weak) is that I prefer to translate my WPARAM and LPARAM into more meaningful parameters to a handler function, and a simple switch in WndProc is a convenient place to do this. Daft example:void OnMouseDown(HWND Hw,int X,int Y){  // obvious what the parameters are}LRESULT CALLBACK WndProc(HWND Hw,UINT Msg,WPARAM wParam,LPARAM lParam){    switch(Msg)   {   case WM_LBUTTONDOWN: OnMouseDown(Hw,GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); return 0;   }    return DefWindowProc(Hw,Msg,wParam,lParam);}Using a function pointer map would require two functions per message to use this approach or require you to translate the parameters inside the actual handler function, which I find less clear.I'm sure there are clever ways to work round this though.It's a good point - I'm sure you could use some kind of boost::bind or other templatized translation methods whereby you don't bind just a function pointer, but a functor object that marshals the wparam and lparams to useful types before invoking the function pointer. Exercise for the reader, perhaps?   ;Quote:Original post by SphetIt's a good point - I'm sure you could use some kind of boost::bind or other templatized translation methods whereby you don't bind just a function pointer, but a functor object that marshals the wparam and lparams to useful types before invoking the function pointer. Exercise for the reader, perhaps?True. As I say, I'm sure there are ways of doing it (sounds like you've hit upon it with functors actually).However, I can honestly say that as long as I only ever translate params and call a handler function, I have never found that a switch statement in WndProc has made a project hard to manage.IIRC, what Oluseyi did in the article quoted above was encode a pointer to a window object into the user data of the actual kernel window instance then use a map of member function callbacks to call a method of an instance of a C++ Window class in response to a message - a valid and well-engineered approach to encapsulating multiple windows.In the case discussed in this thread, using a message map just to avoid a single line in a switch statement seems like over-engineering to me, but it is all subjective I guess.   ;Quote:Original post by AardvajkIn the case discussed in this thread, using a message map just to avoid a single line in a switch statement seems like over-engineering to me, but it is all subjective I guess.I agree with you here - and I see this a lot - where over-engineering is used to solve the 'this sure is a lot of typing' complaint. Ultimately, while a fun exercise (i caught myself typing up a sample instead of doing work), sometimes you type far more in the engineering example then in just typing out the case statements.Using the user ptr is a great idea. Assuming you have an BaseWindow class, you can store a pointer to the BaseWindow inside the userdata using SetWindowLong(), I believe. WinProc's WM_MOUSE_MOVE would get the userdata pointer out, cast it to BaseWindow and call pBaseWindow->OnMouseMove( wParam, lParam ). It would be cleaner to have BaseWindow have a public static member HandleMessage(), that would then call OnMouseMove - this way you can declare OnMouseMove protected instead.S.   ;  Its not only perfectly valid, but common. In my own system, the WndProc is encapsulated in a class of its own, with a separate Window Class -- Oluseyi's system combines the WndProc and Windowing functionality in one class. I haven't yet found a strong argument for one approach over the other. My approach separates responsibilities more cleanly, IMHO, but Oluseyi's approach resembles how Windows operates more literally -- then again, IMO, the Windows' message passing system is inside out, particularly for gaming, where you want messages for the application (or, rather, the application must usually make non-windowing updates based on messages) rather than the window itself.To put it briefly, in Windows (and which Oluseyi's system models) every window has a WndProc. The difference, in my system, is that the application owns the WndProc (and also owns a window, which it is associated with); while this sounds like a subtle difference, its actually very deep -- in my system, the window never has to know anything about the application, and never references it -- a window is simply a window. If the window class owns the WndProc, then I don't see any way to get around the fact that the Window class must know something about the application (class) in order to pass information (such as input commands) to it so that it can respond. Oluseyi's article doesn't address how messages get from the window to the application, but in my system, the WndProc instance takes a template parameter that allows it to know the type of the class which owns the WndProc (typically the "application") which must satisfy a small interface, and I haven't found any shortcomings with my approach despite its differences from the Windows' worldview.   ;Quote:Original post by RavyneTo put it briefly, in Windows (and which Oluseyi's system models) every window has a WndProc. The difference, in my system, is that the application owns the WndProc.As I understand it, the approach in Oluseyi's article has just one WndProc for all instances of Window - it is a static method within the class namespace but is not owned by any particular window.It just translates a windows message with an associated HWND into a class-method call on the correct instance of a Window class. These calls can of course be virtual to allow a derived MineSweeperWindow or WordProcessorWindow to respond to messages in their own way without them being "aware" of this underlying system.To be more precise, in Windows every class of window should have a WndProc. Having a single application-wide WndProc for all classes of window would, in my view, lead to complexity.The approach in the article would extend easily to allow for different derived children of Window to plug in different WndProcs if the interfaces for these classes were different (i.e. they needed to process different messages). This would be preferrable to having one Window interface that forwarded all possible messages to all window classes in many ways.   