]> git.saurik.com Git - wxWidgets.git/blame - docs/doxygen/overviews/eventhandling.h
always define wxUSE_RICHEDIT[2] -- this is better than never defining them (closes...
[wxWidgets.git] / docs / doxygen / overviews / eventhandling.h
CommitLineData
15b6757b 1/////////////////////////////////////////////////////////////////////////////
3b88355f 2// Name: eventhandling.h
15b6757b
FM
3// Purpose: topic overview
4// Author: wxWidgets team
5// RCS-ID: $Id$
6// Licence: wxWindows license
7/////////////////////////////////////////////////////////////////////////////
8
880efa2a 9/**
36c9828f 10
dc28cdf8
FM
11@page overview_eventhandling Event Handling
12
13Classes: wxEvtHandler, wxWindow, wxEvent
14
15@li @ref overview_eventhandling_introduction
722f74ce
VZ
16@li @ref overview_eventhandling_eventtables
17@li @ref overview_eventhandling_connect
dc28cdf8
FM
18@li @ref overview_eventhandling_processing
19@li @ref overview_eventhandling_prog
20@li @ref overview_eventhandling_pluggable
21@li @ref overview_eventhandling_winid
22@li @ref overview_eventhandling_custom
23@li @ref overview_eventhandling_macros
24
25
26<hr>
27
28
29@section overview_eventhandling_introduction Introduction
30
722f74ce
VZ
31There are two principal ways to handle events in wxWidgets. One of them uses
32<em>event table</em> macros and allows to define the connection between events
33and their handlers only statically, i.e. during program compilation. The other
34one uses wxEvtHandler::Connect() call and can be used to connect, and
35disconnect, the handlers dynamically, i.e. during run-time depending on some
36conditions. It also allows directly connecting the events of one object to a
37handler method in another object while the static event tables can only handle
38events in the object where they are defined so using Connect() is more flexible
39than using the event tables. On the other hand, event tables are more succinct
40and centralize all event handlers connection in one place. You can either
41choose a single approach which you find preferable or freely combine both
42methods in your program in different classes or even in one and the same class,
43although this is probably sufficiently confusing to be a bad idea.
dc28cdf8 44
722f74ce
VZ
45But before you make this choice, let us discuss these two ways in some more
46details: in the next section we provide a short introduction to handling the
47events using the event tables, please see @ref overview_eventhandling_connect
48for the discussion of Connect().
49
50@section overview_eventhandling_eventtables Event Handling with Event Tables
51
52To use an <em>event table</em> you must first decide in which class you wish to
53handle the events. The only requirement imposed by wxWidgets is that this class
54must derive from wxEvtHandler and so, considering that wxWindow derives from
55it, any classes representing windows can handle events. Simple events such as
56menu commands are usually processed at the level of a top-level window
57containing the menu, so let's suppose that you need to handle some events in @c
58MyFrame class deriving from wxFrame.
59
60First thing to do is to define one or more <em>event handlers</em>. They
61are just simple (non-virtual) methods of the class which take as a parameter a
62reference to an object of wxEvent-derived class and have no return value (any
63return information is passed via the argument, which is why it is non-const).
64You also need to insert a macro
65
66@code
67DECLARE_EVENT_TABLE()
68@endcode
69
70somewhere in the class declaration. It doesn't matter where does it occur but
71it's customary to put it at the end of it because the macro changes the access
72type internally and so it's safest if there is nothing that follows it. So the
73full class declaration might look like this:
74
75@code
76class MyFrame : public wxFrame
77{
78public:
79 MyFrame(...) : wxFrame(...) { }
80
81 ...
82
83protected:
84 int m_whatever;
85
86private:
87 // notice that as the event handlers normally are not called from outside
88 // the class, they normally be private, in particular they don't need at
89 // all to be public
90 void OnExit(wxCommandEvent& event);
91 void OnButton1(wxCommandEvent& event);
92 void OnSize(wxSizeEvent& event);
93
94 // it's common to call the event handlers OnSomething() but there is no
95 // obligation to it, this one is an event handler too:
96 void DoTest(wxCommandEvent& event);
97
98 DECLARE_EVENT_TABLE()
99};
100@endcode
101
102Next the event table must be defined and, as any definition, it must be placed
103in an implementation file to tell. The event table tells wxWidgets how to map
104events to member functions and in our example it could look like this:
dc28cdf8
FM
105
106@code
107BEGIN_EVENT_TABLE(MyFrame, wxFrame)
722f74ce
VZ
108 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
109 EVT_MENU(DO_TEST, MyFrame::DoTest)
110 EVT_SIZE(MyFrame::OnSize)
111 EVT_BUTTON(BUTTON1, MyFrame::OnButton1)
dc28cdf8
FM
112END_EVENT_TABLE()
113@endcode
114
722f74ce
VZ
115Notice that you must mention a method you want to use for the event handling in
116the event table definition, just defining it in MyFrame class is @e not enough.
117
118Let us now look at the details of this definition: the first line means that we
119are defining the event table for MyFrame class and that its base class is
120wxFrame, so events not processed by MyFrame will, by default, be handled to
121wxFrame. The next four lines define connections of individual events to their
122handlers: the first two of them map menu commands from the items with the
123identifiers specified as the first macro parameter to two different member
124functions. In the next one, @c EVT_SIZE means that any changes in the size of
125the frame will result in calling OnSize() method. Note that this macro doesn't
126need a window identifier, since normally you are only interested in the current
127window's size events.
dc28cdf8
FM
128
129The EVT_BUTTON macro demonstrates that the originating event does not have to
130come from the window class implementing the event table -- if the event source
131is a button within a panel within a frame, this will still work, because event
722f74ce
VZ
132tables are searched up through the hierarchy of windows for the command events
133(but only command events, so you can't catch mouse move events in a child
134control in the parent window in the same way because wxMouseEvent doesn't
135derive from wxCommandEvent, see below for how you can do it). In this case, the
136button's event table will be searched, then the parent panel's, then the
137frame's.
138
139Finally, you need to implement the event handlers. As mentioned before, all
140event handlers take a wxEvent-derived argument whose exact class differs
141according to the type of event and the class of the originating window. For
142size events, wxSizeEvent is used. For menu commands and most control commands
143(such as button presses), wxCommandEvent is used. And when controls get more
144complicated, more specific wxCommandEvent-derived event classes providing
145additional control-specific information can be used, such as wxTreeEvent for
dc28cdf8
FM
146events from wxTreeCtrl windows.
147
722f74ce
VZ
148In the simplest possible case an event handler may not use the @c event
149parameter at all, e.g.
dc28cdf8
FM
150
151@code
722f74ce 152void MyFrame::OnExit(wxCommandEvent&)
dc28cdf8 153{
722f74ce
VZ
154 // when the user selects "Exit" from the menu we should close
155 Close(true);
156}
157@endcode
dc28cdf8 158
722f74ce
VZ
159In other cases you may need some information carried by the @c event argument,
160as in:
dc28cdf8 161
722f74ce
VZ
162@code
163void MyFrame::OnSize(wxSizeEvent& event)
164{
165 wxSize size = event.GetSize();
166
167 ... update the frame using the new size ...
168}
dc28cdf8
FM
169@endcode
170
722f74ce
VZ
171You will find the details about the event table macros and the corresponding
172wxEvent-derived classes in the discussion of each control generating these
173events.
174
175
176@section overview_eventhandling_connect Dynamic Event Handling
177
178As with the event tables, you need to decide in which class do you intend to
179handle the events first and, also as before, this class must still derive from
180wxEvtHandler (usually indirectly via wxWindow), see the declaration of MyFrame
181in the previous section. However the similarities end here and both the syntax
182and the possibilities of this way of handling events in this way are rather
183different.
184
185Let us start by looking at the syntax: the first obvious difference is that you
186don't need to use neither @c DECLARE_EVENT_TABLE() nor @c BEGIN_EVENT_TABLE and
187associated macros any more. Instead, in any place in your code, but usually in
188the code of the class defining the handlers itself (and definitely not in the
189global scope as with the event tables), you should call its Connect() method
190like this:
191
192@code
193MyFrame::MyFrame(...)
194{
195 Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
196 wxCommandEventHandler(MyFrame::OnExit));
197}
198@endcode
199
200This class should be self-explanatory except for wxCommandEventHandler part:
201this is a macro which ensures that the method is of correct type by using
202static_cast in the same way as event table macros do it inside them.
203
204Now let us describe the semantic differences:
205<ul>
206 <li>
207 Event handlers can be connected at any moment, e.g. it's possible to do
208 some initialization first and only connect the handlers if and when it
209 succeeds. This can avoid the need to test that the object was properly
210 initialized in the event handlers themselves: with Connect() they
211 simply won't be called at all if it wasn't.
212 </li>
213
214 <li>
215 As a slight extension of the above, the handlers can also be
216 Disconnect()-ed at any time. And maybe later reconnected again. Of
217 course, it's also possible to emulate this behaviour with the classic
218 static (i.e. connected via event tables) handlers by using an internal
219 flag indicating whether the handler is currently enabled and returning
220 from it if it isn't, but using dynamically connected handlers requires
221 less code and is also usually more clear.
222 </li>
223
224 <li>
225 Also notice that you must derive a class inherited from, say,
226 wxTextCtrl even if you don't want to modify the control behaviour at
227 all but just want to handle some of its events. This is especially
228 inconvenient when the control is loaded from the XRC. Connecting the
229 event handler dynamically bypasses the need for this unwanted
230 sub-classing.
231 </li>
232
233 <li>
234 Last but very, very far from least is the possibility to connect an
235 event of some object to a method of another object. This is impossible
236 to do with event tables because there is no possibility to specify the
237 object to dispatch the event to so it necessarily needs to be sent to
238 the same object which generated the event. Not so with Connect() which
239 has an optional @c eventSink parameter which can be used to specify the
240 object which will handle the event. Of course, in this case the method
241 being connected must belong to the class which is the type of the
242 @c eventSink object! To give a quick example, people often want to catch
243 mouse movement events happening when the mouse is in one of the frame
244 children in the frame itself. Doing it in a naive way doesn't work:
245 <ul>
246 <li>
247 A @c EVT_LEAVE_WINDOW(MyFrame::OnMouseLeave) line in the frame
248 event table has no effect as mouse move (including entering and
249 leaving) events are not propagated upwards to the parent window
250 (at least not by default).
251 </li>
252
253 <li>
254 Putting the same line in a child event table will crash during
255 run-time because the MyFrame method will be called on a wrong
256 object -- it's easy to convince oneself that the only object
257 which can be used here is the pointer to the child, as
258 wxWidgets has nothing else. But calling a frame method with the
259 child window pointer instead of the pointer to the frame is, of
260 course, disastrous.
261 </li>
262 </ul>
dc28cdf8 263
722f74ce
VZ
264 However writing
265 @code
266 MyFrame::MyFrame(...)
267 {
268 m_child->Connect(wxID_ANY, wxEVT_LEAVE_WINDOW,
269 wxMouseEventHandler(MyFrame::OnMouseLeave),
270 NULL, // unused extra data parameter
271 this); // this indicates the object to connect to
272 }
273 @endcode
274 will work exactly as expected. Note that you can get the object which
275 generated the event -- and which is not the same as the frame -- via
276 wxEvent::GetEventObject() method of @c event argument passed to the
277 event handler.
278 <li>
279</ul>
dc28cdf8 280
722f74ce
VZ
281To summarize, using Connect() requires slightly more typing but is much more
282flexible than using static event tables so don't hesitate to use it when you
283need this extra power. On the other hand, event tables are still perfectly fine
284in simple situations where this extra flexibility is not needed.
dc28cdf8
FM
285
286
409e6ce4 287@section overview_eventhandling_processing How Events are Processed
dc28cdf8
FM
288
289When an event is received from the windowing system, wxWidgets calls
290wxEvtHandler::ProcessEvent on the first
291event handler object belonging to the window generating the event.
292
293It may be noted that wxWidgets' event processing system implements something
294very close to virtual methods in normal C++, i.e. it is possible to alter
295the behaviour of a class by overriding its event handling functions. In
296many cases this works even for changing the behaviour of native controls.
297
298For example it is possible to filter out a number of key events sent by the
299system to a native text control by overriding wxTextCtrl and defining a
300handler for key events using EVT_KEY_DOWN. This would indeed prevent
301any key events from being sent to the native control - which might not be
302what is desired. In this case the event handler function has to call Skip()
303so as to indicate that the search for the event handler should continue.
304
305To summarize, instead of explicitly calling the base class version as you
306would have done with C++ virtual functions (i.e. @e wxTextCtrl::OnChar()),
307you should instead call wxEvent::Skip.
308
309In practice, this would look like this if the derived text control only
310accepts 'a' to 'z' and 'A' to 'Z':
311
312@code
313void MyTextCtrl::OnChar(wxKeyEvent& event)
314{
315 if ( isalpha( event.KeyCode() ) )
316 {
15b6757b
FM
317 // key code is within legal range. we call event.Skip() so the
318 // event can be processed either in the base wxWidgets class
319 // or the native control.
36c9828f 320
15b6757b 321 event.Skip();
dc28cdf8
FM
322 }
323 else
324 {
15b6757b
FM
325 // illegal key hit. we don't call event.Skip() so the
326 // event is not processed anywhere else.
36c9828f 327
15b6757b 328 wxBell();
dc28cdf8
FM
329 }
330}
331@endcode
332
333The normal order of event table searching by ProcessEvent is as follows:
334
335@li If the object is disabled (via a call to wxEvtHandler::SetEvtHandlerEnabled)
336 the function skips to step (6).
337@li If the object is a wxWindow, @b ProcessEvent is recursively called on the window's
338 wxValidator. If this returns @true, the function exits.
339@li @b SearchEventTable is called for this event handler. If this fails, the base
340 class table is tried, and so on until no more tables exist or an appropriate
341 function was found, in which case the function exits.
342@li The search is applied down the entire chain of event handlers (usually the chain has
343 a length of one). If this succeeds, the function exits.
344@li If the object is a wxWindow and the event is set to set to propagate (in the library only
345 wxCommandEvent based events are set to propagate), @b ProcessEvent is recursively applied
346 to the parent window's event handler. If this returns @true, the function exits.
347@li Finally, @b ProcessEvent is called on the wxApp object.
348
349<b>Pay close attention to Step 5</b>. People often overlook or get
350confused by this powerful feature of the wxWidgets event processing
351system. To put it a different way, events set to propagate
352(see wxEvent::ShouldPropagate)
353(most likely derived either directly or indirectly from wxCommandEvent)
354will travel up the containment hierarchy from child to parent until the
355maximal propagation level is reached or an event handler is found that
356doesn't call @c event.Skip().
357
358Finally, there is another additional complication (which, in fact, simplifies
359life of wxWidgets programmers significantly): when propagating the command
360events upwards to the parent window, the event propagation stops when it
361reaches the parent dialog, if any. This means that you don't risk to get
362unexpected events from the dialog controls (which might be left unprocessed by
363the dialog itself because it doesn't care about them) when a modal dialog is
364popped up. The events do propagate beyond the frames, however. The rationale
365for this choice is that there are only a few frames in a typical application
366and their parent-child relation are well understood by the programmer while it
367may be very difficult, if not impossible, to track down all the dialogs which
368may be popped up in a complex program (remember that some are created
369automatically by wxWidgets). If you need to specify a different behaviour for
370some reason, you can use wxWindow::SetExtraStyle(wxWS_EX_BLOCK_EVENTS)
371explicitly to prevent the events from being propagated beyond the given window
372or unset this flag for the dialogs which have it on by default.
373
374Typically events that deal with a window as a window (size, motion,
375paint, mouse, keyboard, etc.) are sent only to the window. Events
376that have a higher level of meaning and/or are generated by the window
377itself, (button click, menu select, tree expand, etc.) are command
378events and are sent up to the parent to see if it is interested in the event.
379
380Note that your application may wish to override ProcessEvent to redirect processing of
381events. This is done in the document/view framework, for example, to allow event handlers
382to be defined in the document or view. To test for command events (which will probably
383be the only events you wish to redirect), you may use wxEvent::IsCommandEvent for efficiency,
384instead of using the slower run-time type system.
385
386As mentioned above, only command events are recursively applied to the parents event
387handler in the library itself. As this quite often causes confusion for users,
388here is a list of system events which will NOT get sent to the parent's event handler:
389
390@li wxEvent: The event base class
391@li wxActivateEvent: A window or application activation event
392@li wxCloseEvent: A close window or end session event
393@li wxEraseEvent: An erase background event
394@li wxFocusEvent: A window focus event
395@li wxKeyEvent: A keypress event
396@li wxIdleEvent: An idle event
397@li wxInitDialogEvent: A dialog initialisation event
398@li wxJoystickEvent: A joystick event
399@li wxMenuEvent: A menu event
400@li wxMouseEvent: A mouse event
401@li wxMoveEvent: A move event
402@li wxPaintEvent: A paint event
403@li wxQueryLayoutInfoEvent: Used to query layout information
404@li wxSetCursorEvent: Used for special cursor processing based on current mouse position
405@li wxSizeEvent: A size event
406@li wxScrollWinEvent: A scroll event sent by a scrolled window (not a scroll bar)
407@li wxSysColourChangedEvent: A system colour change event
408
409In some cases, it might be desired by the programmer to get a certain number
410of system events in a parent window, for example all key events sent to, but not
411used by, the native controls in a dialog. In this case, a special event handler
412will have to be written that will override ProcessEvent() in order to pass
413all events (or any selection of them) to the parent window.
414
415
409e6ce4 416@section overview_eventhandling_prog User Generated Events vs Programmatically Generated Events
dc28cdf8
FM
417
418While generically wxEvents can be generated both by user
419actions (e.g. resize of a wxWindow) and by calls to functions
420(e.g. wxWindow::SetSize), wxWidgets controls normally send wxCommandEvent-derived
421events only for the user-generated events. The only @b exceptions to this rule are:
422
423@li wxNotebook::AddPage: No event-free alternatives
424@li wxNotebook::AdvanceSelection: No event-free alternatives
425@li wxNotebook::DeletePage: No event-free alternatives
426@li wxNotebook::SetSelection: Use wxNotebook::ChangeSelection instead, as
427 wxNotebook::SetSelection is deprecated
428@li wxTreeCtrl::Delete: No event-free alternatives
429@li wxTreeCtrl::DeleteAllItems: No event-free alternatives
430@li wxTreeCtrl::EditLabel: No event-free alternatives
431@li All wxTextCtrl methods
432
433wxTextCtrl::ChangeValue can be used instead of wxTextCtrl::SetValue but the other
434functions, such as wxTextCtrl::Replace or wxTextCtrl::WriteText don't have event-free
435equivalents.
436
437
438
409e6ce4 439@section overview_eventhandling_pluggable Pluggable Event Handlers
dc28cdf8
FM
440
441In fact, you don't have to derive a new class from a window class
442if you don't want to. You can derive a new class from wxEvtHandler instead,
443defining the appropriate event table, and then call wxWindow::SetEventHandler
444(or, preferably, wxWindow::PushEventHandler) to make this
445event handler the object that responds to events. This way, you can avoid
446a lot of class derivation, and use instances of the same event handler class (but different
447objects as the same event handler object shouldn't be used more than once) to
448handle events from instances of different widget classes.
449
450If you ever have to call a window's event handler
451manually, use the GetEventHandler function to retrieve the window's event handler and use that
452to call the member function. By default, GetEventHandler returns a pointer to the window itself
453unless an application has redirected event handling using SetEventHandler or PushEventHandler.
454
455One use of PushEventHandler is to temporarily or permanently change the
456behaviour of the GUI. For example, you might want to invoke a dialog editor
457in your application that changes aspects of dialog boxes. You can
458grab all the input for an existing dialog box, and edit it 'in situ',
459before restoring its behaviour to normal. So even if the application
460has derived new classes to customize behaviour, your utility can indulge
461in a spot of body-snatching. It could be a useful technique for on-line
462tutorials, too, where you take a user through a serious of steps and
463don't want them to diverge from the lesson. Here, you can examine the events
464coming from buttons and windows, and if acceptable, pass them through to
465the original event handler. Use PushEventHandler/PopEventHandler
466to form a chain of event handlers, where each handler processes a different
467range of events independently from the other handlers.
468
469
470
409e6ce4 471@section overview_eventhandling_winid Window Identifiers
dc28cdf8
FM
472
473Window identifiers are integers, and are used to
474uniquely determine window identity in the event system (though you can use it
475for other purposes). In fact, identifiers do not need to be unique
476across your entire application just so long as they are unique within a
477particular context you're interested in, such as a frame and its children. You
478may use the @c wxID_OK identifier, for example, on any number of dialogs so
479long as you don't have several within the same dialog.
480
481If you pass @c wxID_ANY to a window constructor, an identifier will be
482generated for you automatically by wxWidgets. This is useful when you don't
483care about the exact identifier either because you're not going to process the
484events from the control being created at all or because you process the events
485from all controls in one place (in which case you should specify @c wxID_ANY
486in the event table or wxEvtHandler::Connect call
487as well. The automatically generated identifiers are always negative and so
488will never conflict with the user-specified identifiers which must be always
489positive.
490
491See @ref page_stdevtid for the list of standard identifiers availabel.
492You can use wxID_HIGHEST to determine the number above which it is safe to
493define your own identifiers. Or, you can use identifiers below wxID_LOWEST.
494Finally, you can allocate identifiers dynamically using wxNewId() function to.
495If you use wxNewId() consistently in your application, you can be sure that
496the your identifiers don't conflict accidentally.
497
498
409e6ce4 499@section overview_eventhandling_custom Custom Event Summary
dc28cdf8
FM
500
501@subsection overview_eventhandling_custom_general General approach
502
503Since version 2.2.x of wxWidgets, each event type is identified by ID which
504is given to the event type @e at runtime which makes it possible to add
505new event types to the library or application without risking ID clashes
506(two different event types mistakingly getting the same event ID). This
507event type ID is stored in a struct of type @b const wxEventType.
508
509In order to define a new event type, there are principally two choices.
510One is to define a entirely new event class (typically deriving from
511wxEvent or wxCommandEvent.
512
513The other is to use the existing event classes and give them an new event
514type. You'll have to define and declare a new event type using either way,
515and this is done using the following macros:
516
517@code
518// in the header of the source file
519BEGIN_DECLARE_EVENT_TYPES()
520DECLARE_EVENT_TYPE(name, value)
521END_DECLARE_EVENT_TYPES()
522
523// in the implementation
524DEFINE_EVENT_TYPE(name)
525@endcode
526
527You can ignore the @e value parameter of the DECLARE_EVENT_TYPE macro
528since it is used only for backwards compatibility with wxWidgets 2.0.x based
529applications where you have to give the event type ID an explicit value.
530See also the @ref page_samples_event for an example of code
531defining and working with the custom event types.
532
533
409e6ce4 534@subsection overview_eventhandling_custom_existing Using Existing Event Classes
dc28cdf8
FM
535
536If you just want to use a wxCommandEvent with
537a new event type, you can then use one of the generic event table macros
538listed below, without having to define a new macro yourself. This also
539has the advantage that you won't have to define a new wxEvent::Clone()
540method for posting events between threads etc. This could look like this
541in your code:
542
543@code
544DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1)
545DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)
546
547// user code intercepting the event
548
549BEGIN_EVENT_TABLE(MyFrame, wxFrame)
550EVT_MENU (wxID_EXIT, MyFrame::OnExit)
551// ....
552EVT_COMMAND (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
553END_EVENT_TABLE()
554
555void MyFrame::OnMyEvent( wxCommandEvent )
556{
557 // do something
558 wxString text = event.GetText();
559}
36c9828f
FM
560
561
dc28cdf8 562// user code sending the event
36c9828f 563
dc28cdf8
FM
564void MyWindow::SendEvent()
565{
566 wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
567 event.SetEventObject( this );
568 // Give it some contents
569 event.SetText( wxT("Hallo") );
570 // Send it
571 GetEventHandler()->ProcessEvent( event );
572}
573@endcode
36c9828f
FM
574
575
409e6ce4 576@subsection overview_eventhandling_custom_generic Generic Event Table Macros
3b88355f 577
dc28cdf8
FM
578@beginTable
579@row2col{EVT_CUSTOM(event\, id\, func),
580 Allows you to add a custom event table
581 entry by specifying the event identifier (such as wxEVT_SIZE),
582 the window identifier, and a member function to call.}
583@row2col{EVT_CUSTOM_RANGE(event\, id1\, id2\, func),
584 The same as EVT_CUSTOM, but responds to a range of window identifiers.}
585@row2col{EVT_COMMAND(id\, event\, func),
586 The same as EVT_CUSTOM, but expects a member function with a
587 wxCommandEvent argument.}
588@row2col{EVT_COMMAND_RANGE(id1\, id2\, event\, func),
589 The same as EVT_CUSTOM_RANGE, but
590 expects a member function with a wxCommandEvent argument.}
591@row2col{EVT_NOTIFY(event\, id\, func),
592 The same as EVT_CUSTOM, but
593 expects a member function with a wxNotifyEvent argument.}
594@row2col{EVT_NOTIFY_RANGE(event\, id1\, id2\, func),
595 The same as EVT_CUSTOM_RANGE, but
596 expects a member function with a wxNotifyEvent argument.}
597@endTable
3b88355f
FM
598
599
409e6ce4 600@subsection overview_eventhandling_custom_ownclass Defining Your Own Event Class
36c9828f 601
dc28cdf8
FM
602Under certain circumstances, it will be required to define your own event
603class e.g. for sending more complex data from one place to another. Apart
604from defining your event class, you will also need to define your own
605event table macro (which is quite long). Watch out to put in enough
606casts to the inherited event function. Here is an example:
36c9828f 607
dc28cdf8
FM
608@code
609// code defining event
36c9828f 610
dc28cdf8
FM
611class wxPlotEvent: public wxNotifyEvent
612{
613public:
614 wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );
36c9828f 615
dc28cdf8
FM
616 // accessors
617 wxPlotCurve *GetCurve()
618 { return m_curve; }
36c9828f 619
dc28cdf8
FM
620 // required for sending with wxPostEvent()
621 virtual wxEvent *Clone() const;
36c9828f 622
dc28cdf8
FM
623private:
624 wxPlotCurve *m_curve;
625};
36c9828f 626
dc28cdf8 627DECLARE_EVENT_TYPE( wxEVT_PLOT_ACTION, -1 )
36c9828f 628
dc28cdf8 629typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);
36c9828f 630
dc28cdf8
FM
631#define EVT_PLOT(id, fn) \
632 DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, \
633 (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
634 wxStaticCastEvent( wxPlotEventFunction, &fn ), (wxObject *) NULL ),
36c9828f
FM
635
636
dc28cdf8 637// code implementing the event type and the event class
36c9828f 638
dc28cdf8 639DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )
36c9828f 640
dc28cdf8 641wxPlotEvent::wxPlotEvent( ...
36c9828f
FM
642
643
dc28cdf8 644// user code intercepting the event
36c9828f 645
dc28cdf8
FM
646BEGIN_EVENT_TABLE(MyFrame, wxFrame)
647EVT_PLOT (ID_MY_WINDOW, MyFrame::OnPlot)
648END_EVENT_TABLE()
36c9828f 649
dc28cdf8
FM
650void MyFrame::OnPlot( wxPlotEvent &event )
651{
652 wxPlotCurve *curve = event.GetCurve();
653}
36c9828f
FM
654
655
dc28cdf8 656// user code sending the event
36c9828f 657
dc28cdf8
FM
658void MyWindow::SendEvent()
659{
660 wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
661 event.SetEventObject( this );
662 event.SetCurve( m_curve );
663 GetEventHandler()->ProcessEvent( event );
664}
665@endcode
36c9828f 666
86faa458 667
409e6ce4 668@section overview_eventhandling_macros Event Handling Summary
86faa458 669
dc28cdf8 670For the full list of event classes, please see the
409e6ce4 671@ref group_class_events "event classes group page".
86faa458 672
5c02d584
FM
673
674@todo for all controls state clearly when calling a member function results in an
675 event being generated and when it doesn't (possibly updating also the
676 'Events generated by the user vs programmatically generated events' paragraph
677 of the 'Event handling overview' with the list of the functions which break
678 that rule).
679
3b88355f 680*/
36c9828f 681