I’m thinking of creating a Window class library that uses Win32 API and C++ standard libraries
And I’d like to add signal/slot functionality that handles window messages.
using namespace std;
using namespace boost::signals2;
typedef signal<void (Window*, EventArgs*)> WndEvent;
class EventArgs { public: HWND hWnd; WPARAM wParam; LPARAM lParam; };
class Window {
protected: unordered_map<UINT, WndMsg*> msgMap;
public: void addMsgHandler(UINT msg, void (*handler)(Window*, EventArgs*)) {
auto iter=msgMap.find(msg);
if(iter==msgMap.end()) {
WndEvent* newEvent = new WndEvent();
newEvent->connect(handler);
msgMap.insert(make_pair(msg, newEvent));
}
else iter->second->connect(handler);
}
private: LRESULT wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lparam) {
for(auto iter=msgMap.begin(); iter!=msgMap.end(); iter++)
iter->second->();
}
};
In using that library:
class Form : public Window {
void initialize() {// add here pair of 'message' and 'corresponding handler'
addMsgHandler(WM_LBUTTONUP, boost::bind(&Form::onLButtonUp, this, _1, _2));
...
}
void onLButtonUp(Window* sender, EventArgs* e) { // event handler
wchar_t buf[1000];
wsprintf(buf, L"(%d, %d) clicked", GET_X_LPARAM(e->lParam), GET_Y_LPARAM(e->lParam));
MessageBox(0, buf, L"", MB_OK);
}
}
Here the problem is onLButtonUp’s signature doesn’t match since it’s a class member function.
So I tried to use boost::bind and I got compile error like this:
Window::addMsgHandler': cannot convert parameter 2 'boost::_bi::bind_t<R,F,L>' to 'void (__cdecl *)(Window *,EventArgs *)'
which means I have to change (from simple function pointer to boost function object?) the signature of addMsgHandler() but
I cannot determine the data type (with very long template parameters) to be passed.
The compile error message says
R=void,
F=boost::_mfi::mf2<void,Form,Window *,EventArgs *>,1>
L=boost::_bi::list3<boost::_bi::value<Form*>,boost::arg<1>,boost::arg<2>>
Furthermore, since many other classes will be derived from class Window, I cannot know the template type when I define class Window.
Is there a proper way to pass boost.bind object as function parameter?
Define it like this:
Or even like this:
Now, when calling this function,
slotparameter should be a “callable” accepting 2 arguments of typesWindow *andEventArgs *, and you can create such a slot usingmem_fn,boost::bind,std::bind, or just passing an appropriate raw function ptr.