X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5fc0243835d4f6cbe586d85e3a6baa3c9c95fc7c..afbe906abdf9aa69a56571b8b20b095351dd8f34:/docs/latex/wx/tevent.tex?ds=sidebyside diff --git a/docs/latex/wx/tevent.tex b/docs/latex/wx/tevent.tex index a69b2f5350..ed4760d0fc 100644 --- a/docs/latex/wx/tevent.tex +++ b/docs/latex/wx/tevent.tex @@ -12,7 +12,7 @@ From wxWindows 2.0, {\it event tables} are used instead, with a few exceptions. An event table is placed in an implementation file to tell wxWindows how to map events to member functions. These member functions are not virtual functions, but -they all similar in form: they take a single wxEvent-derived argument, and have a void return +they are all similar in form: they take a single wxEvent-derived argument, and have a void return type. Here's an example of an event table. @@ -70,19 +70,24 @@ protected: \subsection{How events are processed}\label{eventprocessing} -When an event is received from the windowing system, wxWindows calls \helpref{wxEvtHandler::ProcessEvent}{wxevthandlerprocessevent} on -the first event handler object belonging to the window generating the event. +When an event is received from the windowing system, wxWindows calls +\helpref{wxEvtHandler::ProcessEvent}{wxevthandlerprocessevent} on the first +event handler object belonging to the window generating the event. It may be noted that wxWindows' event processing system implements something very close to virtual methods in normal C++, i.e. it is possible to alter the behaviour of a class by overriding its event handling functions. In many cases this works even for changing the behaviour of native controls. -E.g. it is possible to filter out a number of key events sent by the +For example it is possible to filter out a number of key events sent by the system to a native text control by overriding wxTextCtrl and defining a -handler for key events using EVT_KEY_DOWN. This would in-deed prevent +handler for key events using EVT\_KEY\_DOWN. This would indeed prevent any key events from being sent to the native control - which might not be what is desired. In this case the event handler function has to call Skip() -so as to indicate that it did NOT handle the event at all. +so as to indicate that the search for the event handler should continue. + +To summarize, instead of explicitly calling the base class version as you +would have done with C++ virtual functions (i.e. {\it wxTextCtrl::OnChar()}), +you should instead call \helpref{Skip}{wxeventskip}. In practice, this would look like this if the derived text control only accepts 'a' to 'z' and 'A' to 'Z': @@ -96,18 +101,17 @@ void MyTextCtrl::OnChar(wxKeyEvent& event) // key code is within legal range. we call event.Skip() so the // event can be processed either in the base wxWindows class // or the native control. - - event.Skip(); + + event.Skip(); } else { // illegal key hit. we don't call event.Skip() so the // event is not processed anywhere else. - + wxBell(); } } - \end{verbatim} }% @@ -129,9 +133,43 @@ recursively applied to the parent window's event handler. If this returns TRUE, \item Finally, {\bf ProcessEvent} is called on the wxApp object. \end{enumerate} +{\bf Pay close attention to Step 5.} People often overlook or get +confused by this powerful feature of the wxWindows event processing +system. To put it a different way, events derived either directly or +indirectly from wxCommandEvent will travel up the containment +hierarchy from child to parent until an event handler is found that +doesn't call event.Skip(). Events not derived from wxCommandEvent are +sent only to the window they occurred in and then stop. + +Finally, there is another additional complication (which, in fact, simplifies +life of wxWindows programmers significantly): when propagating the command +events upwards to the parent window, the event propagation stops when it +reaches the parent dialog, if any. This means that you don't risk to get +unexpected events from the dialog controls (which might be left unprocessed by +the dialog itself because it doesn't care about them) when a modal dialog is +popped up. The events do propagate beyond the frames, however. The rationale +for this choice is that there are only a few frames in a typical application +and their parent-child relation are well understood by the programmer while it +may be very difficult, if not impossible, to track down all the dialogs which +may be popped up in a complex program (remember that some are created +automatically by wxWindows). If you need to specify a different behaviour for +some reason, you can use +\helpref{SetExtraStyle(wxWS\_EX\_BLOCK\_EVENTS)}{wxwindowsetextrastyle} +explicitly to prevent the events from being propagated beyond the given window +or unset this flag for the dialogs which have it on by default. + +Typically events that deal with a window as a window (size, motion, +paint, mouse, keyboard, etc.) are sent only to the window. Events +that have a higher level of meaning and/or are generated by the window +itself, (button click, menu select, tree expand, etc.) are command +events and are sent up to the parent to see if it is interested in the +event. + Note that your application may wish to override ProcessEvent to redirect processing of events. This is done in the document/view framework, for example, to allow event handlers -to be defined in the document or view. +to be defined in the document or view. To test for command events (which will probably +be the only events you wish to redirect), you may use wxEvent::IsCommandEvent for +efficiency, instead of using the slower run-time type system. As mentioned above, only command events are recursively applied to the parents event handler. As this quite often causes confusion for users, here is a list of system @@ -153,15 +191,33 @@ events which will NOT get sent to the parent's event handler: \twocolitem{\helpref{wxPaintEvent}{wxpaintevent}}{A paint event} \twocolitem{\helpref{wxQueryLayoutInfoEvent}{wxquerylayoutinfoevent}}{Used to query layout information} \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 -of system events in a parent window, e.g. all key events sent to, but not +of system events in a parent window, for example all key events sent to, but not 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. See next section. +all events (or any selection of them) to the parent window. + +% VZ: it doesn't work like this, but just in case we ever reenable this +% behaviour, I leave it here +% +% \subsection{Redirection of command events to the window with the focus} +% +% The usual upward search through the window hierarchy for command event +% handlers does not always meet an application's requirements. Say you have two +% wxTextCtrl windows in a frame, plus a toolbar with Cut, Copy and Paste +% buttons. To avoid the need to define event handlers in the frame +% and redirect them explicitly to the window with the focus, command events +% are sent to the window with the focus first, for +% menu and toolbar command and UI update events only. This means that +% each window can handle its own commands and UI updates independently. In +% fact wxTextCtrl can handle Cut, Copy, Paste, Undo and Redo commands and UI update +% requests, so no extra coding is required to support them in your menus and +% toolbars. \subsection{Pluggable event handlers} @@ -191,31 +247,87 @@ the original event handler. Use PushEventHandler/PopEventHandler to form a chain of event handlers, where each handler processes a different range of events independently from the other handlers. -\subsection{Event macros summary}\label{eventmacros} +\subsection{Window identifiers}\label{windowids} -\wxheading{Specifying an event table} +\index{identifiers}\index{wxID}Window identifiers are integers, and are used to uniquely determine window identity in the +event system (though you can use it for other purposes). In fact, identifiers do not need +to be unique across your entire application just so long as they are unique within a particular context you're interested +in, such as a frame and its children. You may use the wxID\_OK identifier, for example, on +any number of dialogs so long as you don't have several within the same dialog. -\twocolwidtha{8cm}% -\begin{twocollist}\itemsep=0pt -\twocolitem{\windowstyle{EVT\_CUSTOM(eventId, 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(eventId, id1, id2, func)}}{The same as EVT\_CUSTOM, -but responds to a range of window identifiers.} -\end{twocollist} +If you pass -1 to a window constructor, an identifier will be generated for you, but beware: +if things don't respond in the way they should, it could be because of an id conflict. It is safer +to supply window ids at all times. Automatic generation of identifiers starts at 1 so may well conflict +with your own identifiers. + +The following standard identifiers are supplied. You can use wxID\_HIGHEST to determine the +number above which it is safe to define your own identifiers. Or, you can use identifiers below +wxID\_LOWEST. + +\begin{verbatim} +#define wxID_LOWEST 4999 + +#define wxID_OPEN 5000 +#define wxID_CLOSE 5001 +#define wxID_NEW 5002 +#define wxID_SAVE 5003 +#define wxID_SAVEAS 5004 +#define wxID_REVERT 5005 +#define wxID_EXIT 5006 +#define wxID_UNDO 5007 +#define wxID_REDO 5008 +#define wxID_HELP 5009 +#define wxID_PRINT 5010 +#define wxID_PRINT_SETUP 5011 +#define wxID_PREVIEW 5012 +#define wxID_ABOUT 5013 +#define wxID_HELP_CONTENTS 5014 +#define wxID_HELP_COMMANDS 5015 +#define wxID_HELP_PROCEDURES 5016 +#define wxID_HELP_CONTEXT 5017 + +#define wxID_CUT 5030 +#define wxID_COPY 5031 +#define wxID_PASTE 5032 +#define wxID_CLEAR 5033 +#define wxID_FIND 5034 +#define wxID_DUPLICATE 5035 +#define wxID_SELECTALL 5036 + +#define wxID_FILE1 5050 +#define wxID_FILE2 5051 +#define wxID_FILE3 5052 +#define wxID_FILE4 5053 +#define wxID_FILE5 5054 +#define wxID_FILE6 5055 +#define wxID_FILE7 5056 +#define wxID_FILE8 5057 +#define wxID_FILE9 5058 + +#define wxID_OK 5100 +#define wxID_CANCEL 5101 +#define wxID_APPLY 5102 +#define wxID_YES 5103 +#define wxID_NO 5104 +#define wxID_STATIC 5105 + +#define wxID_HIGHEST 5999 +\end{verbatim} + +\subsection{Event macros summary}\label{eventmacros} \wxheading{Generic event table macros} \twocolwidtha{8cm}% \begin{twocollist}\itemsep=0pt -\twocolitem{\windowstyle{EVT\_CUSTOM(eventId, id, func)}}{Allows you to add a custom event table +\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(eventId, id1, id2, func)}}{The same as EVT\_CUSTOM, +\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(eventId, id, func)}}{The same as EVT\_CUSTOM, but +\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(eventId, id1, id2, func)}}{The same as EVT\_CUSTOM\_RANGE, but +\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} @@ -234,9 +346,9 @@ called via \helpref{wxWindow::Close}{wxwindowclose}.} \twocolitem{\helpref{wxDropFilesEvent}{wxdropfilesevent}}{The EVT\_DROP\_FILES macros handles file drop events.} \twocolitem{\helpref{wxEraseEvent}{wxeraseevent}}{The EVT\_ERASE\_BACKGROUND macro is used to handle window erase requests.} -\twocolitem{\helpref{wxFocusEvent}{wxfocusevent}}{The EVT\_SET\_FOCUS and EVT\_KILL\_FOCUS macros are used to handle keybaord focus events.} -\twocolitem{\helpref{wxKeyEvent}{wxkeyevent}}{EVT\_CHAR and EVT\_CHAR\_HOOK macros handle keyboard -input for any window.} +\twocolitem{\helpref{wxFocusEvent}{wxfocusevent}}{The EVT\_SET\_FOCUS and EVT\_KILL\_FOCUS macros are used to handle keyboard focus events.} +\twocolitem{\helpref{wxKeyEvent}{wxkeyevent}}{EVT\_CHAR, EVT\_KEY\_DOWN and +EVT\_KEY\_UP macros handle keyboard input for any window.} \twocolitem{\helpref{wxIdleEvent}{wxidleevent}}{The EVT\_IDLE macro handle application idle events (to process background tasks, for example).} \twocolitem{\helpref{wxInitDialogEvent}{wxinitdialogevent}}{The EVT\_INIT\_DIALOG macro is used @@ -246,15 +358,17 @@ to handle dialog initialisation.} \twocolitem{\helpref{wxMouseEvent}{wxmouseevent}}{Mouse event macros can handle either individual mouse events or all mouse events.} \twocolitem{\helpref{wxMoveEvent}{wxmoveevent}}{The EVT\_MOVE macro is used to handle a window move.} -\twocolitem{\helpref{wxUpdateUIEvent}{wxupdateuievent}}{The EVT\_UPDATE\_UI macro is used to handle user interface -update pseudo-events, which are generated to give the application the chance to update the visual state of menus, -toolbars and controls.} \twocolitem{\helpref{wxPaintEvent}{wxpaintevent}}{The EVT\_PAINT macro is used to handle window paint requests.} -\twocolitem{\helpref{wxScrollEvent}{wxscrollevent}}{These macros are used to handle scroll events from -windows, \helpref{wxScrollBar}{wxscrollbar}, and \helpref{wxSpinButton}{wxspinbutton}.} +\twocolitem{\helpref{wxScrollEvent}{wxscrollevent}}{These macros are used to handle scroll events from +\helpref{wxScrollBar}{wxscrollbar}, \helpref{wxSlider}{wxslider},and \helpref{wxSpinButton}{wxspinbutton}.} \twocolitem{\helpref{wxSizeEvent}{wxsizeevent}}{The EVT\_SIZE macro is used to handle a window resize.} +\twocolitem{\helpref{wxSplitterEvent}{wxsplitterevent}}{The EVT\_SPLITTER\_SASH\_POS\_CHANGED, EVT\_SPLITTER\_UNSPLIT +and EVT\_SPLITTER\_DOUBLECLICKED macros are used to handle the various splitter window events.} \twocolitem{\helpref{wxSysColourChangedEvent}{wxsyscolourchangedevent}}{The EVT\_SYS\_COLOUR\_CHANGED macro is used to handle events informing the application that the user has changed the system colours (Windows only).} \twocolitem{\helpref{wxTreeEvent}{wxtreeevent}}{These macros handle \helpref{wxTreeCtrl}{wxtreectrl} events.} +\twocolitem{\helpref{wxUpdateUIEvent}{wxupdateuievent}}{The EVT\_UPDATE\_UI macro is used to handle user interface +update pseudo-events, which are generated to give the application the chance to update the visual state of menus, +toolbars and controls.} \end{twocollist}