/**
Returns a copy of the event.
- Any event that is posted to the wxWidgets event system for later action (via
- wxEvtHandler::AddPendingEvent or wxPostEvent()) must implement this method.
+ Any event that is posted to the wxWidgets event system for later action
+ (via wxEvtHandler::AddPendingEvent or wxPostEvent()) must implement
+ this method.
All wxWidgets events fully implement this method, but any derived events
implemented by the user should also implement this method just in case they
virtual ~wxEvtHandler();
/**
- This function posts an event to be processed later.
+ Queue event for a later processing.
+
+ This method is similar to ProcessEvent() but while the latter is
+ synchronous, i.e. the event is processed immediately, before the
+ function returns, this one is asynchronous and returns immediately
+ while the event will be processed at some later time (usually during
+ the next event loop iteration).
+
+ Another important difference is that this method takes ownership of the
+ @a event parameter, i.e. it will delete it itself. This implies that
+ the event should be allocated on the heap and that the pointer can't be
+ used any more after the function returns (as it can be deleted at any
+ moment).
+
+ QueueEvent() can be used for inter-thread communication from the worker
+ threads to the main thread, it is safe in the sense that it uses
+ locking internally and avoids the problem mentioned in AddPendingEvent()
+ documentation by ensuring that the @a event object is not used by the
+ calling thread any more. Care should still be taken to avoid that some
+ fields of this object are used by it, notably any wxString members of
+ the event object must not be shallow copies of another wxString object
+ as this would result in them still using the same string buffer behind
+ the scenes. For example
+ @code
+ void FunctionInAWorkerThread(const wxString& str)
+ {
+ wxCommandEvent* evt = new wxCommandEvent;
+
+ // NOT evt->SetString(str) as this would be a shallow copy
+ evt->SetString(str.c_str()); // make a deep copy
+
+ wxTheApp->QueueEvent( evt );
+ }
+ @endcode
- The difference between sending an event (using the ProcessEvent
- method) and posting it is that in the first case the event is
- processed before the function returns, while in the second case,
- the function returns immediately and the event will be processed
- sometime later (usually during the next event loop iteration).
+ Finally notice that this method automatically wakes up the event loop
+ if it is currently idle by calling ::wxWakeUpIdle() so there is no need
+ to do it manually when using it.
- A copy of event is made by the function, so the original can be deleted as
- soon as function returns (it is common that the original is created on the
- stack). This requires that the wxEvent::Clone method be implemented by event
- so that it can be duplicated and stored until it gets processed.
+ @since 2.9.0
+
+ @param event
+ A heap-allocated event to be queued, QueueEvent() takes ownership
+ of it. This parameter shouldn't be @c NULL.
+ */
+ virtual void QueueEvent(wxEvent *event);
+
+ /**
+ Post an event to be processed later.
- This is also the method to call for inter-thread communication - it will post
- events safely between different threads which means that this method is
- thread-safe by using critical sections where needed. In a multi-threaded program,
- you often need to inform the main GUI thread about the status of other working
- threads and such notification should be done using this method.
+ This function is similar to QueueEvent() but can't be used to post
+ events from worker threads for the event objects with wxString fields
+ (i.e. in practice most of them) because of an unsafe use of the same
+ wxString object which happens because the wxString field in the
+ original @a event object and its copy made internally by this function
+ share the same string buffer internally. Use QueueEvent() to avoid
+ this.
- This method automatically wakes up idle handling if the underlying window
- system is currently idle and thus would not send any idle events.
- (Waking up idle handling is done calling ::wxWakeUpIdle.)
+ A copy of event is made by the function, so the original can be deleted
+ as soon as function returns (it is common that the original is created
+ on the stack). This requires that the wxEvent::Clone() method be
+ implemented by event so that it can be duplicated and stored until it
+ gets processed.
@param event
- Event to add to process queue.
+ Event to add to the pending events queue.
*/
virtual void AddPendingEvent(const wxEvent& event);
@param event
Event to process.
- @returns @true if a suitable event handler function was found and
+ @return @true if a suitable event handler function was found and
executed, and the function did not call wxEvent::Skip.
@see SearchEventTable()
@param event
Event to process.
- @returns @true if the event was processed, @false if no handler was found
+ @return @true if the event was processed, @false if no handler was found
or an exception was thrown.
@see wxWindow::HandleWindowEvent
@param event
Event to be matched against an event table entry.
- @returns @true if a suitable event handler function was found and
+ @return @true if a suitable event handler function was found and
executed, and the function did not call wxEvent::Skip.
@remarks This function looks through the object's event table and tries
other platforms (you can still distinguish simple clicks from double-clicks as
they generate different kinds of events however).
- @wxsince{2.9.0}
+ @since 2.9.0
*/
int GetClickCount() const;
This allows the wxWindow::Close function to return @true or @false depending
on whether the close instruction was honoured or not.
+ The EVT_END_SESSION event is slightly different as it is sent by the system
+ when the user session is ending (e.g. because of log out or shutdown) and
+ so all windows are being forcefully closed. At least under MSW, after the
+ handler for this event is executed the program is simply killed by the
+ system. Because of this, the default handler for this event provided by
+ wxWidgets calls all the usual cleanup code (including wxApp::OnExit()) so
+ that it could still be executed and exit()s the process itself, without
+ waiting for being killed. If this behaviour is for some reason undesirable,
+ make sure that you define a handler for this event in your wxApp-derived
+ class and do not call @c event.Skip() in it (but be aware that the system
+ will still kill your application).
+
@beginEventTable{wxCloseEvent}
@event{EVT_CLOSE(func)}
Process a close event, supplying the member function.
This event applies to wxFrame and wxDialog classes.
@event{EVT_QUERY_END_SESSION(func)}
Process a query end session event, supplying the member function.
- This event applies to wxApp only.
+ This event can be handled in wxApp-derived class only.
@event{EVT_END_SESSION(func)}
Process an end session event, supplying the member function.
- This event applies to wxApp only.
+ This event can be handled in wxApp-derived class only.
@endEventTable
@library{wxcore}
Otherwise, it dispatches @a event immediately using
wxEvtHandler::ProcessEvent(). See the respective documentation for details
- (and caveats).
+ (and caveats). Because of limitation of wxEvtHandler::AddPendingEvent()
+ this function is not thread-safe for event objects having wxString fields,
+ use wxQueueEvent() instead.
@header{wx/event.h}
*/
-void wxPostEvent(wxEvtHandler* dest, wxEvent& event);
+void wxPostEvent(wxEvtHandler* dest, const wxEvent& event);
+
+/**
+ Queue an event for processing on the given object.
+
+ This is a wrapper around wxEvtHandler::QueueEvent(), see its documentation
+ for more details.
+
+ @header{wx/event.h}
+
+ @param dest
+ The object to queue the event on, can't be @c NULL.
+ @param event
+ The heap-allocated and non-@c NULL event to queue, the function takes
+ ownership of it.
+ */
+void wxQueueEvent(wxEvtHandler* dest, wxEvent *event);
//@}