In the following code I do the following:
- I create a new template wxCommandEvent class that holds some payload specified by the template.
- I then subclass a wxStringPayloadEvent class.
- Finally I create an example app that simply issues a wxStringPayloadEvent and then the event handler gets triggered and displays the payload in a message box on the screen.
If I use the slightly old-fashioned wxEvtHandler::Connect method, (as I've commented out below), then everything works. But if I use the wxEvtHandler::Bind method I get a series of very cryptic error messages (posted after the code).
Since Bind allows more freedom and is easier to use (it doesn't require creating awkward macros), then I would like to use it instead of Connect ... any ideas?
Here's the code:
#include <wx/wx.h>
//Creating my own custom event which will hold a payload of some templated type
template <class Payload_type>
class TemplatedPayloadEvent : public wxCommandEvent
{
public:
TemplatedPayloadEvent(){}
TemplatedPayloadEvent(wxEventType eventType) : wxCommandEvent(eventType){}
TemplatedPayloadEvent(const TemplatedPayloadEvent& event)
: wxCommandEvent(event)
{
this->mPayload = event.mPayload;
}
virtual TemplatedPayloadEvent* Clone() const {return new TemplatedPayloadEvent(*this);}
void setPayload(Payload_type payload) {mPayload = payload;}
Payload_type getPayload() {return mPayload;}
private:
Payload_type mPayload;
};
//instantiating new event along with associated elements
class wxStringPayloadEvent : public TemplatedPayloadEvent<wxString>
{
public:
wxStringPayloadEvent() : TemplatedPayloadEvent<wxString>(wxEVT_STRING_PAYLOAD){};
};
typedef void (wxEvtHandler::*wxStringPayloadEventFunction)(wxStringPayloadEvent&);
#define wxStringPayloadEventHandler(func) \
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)\
wxStaticCastEvent(wxStringPayloadEventFunction, &func)
const wxEventType wxEVT_STRING_PAYLOAD = wxNewEventType();
//implementing test application
class MyApp : public wxApp
{
public:
virtual bool OnInit();
void OnProcessCustom(wxStringPayloadEvent& event);
};
bool
MyApp::OnInit()
{
//Connect event
//Connect(wxEVT_STRING_PAYLOAD, wxStringPayloadEventHandler(MyApp::OnProcessCustom));
Bind(wxEVT_STRING_PAYLOAD, &MyApp::OnProcessCustom, this);///< wish I could use this
wxStringPayloadEvent eventCustom;
eventCustom.SetEventObject(this);
eventCustom.setPayload(wxT("Test payload."));
wxPostEvent(this, eventCustom);
return true;
}
void MyApp::OnProcessCustom(wxStringPayloadEvent& event)
{
wxMessageBox(wxT("Event received. Payload = \"") + event.getPayload() + wxT("\""));
}
IMPLEMENT_APP(MyApp);
Here's the error message:
/ThirdParty/Includes/wx/event.h: In constructor 'wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>::wxEventFunctorMethod(void (Class::*)(EventArg&), EventHandler*) [with EventTag = int, Class = MyApp, EventArg = wxStringPayloadEvent, EventHandler = MyApp]':
/ThirdParty/Includes/wx/event.h:587: instantiated from 'wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>* wxNewEventFunctor(const EventTag&, void (Class::*)(EventArg&), EventHandler*) [with EventTag = int, Class = MyApp, EventArg = wxStringPayloadEvent, EventHandler = MyApp]'
/ThirdParty/Includes/wx/event.h:3182: instantiated from 'void wxEvtHandler::Bind(const EventTag&, void (Class::*)(EventArg&), EventHandler*, int, int, wxObject*) [with EventTag = wxEventType, Class = MyApp, EventArg = wxStringPayloadEvent, EventHandler = MyApp]'
../src/program.cpp:29: instantiated from here
/ThirdParty/Includes/wx/event.h:382: error: invalid conversion from 'wxEvent*' to 'wxStringPayloadEvent*'
/ThirdParty/Includes/wx/event.h:382: error: initializing argument 1 of 'static void wxEventFunctorMethod<EventTag, Class, EventArg, EventHandler>::CheckHandlerArgument(EventArg*) [with EventTag = int, Class = MyApp, EventArg = wxStringPayloadEvent, EventHandler = MyApp]'
Update more clues:
- This might be a clue, but my C++ is still not good enough to be sure.
- Looking at event.h:382 I find the following comment:
if you get an error here it means that the signature of the handler you're trying to use is not compatible with (i.e. is not the same as or a base class of) the real event class used for this event type