Difference between revisions of "Custom Events"

From WxWiki
Jump to navigation Jump to search
m (DavidGH moved page Custom Events in wx2.9 to Custom Events in wx3.0 without leaving a redirect: Updated 2.9. to 3.0)
m (Text replacement - "<source>" to "<syntaxhighlight lang="cpp">")
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
==ToDo when wx3 is released==
 
*Change around the page-names so that Custom_Events becomes this page, and the original is renamed to Custom_Events_in_wx2.x (or similar)
 
*When docs.wxwidgets.org/stable/ becomes 3.0, check that the wxref-type urls link correctly; they don't atm.
 
 
 
==Introduction==
 
==Introduction==
Starting with wx2.9, there have been enough changes to how custom events are created (different macros) and used (<wxref class="wxEvtHandler" method="Bind"></wxref>) that a separate page will be useful. You can find the page for older wx versions [[Custom_Events|here]].
+
Starting with wx3.0, there have been enough changes to how custom events are created (different macros) and used ([https://docs.wxwidgets.org/stable/classwx_evt_handler.html#a0f30c8fa5583b4a5f661897d63de3b62 wxEvtHandler::Bind]) that a separate page will be useful. You can find the page for older wx versions [[Custom Events in wx2.8 and earlier|here]].
  
 
==Things you should understand before you start==
 
==Things you should understand before you start==
Line 11: Line 7:
 
These two completely different things often get confused.
 
These two completely different things often get confused.
  
An event is an object of class <wxref class="wxEvent"></wxref>, or more usually of one of its derivatives e.g. <wxref class="wxCommandEvent"></wxref>. A wxEventType is just a typedef for int. However the (understandable) tendency to use names like MyFooCommandEvent for wxEventTypes can cause considerable confusion.
+
An event is an object of class wxEvent, or more usually of one of its derivatives e.g. wxCommandEvent. A wxEventType is just a typedef for int. However the (understandable) tendency to use names like MyFooCommandEvent for wxEventTypes can cause considerable confusion.
  
 
===Event Macros===
 
===Event Macros===
Line 18: Line 14:
 
The old macros for this were:
 
The old macros for this were:
 
'''DECLARE_EVENT_TYPE(MY_NEW_TYPE, wxID_ANY)''' and '''DEFINE_EVENT_TYPE(MY_NEW_TYPE)'''
 
'''DECLARE_EVENT_TYPE(MY_NEW_TYPE, wxID_ANY)''' and '''DEFINE_EVENT_TYPE(MY_NEW_TYPE)'''
though it was almost as easy to use non-macro code. SInce wx2.9 events are type-safe and the new macros take this into account; so code that doesn't have to be backwards-compatible should use:
+
though it was almost as easy to use non-macro code. SInce wx3.0 events are type-safe and the new macros take this into account; so code that doesn't have to be backwards-compatible should use:
 
'''wxDECLARE_EVENT(MY_NEW_TYPE, wxCommandEvent);''' and '''wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent);'''
 
'''wxDECLARE_EVENT(MY_NEW_TYPE, wxCommandEvent);''' and '''wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent);'''
 
(Note the semicolons.) You now have to specify the event class that will use the new wxEventType; it will often be wxCommandEvent.  
 
(Note the semicolons.) You now have to specify the event class that will use the new wxEventType; it will often be wxCommandEvent.  
  
 
===Dynamic or Static event binding===
 
===Dynamic or Static event binding===
wx code has traditionally tended to use static event tables to connect events to handlers. However it has long been possible to [http://wxwidgets.blogspot.com/2007/01/in-praise-of-connect.html do this dynamically], and since wx2.9 this has become easier and much safer with the addition of <wxref class="wxEvtHandler" method="Bind"></wxref>. Custom events can use either method.
+
wx code has traditionally tended to use static event tables to connect events to handlers. However it has long been possible to [http://wxwidgets.blogspot.com/2007/01/in-praise-of-connect.html do this dynamically], and since wx3.0 this has become easier and much safer with the addition of [https://docs.wxwidgets.org/stable/classwx_evt_handler.html#a0f30c8fa5583b4a5f661897d63de3b62 wxEvtHandler::Bind]. Custom events can use either method.
  
It is strongly suggested that you no longer use  <wxref class="wxEvtHandler" method="Connect"></wxref> (except when backward-compatibility with wx2.8 is essential) as it is so easy to get it wrong; and getting it wrong either fails silently or causes runtime crashes.
+
It is strongly suggested that you no longer use  wxEvtHandler::Connect (except when backward-compatibility with wx2.8 is essential) as it is so easy to get it wrong; and getting it wrong either fails silently or causes runtime crashes.
  
 
===Dispatching your custom event===
 
===Dispatching your custom event===
 
Once you've created an event instance using your custom class or wxEventType, you need to send or post it to its destination. You can do this using the same methods as in wx2.8: sending (synchronously) with  
 
Once you've created an event instance using your custom class or wxEventType, you need to send or post it to its destination. You can do this using the same methods as in wx2.8: sending (synchronously) with  
<wxref class="wxEvtHandler" method="ProcessEvent"></wxref> or posting (asynchronously) with <wxref class="wxEvtHandler" method="AddPendingEvent"></wxref> or the convenience function wxPostEvent. However since wx2.9 there is also the asynchronous (and more thread-safe) <wxref class="wxEvtHandler" method="QueueEvent"></wxref> and its convenience function wxQueueEvent.
+
wxEvtHandler::ProcessEvent or posting (asynchronously) with wxEvtHandler::AddPendingEvent or the convenience function wxPostEvent. However since wx3.0 there is also the asynchronous (and more thread-safe) wxEvtHandler::QueueEvent and its convenience function wxQueueEvent.
  
 
===What sort of custom event do I need?===
 
===What sort of custom event do I need?===
 
The term 'custom event' can be used to mean either creating your own subclass of wxEvent or wxCommandEvent, or just defining a new wxEventType to use with the standard event classes. Which of these you do depends on how much, and what type of, data you want to send in your event.
 
The term 'custom event' can be used to mean either creating your own subclass of wxEvent or wxCommandEvent, or just defining a new wxEventType to use with the standard event classes. Which of these you do depends on how much, and what type of, data you want to send in your event.
  
Most of the time you won't need a subclassed wxEvent, just a standard event with a new wxEventType to 'label' it. Even a plain <wxref class="wxEvent"></wxref> can transport useful data in its id and eventType fields. A <wxref class="wxCommandEvent"></wxref> additionally has fields for another int, a long int and a wxString. It can also take a void* in its clientData field. All these should be more than adequate in most situations, so needing to create your own custom class is rare. However if you do need to transport lots of data or have other special needs, subclassing is available and gives you the flexibility to do whatever is required.
+
Most of the time you won't need a subclassed wxEvent, just a standard event with a new wxEventType to 'label' it. Even a plain wxEvent can transport useful data in its id and eventType fields. A wxCommandEvent additionally has fields for another int, a long int and a wxString. It can also take a void* in its clientData field. All these should be more than adequate in most situations, so needing to create your own custom class is rare. However if you do need to transport lots of data or have other special needs, subclassing is available and gives you the flexibility to do whatever is required.
  
 
==Creating and using a new wxEventType==
 
==Creating and using a new wxEventType==
Line 42: Line 38:
  
 
In a suitable cpp file add the line:
 
In a suitable cpp file add the line:
<source>
+
<syntaxhighlight lang="cpp">
 
wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent);
 
wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent);
</source>
+
</syntaxhighlight>
 
It doesn't have to be a wxCommandEvent, but that's the usual choice.
 
It doesn't have to be a wxCommandEvent, but that's the usual choice.
  
 
===Posting:===
 
===Posting:===
 
You can use the new wxEventType either with or without giving the event a specific id.
 
You can use the new wxEventType either with or without giving the event a specific id.
<source>
+
<syntaxhighlight lang="cpp">
 
wxCommandEvent event(MY_NEW_TYPE); // No specific id
 
wxCommandEvent event(MY_NEW_TYPE); // No specific id
  
Line 58: Line 54:
 
wxPostEvent(this, event); // to ourselves
 
wxPostEvent(this, event); // to ourselves
 
wxPostEvent(pBar, event); // or to a different instance or class
 
wxPostEvent(pBar, event); // or to a different instance or class
</source>
+
</syntaxhighlight>
  
 
If you need to send more specific information to the destination, add an id. This can easily be done using an enum.
 
If you need to send more specific information to the destination, add an id. This can easily be done using an enum.
<source>
+
<syntaxhighlight lang="cpp">
 
// The values don't matter, as they're only used with this wxEventType
 
// The values don't matter, as they're only used with this wxEventType
 
enum { foo_one = 1, foo_two, foo_three };
 
enum { foo_one = 1, foo_two, foo_three };
Line 74: Line 70:
 
// You can send the same event elsewhere as it's cloned in wxPostEvent
 
// You can send the same event elsewhere as it's cloned in wxPostEvent
 
wxPostEvent(pBar, event_b);
 
wxPostEvent(pBar, event_b);
</source>
+
</syntaxhighlight>
  
 
===Catching:===
 
===Catching:===
  
You can catch the posted event either with an event table or with <wxref class="wxEvtHandler" method="Bind"></wxref>.
+
You can catch the posted event either with an event table or with wxEvtHandler::Bind.
If you didn't specify the id (though this would work even if you did) the event table would be:  
+
If you didn't specify the id (though this would work even if you did) the event table would be:
<source>
+
 
 +
<syntaxhighlight lang="cpp">
 
wxBEGIN_EVENT_TABLE(MyFoo, wxFoo))
 
wxBEGIN_EVENT_TABLE(MyFoo, wxFoo))
 
   EVT_COMMAND(wxID_ANY, MY_NEW_TYPE, MyFoo::OnMyEvent)
 
   EVT_COMMAND(wxID_ANY, MY_NEW_TYPE, MyFoo::OnMyEvent)
 
   ...
 
   ...
 
wxEND_EVENT_TABLE()
 
wxEND_EVENT_TABLE()
</source>
+
</syntaxhighlight>
  
 
The specific-id version would be:
 
The specific-id version would be:
<source>
+
<syntaxhighlight lang="cpp">
 
wxBEGIN_EVENT_TABLE(MyFoo, wxFoo)
 
wxBEGIN_EVENT_TABLE(MyFoo, wxFoo)
 
   EVT_COMMAND(foo_one, MY_NEW_TYPE, MyFoo::OnMyFirstEvent)
 
   EVT_COMMAND(foo_one, MY_NEW_TYPE, MyFoo::OnMyFirstEvent)
Line 94: Line 91:
 
   ...
 
   ...
 
wxEND_EVENT_TABLE()
 
wxEND_EVENT_TABLE()
</source>
+
</syntaxhighlight>
  
 
The dynamic equivalents would be:
 
The dynamic equivalents would be:
<source>
+
 
 +
<syntaxhighlight lang="cpp">
 
// If done inside a MyFoo function:
 
// If done inside a MyFoo function:
 
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this);
 
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this);
Line 107: Line 105:
 
...
 
...
 
pFoo->Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, pFoo, foo_two);
 
pFoo->Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, pFoo, foo_two);
</source>
+
</syntaxhighlight>
  
 
If this code is not in the same cpp file as the MY_NEW_TYPE definition, you'll need to declare it here first:
 
If this code is not in the same cpp file as the MY_NEW_TYPE definition, you'll need to declare it here first:
Line 118: Line 116:
  
 
==Subclassing wxCommandEvent==
 
==Subclassing wxCommandEvent==
This shows how to create a custom event class which can transport a <wxref class="wxRealPoint"></wxref> (who said there's no real point in custom events? ;) and the alternative ways to make it work.
+
This shows how to create a custom event class which can transport a wxRealPoint (who said there's no real point in custom events? ;) and the alternative ways to make it work.
  
 
===Subclassing===
 
===Subclassing===
 
You may do this in a cpp file, but often you'll use a header.
 
You may do this in a cpp file, but often you'll use a header.
  
<source>
+
<syntaxhighlight lang="cpp">
 
class MyFooEvent;
 
class MyFooEvent;
 
wxDECLARE_EVENT(MY_NEW_TYPE, MyFooEvent);
 
wxDECLARE_EVENT(MY_NEW_TYPE, MyFooEvent);
Line 146: Line 144:
 
wxRealPoint m_RealPoint;
 
wxRealPoint m_RealPoint;
 
};
 
};
  </source>
+
  </syntaxhighlight>
  
 
Now the macros. If you aren't going to use an event table you can omit the ones marked 'optional'.
 
Now the macros. If you aren't going to use an event table you can omit the ones marked 'optional'.
<source>
+
<syntaxhighlight lang="cpp">
 
typedef void (wxEvtHandler::*MyFooEventFunction)(MyFooEvent &);
 
typedef void (wxEvtHandler::*MyFooEventFunction)(MyFooEvent &);
  
Line 161: Line 159:
 
#define EVT_MYFOO_RANGE(id1,id2, func) \
 
#define EVT_MYFOO_RANGE(id1,id2, func) \
 
wx__DECLARE_EVT2(MY_NEW_TYPE, id1, id2, MyFooEventHandler(func))
 
wx__DECLARE_EVT2(MY_NEW_TYPE, id1, id2, MyFooEventHandler(func))
</source>
+
</syntaxhighlight>
  
 
===Posting:===
 
===Posting:===
<source>
+
<syntaxhighlight lang="cpp">
 
// As before, define a new wxEventType
 
// As before, define a new wxEventType
 
wxDEFINE_EVENT(MY_NEW_TYPE, MyFooEvent);
 
wxDEFINE_EVENT(MY_NEW_TYPE, MyFooEvent);
Line 180: Line 178:
 
// Post the event. pDest is a pointer to the destination
 
// Post the event. pDest is a pointer to the destination
 
wxPostEvent(pDest, event);
 
wxPostEvent(pDest, event);
  </source>
+
  </syntaxhighlight>
  
 
===Catching:===
 
===Catching:===
  
<source>
+
<syntaxhighlight lang="cpp">
 
// Using Bind(). You'll often do this in the destination class constructor:
 
// Using Bind(). You'll often do this in the destination class constructor:
 
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this, foo_one); // Version for modern compilers
 
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this, foo_one); // Version for modern compilers
Line 202: Line 200:
 
     wxMessageBox(msg);
 
     wxMessageBox(msg);
 
}
 
}
</source>
+
</syntaxhighlight>
  
 
===What could ''possibly'' go wrong?===
 
===What could ''possibly'' go wrong?===
Line 208: Line 206:
  
 
==See also:==
 
==See also:==
[http://docs.wxwidgets.org/trunk/overview_events.html The 'Events' overview]
+
[https://docs.wxwidgets.org/trunk/overview_events.html The 'Events' overview]
  
[http://docs.wxwidgets.org/trunk/page_samples.html#page_samples_event The 'event' sample]
+
[https://docs.wxwidgets.org/trunk/page_samples.html#page_samples_event The 'event' sample]
  
 
[http://wiki.wxwidgets.org/Inter-Thread_and_Inter-Process_communication Inter-thread communication]
 
[http://wiki.wxwidgets.org/Inter-Thread_and_Inter-Process_communication Inter-thread communication]

Latest revision as of 19:36, 19 October 2018

Introduction

Starting with wx3.0, there have been enough changes to how custom events are created (different macros) and used (wxEvtHandler::Bind) that a separate page will be useful. You can find the page for older wx versions here.

Things you should understand before you start

Events and Event-types

These two completely different things often get confused.

An event is an object of class wxEvent, or more usually of one of its derivatives e.g. wxCommandEvent. A wxEventType is just a typedef for int. However the (understandable) tendency to use names like MyFooCommandEvent for wxEventTypes can cause considerable confusion.

Event Macros

To make the event system work, wx uses macros which you don't need to know much about. However there are other macros that do need a mention because you should use them, and they have changed since wx2.8: the macros for creating a new wxEventType.

The old macros for this were: DECLARE_EVENT_TYPE(MY_NEW_TYPE, wxID_ANY) and DEFINE_EVENT_TYPE(MY_NEW_TYPE) though it was almost as easy to use non-macro code. SInce wx3.0 events are type-safe and the new macros take this into account; so code that doesn't have to be backwards-compatible should use: wxDECLARE_EVENT(MY_NEW_TYPE, wxCommandEvent); and wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent); (Note the semicolons.) You now have to specify the event class that will use the new wxEventType; it will often be wxCommandEvent.

Dynamic or Static event binding

wx code has traditionally tended to use static event tables to connect events to handlers. However it has long been possible to do this dynamically, and since wx3.0 this has become easier and much safer with the addition of wxEvtHandler::Bind. Custom events can use either method.

It is strongly suggested that you no longer use wxEvtHandler::Connect (except when backward-compatibility with wx2.8 is essential) as it is so easy to get it wrong; and getting it wrong either fails silently or causes runtime crashes.

Dispatching your custom event

Once you've created an event instance using your custom class or wxEventType, you need to send or post it to its destination. You can do this using the same methods as in wx2.8: sending (synchronously) with wxEvtHandler::ProcessEvent or posting (asynchronously) with wxEvtHandler::AddPendingEvent or the convenience function wxPostEvent. However since wx3.0 there is also the asynchronous (and more thread-safe) wxEvtHandler::QueueEvent and its convenience function wxQueueEvent.

What sort of custom event do I need?

The term 'custom event' can be used to mean either creating your own subclass of wxEvent or wxCommandEvent, or just defining a new wxEventType to use with the standard event classes. Which of these you do depends on how much, and what type of, data you want to send in your event.

Most of the time you won't need a subclassed wxEvent, just a standard event with a new wxEventType to 'label' it. Even a plain wxEvent can transport useful data in its id and eventType fields. A wxCommandEvent additionally has fields for another int, a long int and a wxString. It can also take a void* in its clientData field. All these should be more than adequate in most situations, so needing to create your own custom class is rare. However if you do need to transport lots of data or have other special needs, subclassing is available and gives you the flexibility to do whatever is required.

Creating and using a new wxEventType

This is easy and (almost) foolproof.

Creation:

In a suitable cpp file add the line:

wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent);

It doesn't have to be a wxCommandEvent, but that's the usual choice.

Posting:

You can use the new wxEventType either with or without giving the event a specific id.

wxCommandEvent event(MY_NEW_TYPE); // No specific id

// Add any data; sometimes the only information needed at the destination is the arrival of the event itself
event.SetString("This is the data");

// Then post the event
wxPostEvent(this, event); // to ourselves
wxPostEvent(pBar, event); // or to a different instance or class

If you need to send more specific information to the destination, add an id. This can easily be done using an enum.

// The values don't matter, as they're only used with this wxEventType
enum { foo_one = 1, foo_two, foo_three };

wxCommandEvent event_a(MY_NEW_TYPE, foo_one); 
event_a.SetString("data one"); wxPostEvent(this, event_a);

wxCommandEvent event_b(MY_NEW_TYPE, foo_two); 
event_b.SetString("data two"); wxPostEvent(this, event_b);

wxPostEvent(this, event_a); wxPostEvent(this, event_b);
// You can send the same event elsewhere as it's cloned in wxPostEvent
wxPostEvent(pBar, event_b);

Catching:

You can catch the posted event either with an event table or with wxEvtHandler::Bind. If you didn't specify the id (though this would work even if you did) the event table would be:

wxBEGIN_EVENT_TABLE(MyFoo, wxFoo))
  EVT_COMMAND(wxID_ANY, MY_NEW_TYPE, MyFoo::OnMyEvent)
  ...
wxEND_EVENT_TABLE()

The specific-id version would be:

wxBEGIN_EVENT_TABLE(MyFoo, wxFoo)
  EVT_COMMAND(foo_one, MY_NEW_TYPE, MyFoo::OnMyFirstEvent)
  EVT_COMMAND(foo_two, MY_NEW_TYPE, MyFoo::OnMySecondEvent)
  ...
wxEND_EVENT_TABLE()

The dynamic equivalents would be:

// If done inside a MyFoo function:
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this);
// or from elsewhere (pFoo is a pointer to a MyFoo instance):
pFoo->Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, pFoo);

// Similarly for specified ids
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this, foo_one);
...
pFoo->Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, pFoo, foo_two);

If this code is not in the same cpp file as the MY_NEW_TYPE definition, you'll need to declare it here first: wxDECLARE_EVENT(MY_NEW_TYPE, wxCommandEvent);

What could possibly go wrong?

You must define the wxEventType exactly once. If you add wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent); to two files, it will be defined twice with two different values. The same thing will happen if you write it only once, but you put it in a header file that is #included more than once. Why does that matter? Because you'll be posting an event with the type (e.g.) 12000, and trying to catch events with type 12001; which will silently fail.


Subclassing wxCommandEvent

This shows how to create a custom event class which can transport a wxRealPoint (who said there's no real point in custom events? ;) and the alternative ways to make it work.

Subclassing

You may do this in a cpp file, but often you'll use a header.

class MyFooEvent;
wxDECLARE_EVENT(MY_NEW_TYPE, MyFooEvent);

class MyFooEvent: public wxCommandEvent
{
public:
	MyFooEvent(wxEventType commandType = MY_NEW_TYPE, int id = 0)
        		:  wxCommandEvent(commandType, id) { }
 
	// You *must* copy here the data to be transported
	MyFooEvent(const MyFooEvent& event)
        		:  wxCommandEvent(event) { this->SetPoint(event.GetPoint()); }
 
	// Required for sending with wxPostEvent()
	wxEvent* Clone() const { return new MyFooEvent(*this); }
 
	wxRealPoint GetPoint() const { return m_RealPoint; }
	void SetPoint(const wxRealPoint& rp) { m_RealPoint = rp; }
 
private:
	wxRealPoint m_RealPoint;
};

Now the macros. If you aren't going to use an event table you can omit the ones marked 'optional'.

typedef void (wxEvtHandler::*MyFooEventFunction)(MyFooEvent &);

#define MyFooEventHandler(func) wxEVENT_HANDLER_CAST(MyFooEventFunction, func)                    

// Optional: define an event table entry
#define EVT_MYFOO(id, func) \
 	wx__DECLARE_EVT1(MY_NEW_TYPE, id, MyFooEventHandler(func))

// Very optionally, you can do a similar #define for EVT_MYFOO_RANGE.
#define EVT_MYFOO_RANGE(id1,id2, func) \
	wx__DECLARE_EVT2(MY_NEW_TYPE, id1, id2, MyFooEventHandler(func))

Posting:

// As before, define a new wxEventType
wxDEFINE_EVENT(MY_NEW_TYPE, MyFooEvent);

// Optional, but you'll often want to be able to assign specific IDs
enum { foo_one = 1, foo_two, foo_three };
...
// Create an instance of the event, optionally using a specific id
MyFooEvent event(MY_NEW_TYPE,  foo_one);

wxRealPoint rp(3.14159, 2.71828);
// Store the data in the event
event.SetPoint(rp);

// Post the event. pDest is a pointer to the destination
wxPostEvent(pDest, event);

Catching:

// Using Bind(). You'll often do this in the destination class constructor:
Bind(MY_NEW_TYPE, &MyFoo::OnMyEvent, this, foo_one); // Version for modern compilers
//Bind(MY_NEW_TYPE, MyFooEventHandler(MyFoo::OnMyEvent), this, foo_one); // Version for compilers new and old

// Using an event table
wxBEGIN_EVENT_TABLE(MyFoo, wxFoo)
      EVT_MYFOO(wxID_ANY, MyFoo::OnMyEvent)
// or EVT_MYFOO(foo_one, MyFoo::OnMyEvent)
// or EVT_MYFOO_RANGE(foo_one, foo_three, MyFoo::OnMyEvent)
wxEND_EVENT_TABLE()

// The handler:
void MyFoo::OnMyEvent(MyFooEvent& event)
{
    wxString msg = wxString::Format("pi = %f  e = %f", event.GetPoint().x, event.GetPoint().y);
    wxMessageBox(msg);
}

What could possibly go wrong?

In your subclass, you must override wxEvent::Clone and copy the data; otherwise the event will arrive, but it will be empty.

See also:

The 'Events' overview

The 'event' sample

Inter-thread communication