update custom event definition documentation; document wxDEFINE/DECLARE_EVENT()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58715 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -478,170 +478,152 @@ all events (or any selection of them) to the parent window.
|
|||||||
|
|
||||||
@subsection overview_events_custom_general General approach
|
@subsection overview_events_custom_general General approach
|
||||||
|
|
||||||
Since version 2.2.x of wxWidgets, each event type is identified by an ID
|
As each event is uniquely defined by its event type, defining a custom event
|
||||||
given to the event type @e at runtime that makes it possible to add
|
starts with defining a new event type for it. This is done using
|
||||||
new event types to the library or application without risking ID clashes
|
wxDEFINE_EVENT() macro. As an event type is a variable, it can also be
|
||||||
(two different event types mistakingly getting the same event ID).
|
declared using wxDECLARE_EVENT() if necessary.
|
||||||
This event type ID is stored in a struct of type <b>const wxEventType</b>.
|
|
||||||
|
|
||||||
In order to define a new event type, there are principally two choices.
|
The next thing to do is to decide whether you need to define a custom event
|
||||||
One is to define an entirely new event class (typically deriving from
|
class for events of this type or if you can reuse an existing class, typically
|
||||||
wxEvent or wxCommandEvent).
|
either wxEvent (which doesn't provide any extra information) or wxCommandEvent
|
||||||
|
(which contains several extra fields and also propagates upwards by default).
|
||||||
The other is to use the existing event classes and give them a new event
|
Both strategies are described in details below. See also the @ref
|
||||||
type. You'll have to define and declare a new event type either way
|
page_samples_event for a complete example of code defining and working with the
|
||||||
using the following macros:
|
custom event types.
|
||||||
|
|
||||||
@code
|
|
||||||
// in the header of the source file
|
|
||||||
extern const wxEventType wxEVT_YOUR_EVENT_NAME;
|
|
||||||
|
|
||||||
// in the implementation
|
|
||||||
DEFINE_EVENT_TYPE(wxEVT_YOUR_EVENT_NAME)
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
See also the @ref page_samples_event for an example of code
|
|
||||||
defining and working with the custom event types.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection overview_events_custom_existing Using Existing Event Classes
|
@subsection overview_events_custom_existing Using Existing Event Classes
|
||||||
|
|
||||||
If you just want to use a wxCommandEvent with a new event type, use
|
If you just want to use a wxCommandEvent with a new event type, use one of the
|
||||||
one of the generic event table macros listed below, without having to define a
|
generic event table macros listed below, without having to define a new event
|
||||||
new event class yourself. This also has the advantage that you won't have to define a
|
class yourself.
|
||||||
new wxEvent::Clone() method for posting events between threads etc.
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
extern const wxEventType wxEVT_MY_EVENT;
|
// this is typically in a header: it just declares MY_EVENT event type
|
||||||
DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)
|
wxDECLARE_EVENT(MY_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
// user code intercepting the event
|
// this is a definition so can't be in a header
|
||||||
|
wxDEFINE_EVENT(MY_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
|
// example of code handling the event with event tables
|
||||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
EVT_MENU (wxID_EXIT, MyFrame::OnExit)
|
EVT_MENU (wxID_EXIT, MyFrame::OnExit)
|
||||||
// ....
|
...
|
||||||
EVT_COMMAND (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
|
EVT_COMMAND (ID_MY_WINDOW, MY_EVENT, MyFrame::OnMyEvent)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
void MyFrame::OnMyEvent( wxCommandEvent& event )
|
void MyFrame::OnMyEvent(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
// do something
|
// do something
|
||||||
wxString text = event.GetText();
|
wxString text = event.GetText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// example of code handling the event with Connect():
|
||||||
|
MyFrame::MyFrame()
|
||||||
|
{
|
||||||
|
Connect(ID_MY_WINDOW, MY_EVENT, &MyFrame::OnMyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
// user code sending the event
|
// example of code generating the event
|
||||||
|
|
||||||
void MyWindow::SendEvent()
|
void MyWindow::SendEvent()
|
||||||
{
|
{
|
||||||
wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
|
wxCommandEvent event(MY_EVENT, GetId());
|
||||||
event.SetEventObject( this );
|
event.SetEventObject(this);
|
||||||
|
|
||||||
// Give it some contents
|
// Give it some contents
|
||||||
event.SetText( wxT("Hallo") );
|
event.SetText("Hello");
|
||||||
|
|
||||||
// Send it
|
// Do send it
|
||||||
GetEventHandler()->ProcessEvent( event );
|
ProcessWindowEvent(event);
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@subsection overview_events_custom_generic Generic Event Table Macros
|
|
||||||
|
|
||||||
@beginTable
|
|
||||||
@row2col{EVT_CUSTOM(event\, id\, func),
|
|
||||||
Allows you to add a custom event table
|
|
||||||
entry by specifying the event identifier (such as wxEVT_SIZE),
|
|
||||||
the window identifier, and a member function to call.}
|
|
||||||
@row2col{EVT_CUSTOM_RANGE(event\, id1\, id2\, func),
|
|
||||||
The same as EVT_CUSTOM, but responds to a range of window identifiers.}
|
|
||||||
@row2col{EVT_COMMAND(id\, event\, func),
|
|
||||||
The same as EVT_CUSTOM, but expects a member function with a
|
|
||||||
wxCommandEvent argument.}
|
|
||||||
@row2col{EVT_COMMAND_RANGE(id1\, id2\, event\, func),
|
|
||||||
The same as EVT_CUSTOM_RANGE, but
|
|
||||||
expects a member function with a wxCommandEvent argument.}
|
|
||||||
@row2col{EVT_NOTIFY(event\, id\, func),
|
|
||||||
The same as EVT_CUSTOM, but
|
|
||||||
expects a member function with a wxNotifyEvent argument.}
|
|
||||||
@row2col{EVT_NOTIFY_RANGE(event\, id1\, id2\, func),
|
|
||||||
The same as EVT_CUSTOM_RANGE, but
|
|
||||||
expects a member function with a wxNotifyEvent argument.}
|
|
||||||
@endTable
|
|
||||||
|
|
||||||
|
|
||||||
@subsection overview_events_custom_ownclass Defining Your Own Event Class
|
@subsection overview_events_custom_ownclass Defining Your Own Event Class
|
||||||
|
|
||||||
Under certain circumstances, you must define your own event
|
Under certain circumstances, you must define your own event class e.g., for
|
||||||
class e.g., for sending more complex data from one place to another. Apart
|
sending more complex data from one place to another. Apart from defining your
|
||||||
from defining your event class, you will also need to define your own
|
event class, you also need to define your own event table macro if you want to
|
||||||
event table macro (which is quite long). Watch out to put in enough
|
use event tables for handling events of this type.
|
||||||
casts to the inherited event function. Here is an example:
|
|
||||||
|
Here is an example:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
// code defining event
|
// define a new event class
|
||||||
|
class MyPlotEvent: public wxEvent
|
||||||
class wxPlotEvent: public wxNotifyEvent
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );
|
MyPlotEvent(wxEventType eventType, int winid, const wxPoint& pos)
|
||||||
|
: wxEvent(winid, eventType),
|
||||||
|
m_pos(pos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
wxPlotCurve *GetCurve()
|
wxPoint GetPoint() const { return m_pos; }
|
||||||
{ return m_curve; }
|
|
||||||
|
|
||||||
// required for sending with wxPostEvent()
|
// implement the base class pure virtual
|
||||||
virtual wxEvent *Clone() const;
|
virtual wxEvent *Clone() const { return new MyPlotEvent(*this); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxPlotCurve *m_curve;
|
const wxPoint m_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const wxEventType wxEVT_PLOT_ACTION;
|
// we define a single MY_PLOT_CLICKED event type associated with the class
|
||||||
typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);
|
// above but typically you are going to have more than one event type, e.g. you
|
||||||
|
// could also have MY_PLOT_ZOOMED or MY_PLOT_PANNED &c -- in which case you
|
||||||
#define wxPlotEventHandler(func) \
|
// would just add more similar lines here
|
||||||
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxPlotEventFunction, &func)
|
wxDEFINE_EVENT(MY_PLOT_CLICKED, MyPlotEvent);
|
||||||
#define EVT_PLOT(id, fn) \
|
|
||||||
wx__DECLARE_EVT1(wxEVT_PLOT_ACTION, id, wxPlotEventHandler(fn))
|
|
||||||
|
|
||||||
|
|
||||||
// code implementing the event type and the event class
|
// if you want to support old compilers you need to use some ugly macros:
|
||||||
|
typedef void (wxEvtHandler::*MyPlotEventFunction)(MyPlotEvent&);
|
||||||
|
#define MyPlotEventHandler(func) wxEVENT_HANDLER_CAST(MyPlotEventFunction, func)
|
||||||
|
|
||||||
DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )
|
// if your code is only built sing reasonably modern compilers, you could just
|
||||||
|
// do this instead:
|
||||||
|
#define MyPlotEventHandler(func) (&func)
|
||||||
|
|
||||||
wxPlotEvent::wxPlotEvent( ... )
|
// finally define a macro for creating the event table entries for the new
|
||||||
{
|
// event type
|
||||||
...
|
//
|
||||||
}
|
// remember that you don't need this at all if you only use Connect() and that
|
||||||
|
// you can replace MyPlotEventHandler(func) with just &func unless you use a
|
||||||
|
// really old compiler
|
||||||
|
#define MY_EVT_PLOT_CLICK(id, func) \
|
||||||
|
wx__DECLARE_EVT1(MY_PLOT_CLICKED, id, MyPlotEventHandler(func))
|
||||||
|
|
||||||
|
|
||||||
// user code intercepting the event
|
// example of code handling the event (you will use one of these methods, not
|
||||||
|
// both, of course):
|
||||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
EVT_PLOT (ID_MY_WINDOW, MyFrame::OnPlot)
|
EVT_PLOT(ID_MY_WINDOW, MyFrame::OnPlot)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
void MyFrame::OnPlot( wxPlotEvent &event )
|
MyFrame::MyFrame()
|
||||||
{
|
{
|
||||||
wxPlotCurve *curve = event.GetCurve();
|
Connect(ID_MY_WINDOW, MY_PLOT_CLICKED, &MyFrame::OnPlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnPlot(MyPlotEvent& event)
|
||||||
|
{
|
||||||
|
... do something with event.GetPoint() ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// user code sending the event
|
// example of code generating the event:
|
||||||
|
|
||||||
void MyWindow::SendEvent()
|
void MyWindow::SendEvent()
|
||||||
{
|
{
|
||||||
wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
|
MyPlotEvent event(MY_PLOT_CLICKED, GetId(), wxPoint(...));
|
||||||
event.SetEventObject( this );
|
event.SetEventObject(this);
|
||||||
event.SetCurve( m_curve );
|
ProcessWindowEvent(event);
|
||||||
GetEventHandler()->ProcessEvent( event );
|
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@section overview_events_misc Miscellaneous Notes
|
@section overview_events_misc Miscellaneous Notes
|
||||||
|
|
||||||
@subsection overview_events_virtual Event Handlers vs Virtual Methods
|
@subsection overview_events_virtual Event Handlers vs Virtual Methods
|
||||||
@@ -755,6 +737,31 @@ If you use wxNewId() consistently in your application, you can be sure that
|
|||||||
your identifiers don't conflict accidentally.
|
your identifiers don't conflict accidentally.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection overview_events_custom_generic Generic Event Table Macros
|
||||||
|
|
||||||
|
@beginTable
|
||||||
|
@row2col{EVT_CUSTOM(event\, id\, func),
|
||||||
|
Allows you to add a custom event table
|
||||||
|
entry by specifying the event identifier (such as wxEVT_SIZE),
|
||||||
|
the window identifier, and a member function to call.}
|
||||||
|
@row2col{EVT_CUSTOM_RANGE(event\, id1\, id2\, func),
|
||||||
|
The same as EVT_CUSTOM, but responds to a range of window identifiers.}
|
||||||
|
@row2col{EVT_COMMAND(id\, event\, func),
|
||||||
|
The same as EVT_CUSTOM, but expects a member function with a
|
||||||
|
wxCommandEvent argument.}
|
||||||
|
@row2col{EVT_COMMAND_RANGE(id1\, id2\, event\, func),
|
||||||
|
The same as EVT_CUSTOM_RANGE, but
|
||||||
|
expects a member function with a wxCommandEvent argument.}
|
||||||
|
@row2col{EVT_NOTIFY(event\, id\, func),
|
||||||
|
The same as EVT_CUSTOM, but
|
||||||
|
expects a member function with a wxNotifyEvent argument.}
|
||||||
|
@row2col{EVT_NOTIFY_RANGE(event\, id1\, id2\, func),
|
||||||
|
The same as EVT_CUSTOM_RANGE, but
|
||||||
|
expects a member function with a wxNotifyEvent argument.}
|
||||||
|
@endTable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@subsection overview_events_macros Event Handling Summary
|
@subsection overview_events_macros Event Handling Summary
|
||||||
|
|
||||||
For the full list of event classes, please see the
|
For the full list of event classes, please see the
|
||||||
|
@@ -3497,14 +3497,125 @@ wxEventType wxEVT_NULL;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes a new event type using wxNewEventType().
|
Initializes a new event type using wxNewEventType().
|
||||||
|
|
||||||
|
@deprecated Use wxDEFINE_EVENT() instead
|
||||||
*/
|
*/
|
||||||
#define DEFINE_EVENT_TYPE(name) const wxEventType name = wxNewEventType();
|
#define DEFINE_EVENT_TYPE(name) const wxEventType name = wxNewEventType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Generates a new unique event type.
|
Generates a new unique event type.
|
||||||
|
|
||||||
|
Usually this function is only used by wxDEFINE_EVENT() and not called
|
||||||
|
directly.
|
||||||
*/
|
*/
|
||||||
wxEventType wxNewEventType();
|
wxEventType wxNewEventType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Define a new event type associated with the specified event class.
|
||||||
|
|
||||||
|
This macro defines a new unique event type @a name associated with the
|
||||||
|
event class @a cls.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
@code
|
||||||
|
wxDEFINE_EVENT(MY_COMMAND_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
|
class MyCustomEvent : public wxEvent { ... };
|
||||||
|
wxDEFINE_EVENT(MY_CUSTOM_EVENT, MyCustomEvent);
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@see wxDECLARE_EVENT(), @ref overview_events_custom
|
||||||
|
*/
|
||||||
|
#define wxDEFINE_EVENT(name, cls) \
|
||||||
|
const wxEventTypeTag< cls > name(wxNewEventType())
|
||||||
|
|
||||||
|
/**
|
||||||
|
Declares a custom event type.
|
||||||
|
|
||||||
|
This macro declares a variable called @a name which must be defined
|
||||||
|
elsewhere using wxDEFINE_EVENT().
|
||||||
|
|
||||||
|
The class @a cls must be the wxEvent-derived class associated with the
|
||||||
|
events of this type and its full declaration must be visible from the point
|
||||||
|
of use of this macro.
|
||||||
|
*/
|
||||||
|
#define wxDECLARE_EVENT(name, cls) \
|
||||||
|
wxDECLARE_EXPORTED_EVENT(wxEMPTY_PARAMETER_VALUE, name, cls)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Variant of wxDECLARE_EVENT() used for event types defined inside a shared
|
||||||
|
library.
|
||||||
|
|
||||||
|
This is mostly used by wxWidgets internally, e.g.
|
||||||
|
@code
|
||||||
|
wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEvent)
|
||||||
|
@endcode
|
||||||
|
*/
|
||||||
|
#define wxDECLARE_EXPORTED_EVENT( expdecl, name, cls ) \
|
||||||
|
extern const expdecl wxEventTypeTag< cls > name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Helper macro for definition of custom event table macros.
|
||||||
|
|
||||||
|
This macro must only be used if wxEVENTS_COMPATIBILITY_2_8 is 1, otherwise
|
||||||
|
it is better and more clear to just use the address of the function
|
||||||
|
directly as this is all this macro does in this case. However it needs to
|
||||||
|
explicitly cast @a func to @a functype, which is the type of wxEvtHandler
|
||||||
|
member function taking the custom event argument when
|
||||||
|
wxEVENTS_COMPATIBILITY_2_8 is 0.
|
||||||
|
|
||||||
|
See wx__DECLARE_EVT0 for an example of use.
|
||||||
|
|
||||||
|
@see @ref overview_events_custom_ownclass
|
||||||
|
*/
|
||||||
|
#define wxEVENT_HANDLER_CAST(functype, func) (&func)
|
||||||
|
|
||||||
|
//@{
|
||||||
|
/**
|
||||||
|
These macros are used to define event table macros for handling custom
|
||||||
|
events.
|
||||||
|
|
||||||
|
Example of use:
|
||||||
|
@code
|
||||||
|
class MyEvent : public wxEvent { ... };
|
||||||
|
|
||||||
|
// note that this is not necessary unless using old compilers: for the
|
||||||
|
// reasonably new ones just use &func instead of MyEventHandler(func)
|
||||||
|
typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
|
||||||
|
#define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
|
||||||
|
|
||||||
|
wxDEFINE_EVENT(MY_EVENT_TYPE, MyEvent);
|
||||||
|
|
||||||
|
#define EVT_MY(id, func) \
|
||||||
|
wx__DECLARE_EVT1(MY_EVENT_TYPE, id, MyEventHandler(func))
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
|
EVT_MY(wxID_ANY, MyFrame::OnMyEvent)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@param evt
|
||||||
|
The event type to handle.
|
||||||
|
@param id
|
||||||
|
The identifier of events to handle.
|
||||||
|
@param id1
|
||||||
|
The first identifier of the range.
|
||||||
|
@param id2
|
||||||
|
The second identifier of the range.
|
||||||
|
@param fn
|
||||||
|
The event handler method.
|
||||||
|
*/
|
||||||
|
#define wx__DECLARE_EVT2(evt, id1, id2, fn) \
|
||||||
|
DECLARE_EVENT_TABLE_ENTRY(evt, id1, id2, fn, NULL),
|
||||||
|
#define wx__DECLARE_EVT1(evt, id, fn) \
|
||||||
|
wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)
|
||||||
|
#define wx__DECLARE_EVT0(evt, fn) \
|
||||||
|
wx__DECLARE_EVT1(evt, wxID_ANY, fn)
|
||||||
|
//@}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Use this macro inside a class declaration to declare a @e static event table
|
Use this macro inside a class declaration to declare a @e static event table
|
||||||
for that class.
|
for that class.
|
||||||
|
Reference in New Issue
Block a user