X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dbd94b75015561fe527069c138ce43c44797fe35..88c23b64c7cc5ea6f6e2841ba40cc81bf943c27a:/docs/latex/wx/tevent.tex diff --git a/docs/latex/wx/tevent.tex b/docs/latex/wx/tevent.tex index ea368dd84f..7a959a9fb4 100644 --- a/docs/latex/wx/tevent.tex +++ b/docs/latex/wx/tevent.tex @@ -211,7 +211,6 @@ here is a list of system events which will NOT get sent to the parent's event ha \twocolitem{\helpref{wxSizeEvent}{wxsizeevent}}{A size event} \twocolitem{\helpref{wxScrollWinEvent}{wxscrollwinevent}}{A scroll event sent by a scrolled window (not a scroll bar)} \twocolitem{\helpref{wxSysColourChangedEvent}{wxsyscolourchangedevent}}{A system colour change event} -\twocolitem{\helpref{wxUpdateUIEvent}{wxupdateuievent}}{A user interface update event} \end{twocollist} In some cases, it might be desired by the programmer to get a certain number @@ -220,6 +219,30 @@ used by, the native controls in a dialog. In this case, a special event handler will have to be written that will override ProcessEvent() in order to pass all events (or any selection of them) to the parent window. + +\subsection{Events generated by the user vs programmatically generated events}\label{progevent} + +While generically \helpref{wxEvents}{wxevent} can be generated both by user +actions (e.g. resize of a \helpref{wxWindow}{wxwindow}) and by calls to functions +(e.g. \helpref{wxWindow::SetSize}{wxwindowsetsize}), wxWidgets controls +normally send \helpref{wxCommandEvent}{wxcommandevent}-derived events only for +the user-generated events. The only {\bf exceptions} to this rule are: + +\begin{twocollist}\itemsep=0pt +\twocolitem{\helpref{wxNotebook::AddPage}{wxnotebookaddpage}}{No event-free alternatives} +\twocolitem{\helpref{wxNotebook::AdvanceSelection}{wxnotebookadvanceselection}}{No event-free alternatives} +\twocolitem{\helpref{wxNotebook::DeletePage}{wxnotebookdeletepage}}{No event-free alternatives} +\twocolitem{\helpref{wxNotebook::SetSelection}{wxnotebooksetselection}}{Use \helpref{wxNotebook::ChangeSelection}{wxnotebookchangeselection} instead, as \helpref{wxNotebook::SetSelection}{wxnotebooksetselection} is deprecated} +\twocolitem{\helpref{wxTreeCtrl::Delete}{wxtreectrldelete}}{No event-free alternatives} +\twocolitem{\helpref{wxTreeCtrl::DeleteAllItems}{wxtreectrldeleteallitems}}{No event-free alternatives} +\twocolitem{\helpref{wxTreeCtrl::EditLabel}{wxtreectrleditlabel}}{No event-free alternatives} +\twocolitem{All \helpref{wxTextCtrl}{wxtextctrl} methods}{\helpref{wxTextCtrl::ChangeValue}{wxtextctrlchangevalue} can be used instead +of \helpref{wxTextCtrl::SetValue}{wxtextctrlsetvalue} but the other functions, +such as \helpref{Replace}{wxtextctrlreplace} or \helpref{WriteText}{wxtextctrlwritetext} +don't have event-free equivalents} +\end{twocollist} + + % VZ: it doesn't work like this, but just in case we ever reenable this % behaviour, I leave it here % @@ -356,21 +379,6 @@ you can use identifiers below wxID\_LOWEST. \subsection{Event macros summary}\label{eventmacros} -\wxheading{Generic event table macros} - -\twocolwidtha{8cm}% -\begin{twocollist}\itemsep=0pt -\twocolitem{\windowstyle{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.} -\twocolitem{\windowstyle{EVT\_CUSTOM\_RANGE(event, id1, id2, func)}}{The same as EVT\_CUSTOM, -but responds to a range of window identifiers.} -\twocolitem{\windowstyle{EVT\_COMMAND(id, event, func)}}{The same as EVT\_CUSTOM, but -expects a member function with a wxCommandEvent argument.} -\twocolitem{\windowstyle{EVT\_COMMAND\_RANGE(id1, id2, event, func)}}{The same as EVT\_CUSTOM\_RANGE, but -expects a member function with a wxCommandEvent argument.} -\end{twocollist} - \wxheading{Macros listed by event class} The documentation for specific event macros is organised by event class. Please refer @@ -413,3 +421,175 @@ update pseudo-events, which are generated to give the application the chance to toolbars and controls.} \end{twocollist} +\subsection{Custom event summary}\label{customevents} + +\wxheading{General approach} + +Since version 2.2.x of wxWidgets, each event type is identified by ID which +is given to the event type {\it at runtime} which makes it possible to add +new event types to the library or application without risking ID clashes +(two different event types mistakingly getting the same event ID). This +event type ID is stored in a struct of type {\bf const wxEventType}. + +In order to define a new event type, there are principally two choices. +One is to define a entirely new event class (typically deriving from +\helpref{wxEvent}{wxevent} or \helpref{wxCommandEvent}{wxcommandevent}. +The other is to use the existing event classes and give them an new event +type. You'll have to define and declare a new event type using either way, +and this is done using the following macros: + +\begin{verbatim} +// in the header of the source file +BEGIN_DECLARE_EVENT_TYPES() +DECLARE_EVENT_TYPE(name, value) +END_DECLARE_EVENT_TYPES() + +// in the implementation +DEFINE_EVENT_TYPE(name) +\end{verbatim} + +You can ignore the {\it value} parameter of the DECLARE\_EVENT\_TYPE macro +since it is used only for backwards compatibility with wxWidgets 2.0.x based +applications where you have to give the event type ID an explicit value. + +See also the \helpref{event sample}{sampleevent} for an example of code +defining and working with the custom event types. + +\wxheading{Using existing event classes} + +If you just want to use a \helpref{wxCommandEvent}{wxcommandevent} with +a new event type, you can then use one of the generic event table macros +listed below, without having to define a new macro yourself. This also +has the advantage that you won't have to define a new \helpref{wxEvent::Clone()}{wxeventclone} +method for posting events between threads etc. This could look like this +in your code: + +{\small% +\begin{verbatim} +DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1) + +DEFINE_EVENT_TYPE(wxEVT_MY_EVENT) + +// user code intercepting the event + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU (wxID_EXIT, MyFrame::OnExit) + // .... + EVT_COMMAND (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent) +END_EVENT_TABLE() + +void MyFrame::OnMyEvent( wxCommandEvent &event ) +{ + // do something + wxString text = event.GetText(); +} + + +// user code sending the event + +void MyWindow::SendEvent() +{ + wxCommandEvent event( wxEVT_MY_EVENT, GetId() ); + event.SetEventObject( this ); + // Give it some contents + event.SetText( wxT("Hallo") ); + // Send it + GetEventHandler()->ProcessEvent( event ); +} +\end{verbatim} +}% + + +\wxheading{Generic event table macros} + +\twocolwidtha{8cm}% +\begin{twocollist}\itemsep=0pt +\twocolitem{\windowstyle{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.} +\twocolitem{\windowstyle{EVT\_CUSTOM\_RANGE(event, id1, id2, func)}}{The same as EVT\_CUSTOM, +but responds to a range of window identifiers.} +\twocolitem{\windowstyle{EVT\_COMMAND(id, event, func)}}{The same as EVT\_CUSTOM, but +expects a member function with a wxCommandEvent argument.} +\twocolitem{\windowstyle{EVT\_COMMAND\_RANGE(id1, id2, event, func)}}{The same as EVT\_CUSTOM\_RANGE, but +expects a member function with a wxCommandEvent argument.} +\twocolitem{\windowstyle{EVT\_NOTIFY(event, id, func)}}{The same as EVT\_CUSTOM, but +expects a member function with a wxNotifyEvent argument.} +\twocolitem{\windowstyle{EVT\_NOTIFY\_RANGE(event, id1, id2, func)}}{The same as EVT\_CUSTOM\_RANGE, but +expects a member function with a wxNotifyEvent argument.} +\end{twocollist} + + +\wxheading{Defining your own event class} + +Under certain circumstances, it will be required to define your own event +class e.g. for sending more complex data from one place to another. Apart +from defining your event class, you will also need to define your own +event table macro (which is quite long). Watch out to put in enough +casts to the inherited event function. Here is an example, taken mostly +from the {\it wxPlot} library, which is in the {\it contrib} section of +the wxWidgets sources. + +{\small% +\begin{verbatim} + +// code defining event + +class wxPlotEvent: public wxNotifyEvent +{ +public: + wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 ); + + // accessors + wxPlotCurve *GetCurve() + { return m_curve; } + + // required for sending with wxPostEvent() + wxEvent* Clone(); + +private: + wxPlotCurve *m_curve; +}; + +DECLARE_EVENT_MACRO( wxEVT_PLOT_ACTION, -1 ) + +typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&); + +#define EVT_PLOT(id, fn) \ + DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, \ + (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \ + wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ), + + +// code implementing the event type and the event class + +DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION ) + +wxPlotEvent::wxPlotEvent( ... + + +// user code intercepting the event + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_PLOT (ID_MY_WINDOW, MyFrame::OnPlot) +END_EVENT_TABLE() + +void MyFrame::OnPlot( wxPlotEvent &event ) +{ + wxPlotCurve *curve = event.GetCurve(); +} + + +// user code sending the event + +void MyWindow::SendEvent() +{ + wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() ); + event.SetEventObject( this ); + event.SetCurve( m_curve ); + GetEventHandler()->ProcessEvent( event ); +} + +\end{verbatim} +}% +