1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/event.cpp 
   3 // Purpose:     Event classes 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  28 #include "wx/evtloop.h" 
  35     #include "wx/stopwatch.h" 
  36     #include "wx/module.h" 
  39         #include "wx/window.h" 
  40         #include "wx/control.h" 
  42         #include "wx/spinbutt.h" 
  43         #include "wx/textctrl.h" 
  44         #include "wx/validate.h" 
  48 #include "wx/thread.h" 
  51     #include "wx/scopedptr.h" 
  53     wxDECLARE_SCOPED_PTR(wxEvent
, wxEventPtr
) 
  54     wxDEFINE_SCOPED_PTR(wxEvent
, wxEventPtr
) 
  57 // ---------------------------------------------------------------------------- 
  59 // ---------------------------------------------------------------------------- 
  62     IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler
, wxObject
) 
  63     IMPLEMENT_ABSTRACT_CLASS(wxEvent
, wxObject
) 
  64     IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent
, wxEvent
) 
  68     IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent
, wxEvent
) 
  69     IMPLEMENT_DYNAMIC_CLASS(wxThreadEvent
, wxCommandEvent
) 
  70     IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent
, wxCommandEvent
) 
  71     IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent
, wxCommandEvent
) 
  72     IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent
, wxEvent
) 
  73     IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent
, wxEvent
) 
  74     IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent
, wxEvent
) 
  75     IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent
, wxEvent
) 
  76     IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent
, wxEvent
) 
  77     IMPLEMENT_DYNAMIC_CLASS(wxNcPaintEvent
, wxEvent
) 
  78     IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent
, wxEvent
) 
  79     IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent
, wxEvent
) 
  80     IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent
, wxEvent
) 
  81     IMPLEMENT_DYNAMIC_CLASS(wxChildFocusEvent
, wxCommandEvent
) 
  82     IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent
, wxEvent
) 
  83     IMPLEMENT_DYNAMIC_CLASS(wxShowEvent
, wxEvent
) 
  84     IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent
, wxEvent
) 
  85     IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent
, wxEvent
) 
  86     IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent
, wxEvent
) 
  87     IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent
, wxEvent
) 
  88     IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent
, wxEvent
) 
  89     IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent
, wxEvent
) 
  90     IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent
, wxEvent
) 
  91     IMPLEMENT_DYNAMIC_CLASS(wxSetCursorEvent
, wxEvent
) 
  92     IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent
, wxEvent
) 
  93     IMPLEMENT_DYNAMIC_CLASS(wxDisplayChangedEvent
, wxEvent
) 
  94     IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent
, wxCommandEvent
) 
  95     IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent
, wxEvent
) 
  96     IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent
, wxEvent
) 
  97     IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent
, wxEvent
) 
  98     IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent
, wxEvent
) 
  99     IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent
, wxEvent
) 
 100     IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent
, wxCommandEvent
) 
 101     IMPLEMENT_DYNAMIC_CLASS(wxContextMenuEvent
, wxCommandEvent
) 
 102     IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureChangedEvent
, wxEvent
) 
 103     IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureLostEvent
, wxEvent
) 
 104     IMPLEMENT_DYNAMIC_CLASS(wxClipboardTextEvent
, wxCommandEvent
) 
 109 const wxEventTable 
*wxEvtHandler::GetEventTable() const 
 110     { return &wxEvtHandler::sm_eventTable
; } 
 112 const wxEventTable 
wxEvtHandler::sm_eventTable 
= 
 113     { (const wxEventTable 
*)NULL
, &wxEvtHandler::sm_eventTableEntries
[0] }; 
 115 wxEventHashTable 
&wxEvtHandler::GetEventHashTable() const 
 116     { return wxEvtHandler::sm_eventHashTable
; } 
 118 wxEventHashTable 
wxEvtHandler::sm_eventHashTable(wxEvtHandler::sm_eventTable
); 
 120 const wxEventTableEntry 
wxEvtHandler::sm_eventTableEntries
[] = 
 121     { DECLARE_EVENT_TABLE_TERMINATOR() }; 
 124 // wxUSE_MEMORY_TRACING considers memory freed from the static objects dtors 
 125 // leaked, so we need to manually clean up all event tables before checking for 
 126 // the memory leaks when using it, however this breaks re-initializing the 
 127 // library (i.e. repeated calls to wxInitialize/wxUninitialize) because the 
 128 // event tables won't be rebuilt the next time, so disable this by default 
 129 #if wxUSE_MEMORY_TRACING 
 131 class wxEventTableEntryModule
: public wxModule
 
 134     wxEventTableEntryModule() { } 
 135     virtual bool OnInit() { return true; } 
 136     virtual void OnExit() { wxEventHashTable::ClearAll(); } 
 138     DECLARE_DYNAMIC_CLASS(wxEventTableEntryModule
) 
 141 IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule
, wxModule
) 
 143 #endif // wxUSE_MEMORY_TRACING 
 145 // ---------------------------------------------------------------------------- 
 147 // ---------------------------------------------------------------------------- 
 149 // common event types are defined here, other event types are defined by the 
 150 // components which use them 
 152 const wxEventType wxEVT_FIRST 
= 10000; 
 153 const wxEventType wxEVT_USER_FIRST 
= wxEVT_FIRST 
+ 2000; 
 155 DEFINE_EVENT_TYPE(wxEVT_NULL
) 
 156 wxDEFINE_EVENT( wxEVT_IDLE
, wxIdleEvent 
); 
 162 wxDEFINE_EVENT( wxEVT_COMMAND_BUTTON_CLICKED
, wxCommandEvent 
); 
 163 wxDEFINE_EVENT( wxEVT_COMMAND_CHECKBOX_CLICKED
, wxCommandEvent 
); 
 164 wxDEFINE_EVENT( wxEVT_COMMAND_CHOICE_SELECTED
, wxCommandEvent 
); 
 165 wxDEFINE_EVENT( wxEVT_COMMAND_LISTBOX_SELECTED
, wxCommandEvent 
); 
 166 wxDEFINE_EVENT( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, wxCommandEvent 
); 
 167 wxDEFINE_EVENT( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, wxCommandEvent 
); 
 168 wxDEFINE_EVENT( wxEVT_COMMAND_MENU_SELECTED
, wxCommandEvent 
); 
 169 wxDEFINE_EVENT( wxEVT_COMMAND_SLIDER_UPDATED
, wxCommandEvent 
); 
 170 wxDEFINE_EVENT( wxEVT_COMMAND_RADIOBOX_SELECTED
, wxCommandEvent 
); 
 171 wxDEFINE_EVENT( wxEVT_COMMAND_RADIOBUTTON_SELECTED
, wxCommandEvent 
); 
 172 wxDEFINE_EVENT( wxEVT_COMMAND_SCROLLBAR_UPDATED
, wxCommandEvent 
); 
 173 wxDEFINE_EVENT( wxEVT_COMMAND_VLBOX_SELECTED
, wxCommandEvent 
); 
 174 wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_SELECTED
, wxCommandEvent 
); 
 175 wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_RCLICKED
, wxCommandEvent 
); 
 176 wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_ENTER
, wxCommandEvent 
); 
 177 wxDEFINE_EVENT( wxEVT_COMMAND_SPINCTRL_UPDATED
, wxCommandEvent 
); 
 178 wxDEFINE_EVENT( wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED
, wxCommandEvent 
); 
 179 wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED
, wxCommandEvent 
); 
 180 wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_DROPDOWN
, wxCommandEvent
); 
 181 wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_CLOSEUP
, wxCommandEvent
); 
 184 wxDEFINE_EVENT( wxEVT_LEFT_DOWN
, wxMouseEvent 
); 
 185 wxDEFINE_EVENT( wxEVT_LEFT_UP
, wxMouseEvent 
); 
 186 wxDEFINE_EVENT( wxEVT_MIDDLE_DOWN
, wxMouseEvent 
); 
 187 wxDEFINE_EVENT( wxEVT_MIDDLE_UP
, wxMouseEvent 
); 
 188 wxDEFINE_EVENT( wxEVT_RIGHT_DOWN
, wxMouseEvent 
); 
 189 wxDEFINE_EVENT( wxEVT_RIGHT_UP
, wxMouseEvent 
); 
 190 wxDEFINE_EVENT( wxEVT_MOTION
, wxMouseEvent 
); 
 191 wxDEFINE_EVENT( wxEVT_ENTER_WINDOW
, wxMouseEvent 
); 
 192 wxDEFINE_EVENT( wxEVT_LEAVE_WINDOW
, wxMouseEvent 
); 
 193 wxDEFINE_EVENT( wxEVT_LEFT_DCLICK
, wxMouseEvent 
); 
 194 wxDEFINE_EVENT( wxEVT_MIDDLE_DCLICK
, wxMouseEvent 
); 
 195 wxDEFINE_EVENT( wxEVT_RIGHT_DCLICK
, wxMouseEvent 
); 
 196 wxDEFINE_EVENT( wxEVT_SET_FOCUS
, wxFocusEvent 
); 
 197 wxDEFINE_EVENT( wxEVT_KILL_FOCUS
, wxFocusEvent 
); 
 198 wxDEFINE_EVENT( wxEVT_CHILD_FOCUS
, wxChildFocusEvent 
); 
 199 wxDEFINE_EVENT( wxEVT_MOUSEWHEEL
, wxMouseEvent 
); 
 200 wxDEFINE_EVENT( wxEVT_AUX1_DOWN
, wxMouseEvent 
); 
 201 wxDEFINE_EVENT( wxEVT_AUX1_UP
, wxMouseEvent 
); 
 202 wxDEFINE_EVENT( wxEVT_AUX1_DCLICK
, wxMouseEvent 
); 
 203 wxDEFINE_EVENT( wxEVT_AUX2_DOWN
, wxMouseEvent 
); 
 204 wxDEFINE_EVENT( wxEVT_AUX2_UP
, wxMouseEvent 
); 
 205 wxDEFINE_EVENT( wxEVT_AUX2_DCLICK
, wxMouseEvent 
); 
 207 // Character input event type 
 208 wxDEFINE_EVENT( wxEVT_CHAR
, wxKeyEvent 
); 
 209 wxDEFINE_EVENT( wxEVT_CHAR_HOOK
, wxKeyEvent 
); 
 210 wxDEFINE_EVENT( wxEVT_NAVIGATION_KEY
, wxNavigationKeyEvent 
); 
 211 wxDEFINE_EVENT( wxEVT_KEY_DOWN
, wxKeyEvent 
); 
 212 wxDEFINE_EVENT( wxEVT_KEY_UP
, wxKeyEvent 
); 
 214 wxDEFINE_EVENT( wxEVT_HOTKEY
, wxKeyEvent 
); 
 218 wxDEFINE_EVENT( wxEVT_SET_CURSOR
, wxSetCursorEvent 
); 
 220 // wxScrollbar and wxSlider event identifiers 
 221 wxDEFINE_EVENT( wxEVT_SCROLL_TOP
, wxScrollEvent 
); 
 222 wxDEFINE_EVENT( wxEVT_SCROLL_BOTTOM
, wxScrollEvent 
); 
 223 wxDEFINE_EVENT( wxEVT_SCROLL_LINEUP
, wxScrollEvent 
); 
 224 wxDEFINE_EVENT( wxEVT_SCROLL_LINEDOWN
, wxScrollEvent 
); 
 225 wxDEFINE_EVENT( wxEVT_SCROLL_PAGEUP
, wxScrollEvent 
); 
 226 wxDEFINE_EVENT( wxEVT_SCROLL_PAGEDOWN
, wxScrollEvent 
); 
 227 wxDEFINE_EVENT( wxEVT_SCROLL_THUMBTRACK
, wxScrollEvent 
); 
 228 wxDEFINE_EVENT( wxEVT_SCROLL_THUMBRELEASE
, wxScrollEvent 
); 
 229 wxDEFINE_EVENT( wxEVT_SCROLL_CHANGED
, wxScrollEvent 
); 
 231 // Due to a bug in older wx versions, wxSpinEvents were being sent with type of 
 232 // wxEVT_SCROLL_LINEUP, wxEVT_SCROLL_LINEDOWN and wxEVT_SCROLL_THUMBTRACK. But 
 233 // with the type-safe events in place, these event types are associated with 
 234 // wxScrollEvent. To allow handling of spin events, new event types have been 
 235 // defined in spinbutt.h/spinnbuttcmn.cpp. To maintain backward compatibility 
 236 // the spin event types are being initialized with the scroll event types. 
 240 wxDEFINE_EVENT_ALIAS( wxEVT_SPIN_UP
,   wxSpinEvent
, wxEVT_SCROLL_LINEUP 
); 
 241 wxDEFINE_EVENT_ALIAS( wxEVT_SPIN_DOWN
, wxSpinEvent
, wxEVT_SCROLL_LINEDOWN 
); 
 242 wxDEFINE_EVENT_ALIAS( wxEVT_SPIN
,      wxSpinEvent
, wxEVT_SCROLL_THUMBTRACK 
); 
 244 #endif // wxUSE_SPINBTN 
 246 // Scroll events from wxWindow 
 247 wxDEFINE_EVENT( wxEVT_SCROLLWIN_TOP
, wxScrollWinEvent 
); 
 248 wxDEFINE_EVENT( wxEVT_SCROLLWIN_BOTTOM
, wxScrollWinEvent 
); 
 249 wxDEFINE_EVENT( wxEVT_SCROLLWIN_LINEUP
, wxScrollWinEvent 
); 
 250 wxDEFINE_EVENT( wxEVT_SCROLLWIN_LINEDOWN
, wxScrollWinEvent 
); 
 251 wxDEFINE_EVENT( wxEVT_SCROLLWIN_PAGEUP
, wxScrollWinEvent 
); 
 252 wxDEFINE_EVENT( wxEVT_SCROLLWIN_PAGEDOWN
, wxScrollWinEvent 
); 
 253 wxDEFINE_EVENT( wxEVT_SCROLLWIN_THUMBTRACK
, wxScrollWinEvent 
); 
 254 wxDEFINE_EVENT( wxEVT_SCROLLWIN_THUMBRELEASE
, wxScrollWinEvent 
); 
 257 wxDEFINE_EVENT( wxEVT_SIZE
, wxSizeEvent 
); 
 258 wxDEFINE_EVENT( wxEVT_SIZING
, wxSizeEvent 
); 
 259 wxDEFINE_EVENT( wxEVT_MOVE
, wxMoveEvent 
); 
 260 wxDEFINE_EVENT( wxEVT_MOVING
, wxMoveEvent 
); 
 261 wxDEFINE_EVENT( wxEVT_MOVE_START
, wxMoveEvent 
); 
 262 wxDEFINE_EVENT( wxEVT_MOVE_END
, wxMoveEvent 
); 
 263 wxDEFINE_EVENT( wxEVT_CLOSE_WINDOW
, wxCloseEvent 
); 
 264 wxDEFINE_EVENT( wxEVT_END_SESSION
, wxCloseEvent 
); 
 265 wxDEFINE_EVENT( wxEVT_QUERY_END_SESSION
, wxCloseEvent 
); 
 266 wxDEFINE_EVENT( wxEVT_HIBERNATE
, wxActivateEvent 
); 
 267 wxDEFINE_EVENT( wxEVT_ACTIVATE_APP
, wxActivateEvent 
); 
 268 wxDEFINE_EVENT( wxEVT_ACTIVATE
, wxActivateEvent 
); 
 269 wxDEFINE_EVENT( wxEVT_CREATE
, wxWindowCreateEvent 
); 
 270 wxDEFINE_EVENT( wxEVT_DESTROY
, wxWindowDestroyEvent 
); 
 271 wxDEFINE_EVENT( wxEVT_SHOW
, wxShowEvent 
); 
 272 wxDEFINE_EVENT( wxEVT_ICONIZE
, wxIconizeEvent 
); 
 273 wxDEFINE_EVENT( wxEVT_MAXIMIZE
, wxMaximizeEvent 
); 
 274 wxDEFINE_EVENT( wxEVT_MOUSE_CAPTURE_CHANGED
, wxMouseCaptureChangedEvent 
); 
 275 wxDEFINE_EVENT( wxEVT_MOUSE_CAPTURE_LOST
, wxMouseCaptureLostEvent 
); 
 276 wxDEFINE_EVENT( wxEVT_PAINT
, wxPaintEvent 
); 
 277 wxDEFINE_EVENT( wxEVT_ERASE_BACKGROUND
, wxEraseEvent 
); 
 278 wxDEFINE_EVENT( wxEVT_NC_PAINT
, wxNcPaintEvent 
); 
 279 wxDEFINE_EVENT( wxEVT_MENU_OPEN
, wxMenuEvent 
); 
 280 wxDEFINE_EVENT( wxEVT_MENU_CLOSE
, wxMenuEvent 
); 
 281 wxDEFINE_EVENT( wxEVT_MENU_HIGHLIGHT
, wxMenuEvent 
); 
 282 wxDEFINE_EVENT( wxEVT_CONTEXT_MENU
, wxContextMenuEvent 
); 
 283 wxDEFINE_EVENT( wxEVT_SYS_COLOUR_CHANGED
, wxSysColourChangedEvent 
); 
 284 wxDEFINE_EVENT( wxEVT_DISPLAY_CHANGED
, wxDisplayChangedEvent 
); 
 285 wxDEFINE_EVENT( wxEVT_QUERY_NEW_PALETTE
, wxQueryNewPaletteEvent 
); 
 286 wxDEFINE_EVENT( wxEVT_PALETTE_CHANGED
, wxPaletteChangedEvent 
); 
 287 wxDEFINE_EVENT( wxEVT_JOY_BUTTON_DOWN
, wxJoystickEvent 
); 
 288 wxDEFINE_EVENT( wxEVT_JOY_BUTTON_UP
, wxJoystickEvent 
); 
 289 wxDEFINE_EVENT( wxEVT_JOY_MOVE
, wxJoystickEvent 
); 
 290 wxDEFINE_EVENT( wxEVT_JOY_ZMOVE
, wxJoystickEvent 
); 
 291 wxDEFINE_EVENT( wxEVT_DROP_FILES
, wxDropFilesEvent 
); 
 292 wxDEFINE_EVENT( wxEVT_INIT_DIALOG
, wxInitDialogEvent 
); 
 293 wxDEFINE_EVENT( wxEVT_UPDATE_UI
, wxUpdateUIEvent 
); 
 296 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_COPY
, wxClipboardTextEvent 
); 
 297 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_CUT
, wxClipboardTextEvent 
); 
 298 wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_PASTE
, wxClipboardTextEvent 
); 
 300 // Generic command events 
 301 // Note: a click is a higher-level event than button down/up 
 302 wxDEFINE_EVENT( wxEVT_COMMAND_LEFT_CLICK
, wxCommandEvent 
); 
 303 wxDEFINE_EVENT( wxEVT_COMMAND_LEFT_DCLICK
, wxCommandEvent 
); 
 304 wxDEFINE_EVENT( wxEVT_COMMAND_RIGHT_CLICK
, wxCommandEvent 
); 
 305 wxDEFINE_EVENT( wxEVT_COMMAND_RIGHT_DCLICK
, wxCommandEvent 
); 
 306 wxDEFINE_EVENT( wxEVT_COMMAND_SET_FOCUS
, wxCommandEvent 
); 
 307 wxDEFINE_EVENT( wxEVT_COMMAND_KILL_FOCUS
, wxCommandEvent 
); 
 308 wxDEFINE_EVENT( wxEVT_COMMAND_ENTER
, wxCommandEvent 
); 
 311 wxDEFINE_EVENT( wxEVT_HELP
, wxHelpEvent 
); 
 312 wxDEFINE_EVENT( wxEVT_DETAILED_HELP
, wxHelpEvent 
); 
 315 wxDEFINE_EVENT( wxEVT_COMMAND_THREAD
, wxThreadEvent 
); 
 321 wxIdleMode 
wxIdleEvent::sm_idleMode 
= wxIDLE_PROCESS_ALL
; 
 323 // ============================================================================ 
 325 // ============================================================================ 
 327 // ---------------------------------------------------------------------------- 
 328 // event initialization 
 329 // ---------------------------------------------------------------------------- 
 334     static int s_lastUsedEventType 
= wxEVT_FIRST
; 
 336     return s_lastUsedEventType
++; 
 338 // ---------------------------------------------------------------------------- 
 340 // ---------------------------------------------------------------------------- 
 342 wxEventFunctor::~wxEventFunctor() 
 346 // ---------------------------------------------------------------------------- 
 348 // ---------------------------------------------------------------------------- 
 351  * General wxWidgets events, covering all interesting things that might happen 
 352  * (button clicking, resizing, setting text in widgets, etc.). 
 354  * For each completely new event type, derive a new event class. 
 358 wxEvent::wxEvent(int theId
, wxEventType commandType
) 
 360     m_eventType 
= commandType
; 
 361     m_eventObject 
= NULL
; 
 365     m_callbackUserData 
= NULL
; 
 366     m_isCommandEvent 
= false; 
 367     m_propagationLevel 
= wxEVENT_PROPAGATE_NONE
; 
 368     m_wasProcessed 
= false; 
 371 wxEvent::wxEvent(const wxEvent
& src
) 
 373     , m_eventObject(src
.m_eventObject
) 
 374     , m_eventType(src
.m_eventType
) 
 375     , m_timeStamp(src
.m_timeStamp
) 
 377     , m_callbackUserData(src
.m_callbackUserData
) 
 378     , m_propagationLevel(src
.m_propagationLevel
) 
 379     , m_skipped(src
.m_skipped
) 
 380     , m_isCommandEvent(src
.m_isCommandEvent
) 
 381     , m_wasProcessed(false) 
 385 wxEvent
& wxEvent::operator=(const wxEvent
& src
) 
 387     wxObject::operator=(src
); 
 389     m_eventObject 
= src
.m_eventObject
; 
 390     m_eventType 
= src
.m_eventType
; 
 391     m_timeStamp 
= src
.m_timeStamp
; 
 393     m_callbackUserData 
= src
.m_callbackUserData
; 
 394     m_propagationLevel 
= src
.m_propagationLevel
; 
 395     m_skipped 
= src
.m_skipped
; 
 396     m_isCommandEvent 
= src
.m_isCommandEvent
; 
 398     // don't change m_wasProcessed 
 407 // ---------------------------------------------------------------------------- 
 409 // ---------------------------------------------------------------------------- 
 412     // 'this' : used in base member initializer list (for m_commandString) 
 413     #pragma warning(disable:4355) 
 416 wxCommandEvent::wxCommandEvent(wxEventType commandType
, int theId
) 
 417               : wxEvent(theId
, commandType
) 
 420     m_clientObject 
= NULL
; 
 423     m_isCommandEvent 
= true; 
 425     // the command events are propagated upwards by default 
 426     m_propagationLevel 
= wxEVENT_PROPAGATE_MAX
; 
 430     #pragma warning(default:4355) 
 433 wxString 
wxCommandEvent::GetString() const 
 435     if (m_eventType 
!= wxEVT_COMMAND_TEXT_UPDATED 
|| !m_eventObject
) 
 442         wxTextCtrl 
*txt 
= wxDynamicCast(m_eventObject
, wxTextCtrl
); 
 444             return txt
->GetValue(); 
 446 #endif // wxUSE_TEXTCTRL 
 451 // ---------------------------------------------------------------------------- 
 453 // ---------------------------------------------------------------------------- 
 456 wxLongLong 
wxUpdateUIEvent::sm_lastUpdate 
= 0; 
 459 long wxUpdateUIEvent::sm_updateInterval 
= 0; 
 461 wxUpdateUIMode 
wxUpdateUIEvent::sm_updateMode 
= wxUPDATE_UI_PROCESS_ALL
; 
 464 bool wxUpdateUIEvent::CanUpdate(wxWindowBase 
*win
) 
 466     // Don't update if we've switched global updating off 
 467     // and this window doesn't support updates. 
 469        (GetMode() == wxUPDATE_UI_PROCESS_SPECIFIED 
&& 
 470        ((win
->GetExtraStyle() & wxWS_EX_PROCESS_UI_UPDATES
) == 0))) 
 473     if (sm_updateInterval 
== -1) 
 476     if (sm_updateInterval 
== 0) 
 479 #if wxUSE_STOPWATCH && wxUSE_LONGLONG 
 480     wxLongLong now 
= wxGetLocalTimeMillis(); 
 481     if (now 
> (sm_lastUpdate 
+ sm_updateInterval
)) 
 488     // If we don't have wxStopWatch or wxLongLong, we 
 489     // should err on the safe side and update now anyway. 
 494 // Reset the update time to provide a delay until the next 
 495 // time we should update 
 496 void wxUpdateUIEvent::ResetUpdateTime() 
 498 #if wxUSE_STOPWATCH && wxUSE_LONGLONG 
 499     if (sm_updateInterval 
> 0) 
 501         wxLongLong now 
= wxGetLocalTimeMillis(); 
 502         if (now 
> (sm_lastUpdate 
+ sm_updateInterval
)) 
 510 // ---------------------------------------------------------------------------- 
 512 // ---------------------------------------------------------------------------- 
 514 wxScrollEvent::wxScrollEvent(wxEventType commandType
, 
 518     : wxCommandEvent(commandType
, id
) 
 520     m_extraLong 
= orient
; 
 524 // ---------------------------------------------------------------------------- 
 526 // ---------------------------------------------------------------------------- 
 528 wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType
, 
 532     m_eventType 
= commandType
; 
 533     m_extraLong 
= orient
; 
 537 // ---------------------------------------------------------------------------- 
 539 // ---------------------------------------------------------------------------- 
 541 wxMouseEvent::wxMouseEvent(wxEventType commandType
) 
 543     m_eventType 
= commandType
; 
 549     m_middleDown 
= false; 
 558     m_linesPerAction 
= 0; 
 562 void wxMouseEvent::Assign(const wxMouseEvent
& event
) 
 564     wxEvent::operator=(event
); 
 566     // Borland C++ 5.82 doesn't compile an explicit call to an implicitly 
 567     // defined operator=() so need to do it this way: 
 568     *static_cast<wxMouseState 
*>(this) = event
; 
 573     m_leftDown 
= event
.m_leftDown
; 
 574     m_middleDown 
= event
.m_middleDown
; 
 575     m_rightDown 
= event
.m_rightDown
; 
 576     m_aux1Down 
= event
.m_aux1Down
; 
 577     m_aux2Down 
= event
.m_aux2Down
; 
 579     m_wheelRotation 
= event
.m_wheelRotation
; 
 580     m_wheelDelta 
= event
.m_wheelDelta
; 
 581     m_linesPerAction 
= event
.m_linesPerAction
; 
 582     m_wheelAxis 
= event
.m_wheelAxis
; 
 585 // return true if was a button dclick event 
 586 bool wxMouseEvent::ButtonDClick(int but
) const 
 591             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDClick")); 
 594         case wxMOUSE_BTN_ANY
: 
 595             return (LeftDClick() || MiddleDClick() || RightDClick() || 
 596                     Aux1DClick() || Aux2DClick()); 
 598         case wxMOUSE_BTN_LEFT
: 
 601         case wxMOUSE_BTN_MIDDLE
: 
 602             return MiddleDClick(); 
 604         case wxMOUSE_BTN_RIGHT
: 
 605             return RightDClick(); 
 607         case wxMOUSE_BTN_AUX1
: 
 610         case wxMOUSE_BTN_AUX2
: 
 615 // return true if was a button down event 
 616 bool wxMouseEvent::ButtonDown(int but
) const 
 621             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDown")); 
 624         case wxMOUSE_BTN_ANY
: 
 625             return (LeftDown() || MiddleDown() || RightDown() || 
 626                     Aux1Down() || Aux2Down()); 
 628         case wxMOUSE_BTN_LEFT
: 
 631         case wxMOUSE_BTN_MIDDLE
: 
 634         case wxMOUSE_BTN_RIGHT
: 
 637         case wxMOUSE_BTN_AUX1
: 
 640         case wxMOUSE_BTN_AUX2
: 
 645 // return true if was a button up event 
 646 bool wxMouseEvent::ButtonUp(int but
) const 
 651             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonUp")); 
 654         case wxMOUSE_BTN_ANY
: 
 655             return (LeftUp() || MiddleUp() || RightUp() || 
 656                     Aux1Up() || Aux2Up()); 
 658         case wxMOUSE_BTN_LEFT
: 
 661         case wxMOUSE_BTN_MIDDLE
: 
 664         case wxMOUSE_BTN_RIGHT
: 
 667         case wxMOUSE_BTN_AUX1
: 
 670         case wxMOUSE_BTN_AUX2
: 
 675 // return true if the given button is currently changing state 
 676 bool wxMouseEvent::Button(int but
) const 
 681             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::Button")); 
 684         case wxMOUSE_BTN_ANY
: 
 685             return ButtonUp(wxMOUSE_BTN_ANY
) || 
 686                     ButtonDown(wxMOUSE_BTN_ANY
) || 
 687                         ButtonDClick(wxMOUSE_BTN_ANY
); 
 689         case wxMOUSE_BTN_LEFT
: 
 690             return LeftDown() || LeftUp() || LeftDClick(); 
 692         case wxMOUSE_BTN_MIDDLE
: 
 693             return MiddleDown() || MiddleUp() || MiddleDClick(); 
 695         case wxMOUSE_BTN_RIGHT
: 
 696             return RightDown() || RightUp() || RightDClick(); 
 698         case wxMOUSE_BTN_AUX1
: 
 699            return Aux1Down() || Aux1Up() || Aux1DClick(); 
 701         case wxMOUSE_BTN_AUX2
: 
 702            return Aux2Down() || Aux2Up() || Aux2DClick(); 
 706 int wxMouseEvent::GetButton() const 
 708     for ( int i 
= 1; i 
< wxMOUSE_BTN_MAX
; i
++ ) 
 716     return wxMOUSE_BTN_NONE
; 
 719 // Find the logical position of the event given the DC 
 720 wxPoint 
wxMouseEvent::GetLogicalPosition(const wxDC
& dc
) const 
 722     wxPoint 
pt(dc
.DeviceToLogicalX(m_x
), dc
.DeviceToLogicalY(m_y
)); 
 726 // ---------------------------------------------------------------------------- 
 728 // ---------------------------------------------------------------------------- 
 730 wxKeyEvent::wxKeyEvent(wxEventType type
) 
 739 wxKeyEvent::wxKeyEvent(const wxKeyEvent
& evt
) 
 746     m_keyCode 
= evt
.m_keyCode
; 
 747     m_rawCode 
= evt
.m_rawCode
; 
 748     m_rawFlags 
= evt
.m_rawFlags
; 
 751     m_uniChar 
= evt
.m_uniChar
; 
 755 bool wxKeyEvent::IsKeyInCategory(int category
) const 
 757     switch ( GetKeyCode() ) 
 763         case WXK_NUMPAD_LEFT
: 
 764         case WXK_NUMPAD_RIGHT
: 
 766         case WXK_NUMPAD_DOWN
: 
 767             return (category 
& WXK_CATEGORY_ARROW
) != 0; 
 771         case WXK_NUMPAD_PAGEUP
: 
 772         case WXK_NUMPAD_PAGEDOWN
: 
 773             return (category 
& WXK_CATEGORY_PAGING
) != 0; 
 777         case WXK_NUMPAD_HOME
: 
 779             return (category 
& WXK_CATEGORY_JUMP
) != 0; 
 783             return (category 
& WXK_CATEGORY_TAB
) != 0; 
 787         case WXK_NUMPAD_DELETE
: 
 788             return (category 
& WXK_CATEGORY_CUT
) != 0; 
 795 // ---------------------------------------------------------------------------- 
 796 // wxWindowCreateEvent 
 797 // ---------------------------------------------------------------------------- 
 799 wxWindowCreateEvent::wxWindowCreateEvent(wxWindow 
*win
) 
 801     SetEventType(wxEVT_CREATE
); 
 805 // ---------------------------------------------------------------------------- 
 806 // wxWindowDestroyEvent 
 807 // ---------------------------------------------------------------------------- 
 809 wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow 
*win
) 
 811     SetEventType(wxEVT_DESTROY
); 
 815 // ---------------------------------------------------------------------------- 
 817 // ---------------------------------------------------------------------------- 
 819 wxChildFocusEvent::wxChildFocusEvent(wxWindow 
*win
) 
 820                  : wxCommandEvent(wxEVT_CHILD_FOCUS
) 
 825 // ---------------------------------------------------------------------------- 
 827 // ---------------------------------------------------------------------------- 
 830 wxHelpEvent::Origin 
wxHelpEvent::GuessOrigin(Origin origin
) 
 832     if ( origin 
== Origin_Unknown 
) 
 834         // assume that the event comes from the help button if it's not from 
 835         // keyboard and that pressing F1 always results in the help event 
 836         origin 
= wxGetKeyState(WXK_F1
) ? Origin_Keyboard 
: Origin_HelpButton
; 
 847 // ---------------------------------------------------------------------------- 
 849 // ---------------------------------------------------------------------------- 
 851 static const int EVENT_TYPE_TABLE_INIT_SIZE 
= 31; // Not too big not too small... 
 853 wxEventHashTable
* wxEventHashTable::sm_first 
= NULL
; 
 855 wxEventHashTable::wxEventHashTable(const wxEventTable 
&table
) 
 859     AllocEventTypeTable(EVENT_TYPE_TABLE_INIT_SIZE
); 
 863         m_next
->m_previous 
= this; 
 867 wxEventHashTable::~wxEventHashTable() 
 870         m_next
->m_previous 
= m_previous
; 
 872         m_previous
->m_next 
= m_next
; 
 873     if (sm_first 
== this) 
 879 void wxEventHashTable::Clear() 
 881     for ( size_t i 
= 0; i 
< m_size
; i
++ ) 
 883         EventTypeTablePointer  eTTnode 
= m_eventTypeTable
[i
]; 
 887     delete[] m_eventTypeTable
; 
 888     m_eventTypeTable 
= NULL
; 
 893 #if wxUSE_MEMORY_TRACING 
 896 void wxEventHashTable::ClearAll() 
 898     wxEventHashTable
* table 
= sm_first
; 
 902         table 
= table
->m_next
; 
 906 #endif // wxUSE_MEMORY_TRACING 
 908 bool wxEventHashTable::HandleEvent(wxEvent 
&event
, wxEvtHandler 
*self
) 
 913         m_rebuildHash 
= false; 
 916     if (!m_eventTypeTable
) 
 919     // Find all entries for the given event type. 
 920     wxEventType eventType 
= event
.GetEventType(); 
 921     const EventTypeTablePointer eTTnode 
= m_eventTypeTable
[eventType 
% m_size
]; 
 922     if (eTTnode 
&& eTTnode
->eventType 
== eventType
) 
 924         // Now start the search for an event handler 
 925         // that can handle an event with the given ID. 
 926         const wxEventTableEntryPointerArray
& 
 927             eventEntryTable 
= eTTnode
->eventEntryTable
; 
 929         const size_t count 
= eventEntryTable
.GetCount(); 
 930         for (size_t n 
= 0; n 
< count
; n
++) 
 932             const wxEventTableEntry
& entry 
= *eventEntryTable
[n
]; 
 933             if ( wxEvtHandler::ProcessEventIfMatchesId(entry
, self
, event
) ) 
 941 void wxEventHashTable::InitHashTable() 
 943     // Loop over the event tables and all its base tables. 
 944     const wxEventTable 
*table 
= &m_table
; 
 947         // Retrieve all valid event handler entries 
 948         const wxEventTableEntry 
*entry 
= table
->entries
; 
 949         while (entry
->m_fn 
!= 0) 
 951             // Add the event entry in the Hash. 
 957         table 
= table
->baseTable
; 
 960     // Lets free some memory. 
 962     for(i 
= 0; i 
< m_size
; i
++) 
 964         EventTypeTablePointer  eTTnode 
= m_eventTypeTable
[i
]; 
 967             eTTnode
->eventEntryTable
.Shrink(); 
 972 void wxEventHashTable::AddEntry(const wxEventTableEntry 
&entry
) 
 974     // This might happen 'accidentally' as the app is exiting 
 975     if (!m_eventTypeTable
) 
 978     EventTypeTablePointer 
*peTTnode 
= &m_eventTypeTable
[entry
.m_eventType 
% m_size
]; 
 979     EventTypeTablePointer  eTTnode 
= *peTTnode
; 
 983         if (eTTnode
->eventType 
!= entry
.m_eventType
) 
 986             GrowEventTypeTable(); 
 987             // Try again to add it. 
 994         eTTnode 
= new EventTypeTable
; 
 995         eTTnode
->eventType 
= entry
.m_eventType
; 
 999     // Fill all hash entries between entry.m_id and entry.m_lastId... 
1000     eTTnode
->eventEntryTable
.Add(&entry
); 
1003 void wxEventHashTable::AllocEventTypeTable(size_t size
) 
1005     m_eventTypeTable 
= new EventTypeTablePointer
[size
]; 
1006     memset((void *)m_eventTypeTable
, 0, sizeof(EventTypeTablePointer
)*size
); 
1010 void wxEventHashTable::GrowEventTypeTable() 
1012     size_t oldSize 
= m_size
; 
1013     EventTypeTablePointer 
*oldEventTypeTable 
= m_eventTypeTable
; 
1015     // TODO: Search the most optimal grow sequence 
1016     AllocEventTypeTable(/* GetNextPrime(oldSize) */oldSize
*2+1); 
1018     for ( size_t i 
= 0; i 
< oldSize
; /* */ ) 
1020         EventTypeTablePointer  eTToldNode 
= oldEventTypeTable
[i
]; 
1023             EventTypeTablePointer 
*peTTnode 
= &m_eventTypeTable
[eTToldNode
->eventType 
% m_size
]; 
1024             EventTypeTablePointer  eTTnode 
= *peTTnode
; 
1026             // Check for collision, we don't want any. 
1029                 GrowEventTypeTable(); 
1030                 continue; // Don't increment the counter, 
1031                           // as we still need to add this element. 
1035                 // Get the old value and put it in the new table. 
1036                 *peTTnode 
= oldEventTypeTable
[i
]; 
1043     delete[] oldEventTypeTable
; 
1046 // ---------------------------------------------------------------------------- 
1048 // ---------------------------------------------------------------------------- 
1050 wxEvtHandler::wxEvtHandler() 
1052     m_nextHandler 
= NULL
; 
1053     m_previousHandler 
= NULL
; 
1055     m_dynamicEvents 
= NULL
; 
1056     m_pendingEvents 
= NULL
; 
1058     // no client data (yet) 
1059     m_clientData 
= NULL
; 
1060     m_clientDataType 
= wxClientData_None
; 
1063 wxEvtHandler::~wxEvtHandler() 
1067     if (m_dynamicEvents
) 
1069         for ( wxList::iterator it 
= m_dynamicEvents
->begin(), 
1070                                end 
= m_dynamicEvents
->end(); 
1074             wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)*it
; 
1076             // Remove ourselves from sink destructor notifications 
1077             // (this has usually been done, in wxTrackable destructor) 
1078             wxEvtHandler 
*eventSink 
= entry
->m_fn
->GetEvtHandler(); 
1081                 wxEventConnectionRef 
* const 
1082                     evtConnRef 
= FindRefInTrackerList(eventSink
); 
1085                     eventSink
->RemoveNode(evtConnRef
); 
1090             delete entry
->m_callbackUserData
; 
1093         delete m_dynamicEvents
; 
1096     // Remove us from the list of the pending events if necessary. 
1098         wxTheApp
->RemovePendingEventHandler(this); 
1100     DeletePendingEvents(); 
1102     // we only delete object data, not untyped 
1103     if ( m_clientDataType 
== wxClientData_Object 
) 
1104         delete m_clientObject
; 
1107 void wxEvtHandler::Unlink() 
1109     // this event handler must take itself out of the chain of handlers: 
1111     if (m_previousHandler
) 
1112         m_previousHandler
->SetNextHandler(m_nextHandler
); 
1115         m_nextHandler
->SetPreviousHandler(m_previousHandler
); 
1117     m_nextHandler 
= NULL
; 
1118     m_previousHandler 
= NULL
; 
1121 bool wxEvtHandler::IsUnlinked() const 
1123     return m_previousHandler 
== NULL 
&& 
1124            m_nextHandler 
== NULL
; 
1129 bool wxEvtHandler::ProcessThreadEvent(const wxEvent
& event
) 
1131     // check that we are really in a child thread 
1132     wxASSERT_MSG( !wxThread::IsMain(), 
1133                   wxT("use ProcessEvent() in main thread") ); 
1135     AddPendingEvent(event
); 
1140 #endif // wxUSE_THREADS 
1142 void wxEvtHandler::QueueEvent(wxEvent 
*event
) 
1144     wxCHECK_RET( event
, "NULL event can't be posted" ); 
1148         // we need an event loop which manages the list of event handlers with 
1149         // pending events... cannot proceed without it! 
1150         wxLogDebug("No application object! Cannot queue this event!"); 
1152         // anyway delete the given event to avoid memory leaks 
1158     // 1) Add this event to our list of pending events 
1159     wxENTER_CRIT_SECT( m_pendingEventsLock 
); 
1161     if ( !m_pendingEvents 
) 
1162         m_pendingEvents 
= new wxList
; 
1164     m_pendingEvents
->Append(event
); 
1166     // 2) Add this event handler to list of event handlers that 
1167     //    have pending events. 
1169     wxTheApp
->AppendPendingEventHandler(this); 
1171     // only release m_pendingEventsLock now because otherwise there is a race 
1172     // condition as described in the ticket #9093: we could process the event 
1173     // just added to m_pendingEvents in our ProcessPendingEvents() below before 
1174     // we had time to append this pointer to wxHandlersWithPendingEvents list; thus 
1175     // breaking the invariant that a handler should be in the list iff it has 
1176     // any pending events to process 
1177     wxLEAVE_CRIT_SECT( m_pendingEventsLock 
); 
1179     // 3) Inform the system that new pending events are somewhere, 
1180     //    and that these should be processed in idle time. 
1184 void wxEvtHandler::DeletePendingEvents() 
1186     if (m_pendingEvents
) 
1187         m_pendingEvents
->DeleteContents(true); 
1188     wxDELETE(m_pendingEvents
); 
1191 void wxEvtHandler::ProcessPendingEvents() 
1195         // we need an event loop which manages the list of event handlers with 
1196         // pending events... cannot proceed without it! 
1197         wxLogDebug("No application object! Cannot process pending events!"); 
1201     // we need to process only a single pending event in this call because 
1202     // each call to ProcessEvent() could result in the destruction of this 
1203     // same event handler (see the comment at the end of this function) 
1205     wxENTER_CRIT_SECT( m_pendingEventsLock 
); 
1207     // this method is only called by wxApp if this handler does have 
1209     wxCHECK_RET( m_pendingEvents 
&& !m_pendingEvents
->IsEmpty(), 
1210                  "should have pending events if called" ); 
1212     wxList::compatibility_iterator node 
= m_pendingEvents
->GetFirst(); 
1213     wxEvent
* pEvent 
= static_cast<wxEvent 
*>(node
->GetData()); 
1215     // find the first event which can be processed now: 
1216     wxEventLoopBase
* evtLoop 
= wxEventLoopBase::GetActive(); 
1217     if (evtLoop 
&& evtLoop
->IsYielding()) 
1219         while (node 
&& pEvent 
&& !evtLoop
->IsEventAllowedInsideYield(pEvent
->GetEventCategory())) 
1221             node 
= node
->GetNext(); 
1222             pEvent 
= node 
? static_cast<wxEvent 
*>(node
->GetData()) : NULL
; 
1227             // all our events are NOT processable now... signal this: 
1228             wxTheApp
->DelayPendingEventHandler(this); 
1230             // see the comment at the beginning of evtloop.h header for the 
1231             // logic behind YieldFor() and behind DelayPendingEventHandler() 
1233             wxLEAVE_CRIT_SECT( m_pendingEventsLock 
); 
1239     wxEventPtr 
event(pEvent
); 
1241     // it's important we remove event from list before processing it, else a 
1242     // nested event loop, for example from a modal dialog, might process the 
1243     // same event again. 
1244     m_pendingEvents
->Erase(node
); 
1246     if ( m_pendingEvents
->IsEmpty() ) 
1248         // if there are no more pending events left, we don't need to 
1249         // stay in this list 
1250         wxTheApp
->RemovePendingEventHandler(this); 
1253     wxLEAVE_CRIT_SECT( m_pendingEventsLock 
); 
1255     ProcessEvent(*event
); 
1257     // careful: this object could have been deleted by the event handler 
1258     // executed by the above ProcessEvent() call, so we can't access any fields 
1259     // of this object any more 
1263 bool wxEvtHandler::ProcessEventIfMatchesId(const wxEventTableEntryBase
& entry
, 
1264                                            wxEvtHandler 
*handler
, 
1267     int tableId1 
= entry
.m_id
, 
1268         tableId2 
= entry
.m_lastId
; 
1270     // match only if the event type is the same and the id is either -1 in 
1271     // the event table (meaning "any") or the event id matches the id 
1272     // specified in the event table either exactly or by falling into 
1273     // range between first and last 
1274     if ((tableId1 
== wxID_ANY
) || 
1275         (tableId2 
== wxID_ANY 
&& tableId1 
== event
.GetId()) || 
1276         (tableId2 
!= wxID_ANY 
&& 
1277          (event
.GetId() >= tableId1 
&& event
.GetId() <= tableId2
))) 
1280         event
.m_callbackUserData 
= entry
.m_callbackUserData
; 
1282 #if wxUSE_EXCEPTIONS 
1285             // call the handler via wxApp method which allows the user to catch 
1286             // any exceptions which may be thrown by any handler in the program 
1288             wxTheApp
->CallEventHandler(handler
, *entry
.m_fn
, event
); 
1291 #endif // wxUSE_EXCEPTIONS 
1293             (*entry
.m_fn
)(handler
, event
); 
1296         if (!event
.GetSkipped()) 
1303 bool wxEvtHandler::DoTryApp(wxEvent
& event
) 
1305     if ( wxTheApp 
&& (this != wxTheApp
) ) 
1307         // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always 
1308         // swallow it. wxEVT_IDLE is sent explicitly to wxApp so it will be 
1309         // processed appropriately via SearchEventTable. 
1310         if ( event
.GetEventType() != wxEVT_IDLE 
) 
1312             if ( wxTheApp
->ProcessEvent(event
) ) 
1320 bool wxEvtHandler::TryBefore(wxEvent
& event
) 
1322 #if WXWIN_COMPATIBILITY_2_8 
1323     // call the old virtual function to keep the code overriding it working 
1324     return TryValidator(event
); 
1331 bool wxEvtHandler::TryAfter(wxEvent
& event
) 
1333 #if WXWIN_COMPATIBILITY_2_8 
1334     // as above, call the old virtual function for compatibility 
1335     return TryParent(event
); 
1337     return DoTryApp(event
); 
1341 bool wxEvtHandler::ProcessEvent(wxEvent
& event
) 
1343     // allow the application to hook into event processing 
1345     // note that we should only do it if we're the first event handler called 
1346     // to avoid calling FilterEvent() multiple times as the event goes through 
1347     // the event handler chain and possibly upwards the window hierarchy 
1348     if ( !event
.WasProcessed() ) 
1352             int rc 
= wxTheApp
->FilterEvent(event
); 
1355                 wxASSERT_MSG( rc 
== 1 || rc 
== 0, 
1356                               "unexpected wxApp::FilterEvent return value" ); 
1360             //else: proceed normally 
1364     if ( ProcessEventHere(event
) ) 
1367     // pass the event to the next handler, notice that we shouldn't call 
1368     // TryAfter() even if it doesn't handle the event as the last handler in 
1369     // the chain will do it 
1370     if ( GetNextHandler() ) 
1371         return GetNextHandler()->ProcessEvent(event
); 
1373     // propagate the event upwards the window chain and/or to the application 
1374     // object if it wasn't processed at this level 
1375     return TryAfter(event
); 
1378 bool wxEvtHandler::ProcessEventHere(wxEvent
& event
) 
1380     // If the event handler is disabled it doesn't process any events 
1381     if ( !GetEvtHandlerEnabled() ) 
1384     // Try the hooks which should be called before our own handlers 
1385     if ( TryBefore(event
) ) 
1388     // Handle per-instance dynamic event tables first 
1389     if ( m_dynamicEvents 
&& SearchDynamicEventTable(event
) ) 
1392     // Then static per-class event tables 
1393     if ( GetEventHashTable().HandleEvent(event
, this) ) 
1396     // We don't have a handler for this event. 
1400 bool wxEvtHandler::SafelyProcessEvent(wxEvent
& event
) 
1402 #if wxUSE_EXCEPTIONS 
1406         return ProcessEvent(event
); 
1407 #if wxUSE_EXCEPTIONS 
1411         // notice that we do it in 2 steps to avoid warnings about possibly 
1412         // uninitialized loop variable from some versions of g++ which are not 
1413         // smart enough to figure out that GetActive() doesn't throw and so 
1414         // that loop will always be initialized 
1415         wxEventLoopBase 
*loop 
= NULL
; 
1418             loop 
= wxEventLoopBase::GetActive(); 
1420             if ( !wxTheApp 
|| !wxTheApp
->OnExceptionInMainLoop() ) 
1425             //else: continue running current event loop 
1431             // OnExceptionInMainLoop() threw, possibly rethrowing the same 
1432             // exception again: very good, but we still need Exit() to 
1439 #endif // wxUSE_EXCEPTIONS 
1442 bool wxEvtHandler::SearchEventTable(wxEventTable
& table
, wxEvent
& event
) 
1444     const wxEventType eventType 
= event
.GetEventType(); 
1445     for ( int i 
= 0; table
.entries
[i
].m_fn 
!= 0; i
++ ) 
1447         const wxEventTableEntry
& entry 
= table
.entries
[i
]; 
1448         if ( eventType 
== entry
.m_eventType 
) 
1450             if ( ProcessEventIfMatchesId(entry
, this, event
) ) 
1458 void wxEvtHandler::DoBind(int id
, 
1460                           wxEventType eventType
, 
1461                           wxEventFunctor 
*func
, 
1464     wxDynamicEventTableEntry 
*entry 
= 
1465         new wxDynamicEventTableEntry(eventType
, id
, lastId
, func
, userData
); 
1467     if (!m_dynamicEvents
) 
1468         m_dynamicEvents 
= new wxList
; 
1470     // Insert at the front of the list so most recent additions are found first 
1471     m_dynamicEvents
->Insert( (wxObject
*) entry 
); 
1473     // Make sure we get to know when a sink is destroyed 
1474     wxEvtHandler 
*eventSink 
= func
->GetEvtHandler(); 
1475     if ( eventSink 
&& eventSink 
!= this ) 
1477         wxEventConnectionRef 
*evtConnRef 
= FindRefInTrackerList(eventSink
); 
1479             evtConnRef
->IncRef( ); 
1481             new wxEventConnectionRef(this, eventSink
); 
1486 wxEvtHandler::DoUnbind(int id
, 
1488                        wxEventType eventType
, 
1489                        const wxEventFunctor
& func
, 
1492     if (!m_dynamicEvents
) 
1495     // Remove connection from tracker node (wxEventConnectionRef) 
1496     wxEvtHandler 
*eventSink 
= func
.GetEvtHandler(); 
1497     if ( eventSink 
&& eventSink 
!= this ) 
1499         wxEventConnectionRef 
*evtConnRef 
= FindRefInTrackerList(eventSink
); 
1501             evtConnRef
->DecRef(); 
1504     wxList::compatibility_iterator node 
= m_dynamicEvents
->GetFirst(); 
1507         wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->GetData(); 
1509         if ((entry
->m_id 
== id
) && 
1510             ((entry
->m_lastId 
== lastId
) || (lastId 
== wxID_ANY
)) && 
1511             ((entry
->m_eventType 
== eventType
) || (eventType 
== wxEVT_NULL
)) && 
1512             entry
->m_fn
->IsMatching(func
) && 
1513             ((entry
->m_callbackUserData 
== userData
) || !userData
)) 
1515             delete entry
->m_callbackUserData
; 
1516             m_dynamicEvents
->Erase( node 
); 
1520         node 
= node
->GetNext(); 
1525 bool wxEvtHandler::SearchDynamicEventTable( wxEvent
& event 
) 
1527     wxCHECK_MSG( m_dynamicEvents
, false, 
1528                  wxT("caller should check that we have dynamic events") ); 
1530     wxList::compatibility_iterator node 
= m_dynamicEvents
->GetFirst(); 
1533         wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->GetData(); 
1535         // get next node before (maybe) calling the event handler as it could 
1536         // call Disconnect() invalidating the current node 
1537         node 
= node
->GetNext(); 
1539         if ( event
.GetEventType() == entry
->m_eventType 
) 
1541             wxEvtHandler 
*handler 
= entry
->m_fn
->GetEvtHandler(); 
1544             if ( ProcessEventIfMatchesId(*entry
, handler
, event
) ) 
1552 void wxEvtHandler::DoSetClientObject( wxClientData 
*data 
) 
1554     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Void
, 
1555                   wxT("can't have both object and void client data") ); 
1557     if ( m_clientObject 
) 
1558         delete m_clientObject
; 
1560     m_clientObject 
= data
; 
1561     m_clientDataType 
= wxClientData_Object
; 
1564 wxClientData 
*wxEvtHandler::DoGetClientObject() const 
1566     // it's not an error to call GetClientObject() on a window which doesn't 
1567     // have client data at all - NULL will be returned 
1568     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Void
, 
1569                   wxT("this window doesn't have object client data") ); 
1571     return m_clientObject
; 
1574 void wxEvtHandler::DoSetClientData( void *data 
) 
1576     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Object
, 
1577                   wxT("can't have both object and void client data") ); 
1579     m_clientData 
= data
; 
1580     m_clientDataType 
= wxClientData_Void
; 
1583 void *wxEvtHandler::DoGetClientData() const 
1585     // it's not an error to call GetClientData() on a window which doesn't have 
1586     // client data at all - NULL will be returned 
1587     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Object
, 
1588                   wxT("this window doesn't have void client data") ); 
1590     return m_clientData
; 
1593 // A helper to find an wxEventConnectionRef object 
1594 wxEventConnectionRef 
* 
1595 wxEvtHandler::FindRefInTrackerList(wxEvtHandler 
*eventSink
) 
1597     for ( wxTrackerNode 
*node 
= eventSink
->GetFirst(); node
; node 
= node
->m_nxt 
) 
1599         // we only want wxEventConnectionRef nodes here 
1600         wxEventConnectionRef 
*evtConnRef 
= node
->ToEventConnection(); 
1601         if ( evtConnRef 
&& evtConnRef
->m_src 
== this ) 
1603             wxASSERT( evtConnRef
->m_sink
==eventSink 
); 
1611 void wxEvtHandler::OnSinkDestroyed( wxEvtHandler 
*sink 
) 
1613     wxASSERT(m_dynamicEvents
); 
1615     // remove all connections with this sink 
1616     wxList::compatibility_iterator node 
= m_dynamicEvents
->GetFirst(), node_nxt
; 
1619         wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->GetData(); 
1620         node_nxt 
= node
->GetNext(); 
1622         if ( entry
->m_fn
->GetEvtHandler() == sink 
) 
1624             delete entry
->m_callbackUserData
; 
1625             m_dynamicEvents
->Erase( node 
); 
1632 #endif // wxUSE_BASE 
1636 // Find a window with the focus, that is also a descendant of the given window. 
1637 // This is used to determine the window to initially send commands to. 
1638 wxWindow
* wxFindFocusDescendant(wxWindow
* ancestor
) 
1640     // Process events starting with the window with the focus, if any. 
1641     wxWindow
* focusWin 
= wxWindow::FindFocus(); 
1642     wxWindow
* win 
= focusWin
; 
1644     // Check if this is a descendant of this frame. 
1645     // If not, win will be set to NULL. 
1648         if (win 
== ancestor
) 
1651             win 
= win
->GetParent(); 
1659 // ---------------------------------------------------------------------------- 
1661 // ---------------------------------------------------------------------------- 
1663 wxEventBlocker::wxEventBlocker(wxWindow 
*win
, wxEventType type
) 
1665     wxCHECK_RET(win
, wxT("Null window given to wxEventBlocker")); 
1670     m_window
->PushEventHandler(this); 
1673 wxEventBlocker::~wxEventBlocker() 
1675     wxEvtHandler 
*popped 
= m_window
->PopEventHandler(false); 
1676     wxCHECK_RET(popped 
== this, 
1677         wxT("Don't push other event handlers into a window managed by wxEventBlocker!")); 
1680 bool wxEventBlocker::ProcessEvent(wxEvent
& event
) 
1682     // should this event be blocked? 
1683     for ( size_t i 
= 0; i 
< m_eventsToBlock
.size(); i
++ ) 
1685         wxEventType t 
= (wxEventType
)m_eventsToBlock
[i
]; 
1686         if ( t 
== wxEVT_ANY 
|| t 
== event
.GetEventType() ) 
1687             return true;   // yes, it should: mark this event as processed