template fn replacements for msg macros
I've been toying with template functions as a first step/ exploration/attempt to devise a c++ replacement for message macros from mainly windowsx.h. I've read some stuff on line - comparisons of different templatised techniques, functors etc and am using Stroustrup's C++ and Josuttis for reference.
In general: I have a base wnd class (C++) from which is derived various windows and controls, the hierarchy is something like BaseWnd::Wnd::MainWnd where MainWnd is a 'container' or frame for just about everything else. Currently I use a static wndproc which forwards messages to a virtual class wndproc which is overridden in descendant classes as required. I use msg macros in these virtual wndprocs as follows, eg:
Code:
LRESULT CALLBACK MainWnd::MsgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
HANDLE_MSG(hwnd,WM_ERASEBKGND,OnEraseBkGrd);
}
}
where the HANDLE_MSG macro expands into the case statement and the call to the OnEraseBkGrd handler for WM_ERASEBKGND as defined in windowsx.h. I have included one msg only for simplicity.
This is the template fn to 'replace' it:
Code:
template <class T,class W>
inline OnEraseHandler(T *ObjPtr,BOOL (W::*FnPtr)(HWND,HDC),HWND hwnd,WPARAM wParam,LPARAM lParam)
{
(ObjPtr->*FnPtr)(hwnd,reinterpret_cast<HDC>(wParam));
}
and the virtual wndproc becomes:
Code:
LRESULT CALLBACK MainWnd::MsgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (uMsg)
{
case WM_ERASEBKGND:
return OnEraseHandler(this,&MainWnd::OnEraseBkGrd,hwnd,wParam,lParam);
}
}
Which works ok but is ugly.
The problem: I want the template to function like the macro (I wouldn't mind if the syntax was equally simple too!) in that I can call any handler within the class hierarchy from it, eg:
Code:
HANDLE_MSG(hwnd,WM_ERASEBKGND,Wnd::OnEraseBkGrd);
will call the required fn; if I try the same thing with the template fn ie:
Code:
return OnEraseHandler(this,&Wnd::OnEraseBkGrd,hwnd,wParam,lParam);
It fails (presumably because it's using this to determine the object. This fails too:
Code:
return OnEraseHandler<Wnd,Wnd>(this,&Wnd::OnEraseBkGrd,hwnd,wParam,lParam);
When I speak of failure what I mean is that the handler called is always the one currently in scope ie MainWnd::OnEraseBkGrd.
So, if anyone has been there and done that could you please give me some hint as to how I might coerce the template to call any handler in the class hierarchy I might explicitly choose or perhaps an explanation of why it's not possible to do so. Note that the handler functions (C++), in this case OnEraseBkgrd, are virtual.
Thanks in advance for your time and consideration.
edit: typos, formatting