1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Event classes 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "event.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  37         #include "wx/control.h" 
  46     #include "wx/validate.h" 
  49 // ---------------------------------------------------------------------------- 
  51 // ---------------------------------------------------------------------------- 
  53 IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler
, wxObject
) 
  54 IMPLEMENT_ABSTRACT_CLASS(wxEvent
, wxObject
) 
  57     IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent
, wxEvent
) 
  58     IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent
, wxEvent
) 
  59     IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent
, wxCommandEvent
) 
  60     IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent
, wxCommandEvent
) 
  61     IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent
, wxEvent
) 
  62     IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent
, wxEvent
) 
  63     IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent
, wxEvent
) 
  64     IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent
, wxEvent
) 
  65     IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent
, wxEvent
) 
  66     IMPLEMENT_DYNAMIC_CLASS(wxNcPaintEvent
, wxEvent
) 
  67     IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent
, wxEvent
) 
  68     IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent
, wxEvent
) 
  69     IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent
, wxEvent
) 
  70     IMPLEMENT_DYNAMIC_CLASS(wxChildFocusEvent
, wxCommandEvent
) 
  71     IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent
, wxEvent
) 
  72     IMPLEMENT_DYNAMIC_CLASS(wxShowEvent
, wxEvent
) 
  73     IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent
, wxEvent
) 
  74     IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent
, wxEvent
) 
  75     IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent
, wxEvent
) 
  76     IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent
, wxEvent
) 
  77     IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent
, wxEvent
) 
  78     IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent
, wxEvent
) 
  79     IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent
, wxEvent
) 
  80     IMPLEMENT_DYNAMIC_CLASS(wxSetCursorEvent
, wxEvent
) 
  81     IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent
, wxEvent
) 
  82     IMPLEMENT_DYNAMIC_CLASS(wxDisplayChangedEvent
, wxEvent
) 
  83     IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent
, wxCommandEvent
) 
  84     IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent
, wxCommandEvent
) 
  85     IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent
, wxEvent
) 
  86     IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent
, wxEvent
) 
  87     IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent
, wxEvent
) 
  88     IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent
, wxEvent
) 
  89     IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent
, wxCommandEvent
) 
  90     IMPLEMENT_DYNAMIC_CLASS(wxContextMenuEvent
, wxCommandEvent
) 
  91     IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureChangedEvent
, wxEvent
) 
  94 const wxEventTable 
*wxEvtHandler::GetEventTable() const 
  95     { return &wxEvtHandler::sm_eventTable
; } 
  97 const wxEventTable 
wxEvtHandler::sm_eventTable 
= 
  98     { (const wxEventTable 
*)NULL
, &wxEvtHandler::sm_eventTableEntries
[0] }; 
 100 const wxEventTableEntry 
wxEvtHandler::sm_eventTableEntries
[] = 
 101     { DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL
, 0, 0, (wxObjectEventFunction
)NULL
, NULL
) }; 
 103 // ---------------------------------------------------------------------------- 
 105 // ---------------------------------------------------------------------------- 
 107 // To put pending event handlers 
 108 wxList 
*wxPendingEvents 
= (wxList 
*)NULL
; 
 111     // protects wxPendingEvents list 
 112     wxCriticalSection 
*wxPendingEventsLocker 
= (wxCriticalSection 
*)NULL
; 
 115 #if !WXWIN_COMPATIBILITY_EVENT_TYPES 
 117 // common event types are defined here, other event types are defined by the 
 118 // components which use them 
 120 DEFINE_EVENT_TYPE(wxEVT_NULL
) 
 121 DEFINE_EVENT_TYPE(wxEVT_COMMAND_BUTTON_CLICKED
) 
 122 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKBOX_CLICKED
) 
 123 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHOICE_SELECTED
) 
 124 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_SELECTED
) 
 125 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
) 
 126 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
) 
 127 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MENU_SELECTED
) 
 128 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SLIDER_UPDATED
) 
 129 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RADIOBOX_SELECTED
) 
 130 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RADIOBUTTON_SELECTED
) 
 131 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SCROLLBAR_UPDATED
) 
 132 DEFINE_EVENT_TYPE(wxEVT_COMMAND_VLBOX_SELECTED
) 
 133 DEFINE_EVENT_TYPE(wxEVT_COMMAND_COMBOBOX_SELECTED
) 
 134 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_RCLICKED
) 
 135 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER
) 
 136 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED
) 
 138 // Sockets and timers send events, too 
 139 DEFINE_EVENT_TYPE(wxEVT_SOCKET
) 
 140 DEFINE_EVENT_TYPE(wxEVT_TIMER
) 
 143 DEFINE_EVENT_TYPE(wxEVT_LEFT_DOWN
) 
 144 DEFINE_EVENT_TYPE(wxEVT_LEFT_UP
) 
 145 DEFINE_EVENT_TYPE(wxEVT_MIDDLE_DOWN
) 
 146 DEFINE_EVENT_TYPE(wxEVT_MIDDLE_UP
) 
 147 DEFINE_EVENT_TYPE(wxEVT_RIGHT_DOWN
) 
 148 DEFINE_EVENT_TYPE(wxEVT_RIGHT_UP
) 
 149 DEFINE_EVENT_TYPE(wxEVT_MOTION
) 
 150 DEFINE_EVENT_TYPE(wxEVT_ENTER_WINDOW
) 
 151 DEFINE_EVENT_TYPE(wxEVT_LEAVE_WINDOW
) 
 152 DEFINE_EVENT_TYPE(wxEVT_LEFT_DCLICK
) 
 153 DEFINE_EVENT_TYPE(wxEVT_MIDDLE_DCLICK
) 
 154 DEFINE_EVENT_TYPE(wxEVT_RIGHT_DCLICK
) 
 155 DEFINE_EVENT_TYPE(wxEVT_SET_FOCUS
) 
 156 DEFINE_EVENT_TYPE(wxEVT_KILL_FOCUS
) 
 157 DEFINE_EVENT_TYPE(wxEVT_CHILD_FOCUS
) 
 158 DEFINE_EVENT_TYPE(wxEVT_MOUSEWHEEL
) 
 160 // Non-client mouse events 
 161 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DOWN
) 
 162 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_UP
) 
 163 DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_DOWN
) 
 164 DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_UP
) 
 165 DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_DOWN
) 
 166 DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_UP
) 
 167 DEFINE_EVENT_TYPE(wxEVT_NC_MOTION
) 
 168 DEFINE_EVENT_TYPE(wxEVT_NC_ENTER_WINDOW
) 
 169 DEFINE_EVENT_TYPE(wxEVT_NC_LEAVE_WINDOW
) 
 170 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DCLICK
) 
 171 DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_DCLICK
) 
 172 DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_DCLICK
) 
 174 // Character input event type 
 175 DEFINE_EVENT_TYPE(wxEVT_CHAR
) 
 176 DEFINE_EVENT_TYPE(wxEVT_CHAR_HOOK
) 
 177 DEFINE_EVENT_TYPE(wxEVT_NAVIGATION_KEY
) 
 178 DEFINE_EVENT_TYPE(wxEVT_KEY_DOWN
) 
 179 DEFINE_EVENT_TYPE(wxEVT_KEY_UP
) 
 182 DEFINE_EVENT_TYPE(wxEVT_SET_CURSOR
) 
 184 // wxScrollbar and wxSlider event identifiers 
 185 DEFINE_EVENT_TYPE(wxEVT_SCROLL_TOP
) 
 186 DEFINE_EVENT_TYPE(wxEVT_SCROLL_BOTTOM
) 
 187 DEFINE_EVENT_TYPE(wxEVT_SCROLL_LINEUP
) 
 188 DEFINE_EVENT_TYPE(wxEVT_SCROLL_LINEDOWN
) 
 189 DEFINE_EVENT_TYPE(wxEVT_SCROLL_PAGEUP
) 
 190 DEFINE_EVENT_TYPE(wxEVT_SCROLL_PAGEDOWN
) 
 191 DEFINE_EVENT_TYPE(wxEVT_SCROLL_THUMBTRACK
) 
 192 DEFINE_EVENT_TYPE(wxEVT_SCROLL_THUMBRELEASE
) 
 193 DEFINE_EVENT_TYPE(wxEVT_SCROLL_ENDSCROLL
) 
 195 // Scroll events from wxWindow 
 196 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_TOP
) 
 197 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_BOTTOM
) 
 198 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_LINEUP
) 
 199 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_LINEDOWN
) 
 200 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_PAGEUP
) 
 201 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_PAGEDOWN
) 
 202 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_THUMBTRACK
) 
 203 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_THUMBRELEASE
) 
 206 DEFINE_EVENT_TYPE(wxEVT_SIZE
) 
 207 DEFINE_EVENT_TYPE(wxEVT_MOVE
) 
 208 DEFINE_EVENT_TYPE(wxEVT_CLOSE_WINDOW
) 
 209 DEFINE_EVENT_TYPE(wxEVT_END_SESSION
) 
 210 DEFINE_EVENT_TYPE(wxEVT_QUERY_END_SESSION
) 
 211 DEFINE_EVENT_TYPE(wxEVT_ACTIVATE_APP
) 
 212 DEFINE_EVENT_TYPE(wxEVT_POWER
) 
 213 DEFINE_EVENT_TYPE(wxEVT_ACTIVATE
) 
 214 DEFINE_EVENT_TYPE(wxEVT_CREATE
) 
 215 DEFINE_EVENT_TYPE(wxEVT_DESTROY
) 
 216 DEFINE_EVENT_TYPE(wxEVT_SHOW
) 
 217 DEFINE_EVENT_TYPE(wxEVT_ICONIZE
) 
 218 DEFINE_EVENT_TYPE(wxEVT_MAXIMIZE
) 
 219 DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_CHANGED
) 
 220 DEFINE_EVENT_TYPE(wxEVT_PAINT
) 
 221 DEFINE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND
) 
 222 DEFINE_EVENT_TYPE(wxEVT_NC_PAINT
) 
 223 DEFINE_EVENT_TYPE(wxEVT_PAINT_ICON
) 
 224 DEFINE_EVENT_TYPE(wxEVT_MENU_OPEN
) 
 225 DEFINE_EVENT_TYPE(wxEVT_MENU_CLOSE
) 
 226 DEFINE_EVENT_TYPE(wxEVT_MENU_HIGHLIGHT
) 
 227 DEFINE_EVENT_TYPE(wxEVT_CONTEXT_MENU
) 
 228 DEFINE_EVENT_TYPE(wxEVT_SYS_COLOUR_CHANGED
) 
 229 DEFINE_EVENT_TYPE(wxEVT_DISPLAY_CHANGED
) 
 230 DEFINE_EVENT_TYPE(wxEVT_SETTING_CHANGED
) 
 231 DEFINE_EVENT_TYPE(wxEVT_QUERY_NEW_PALETTE
) 
 232 DEFINE_EVENT_TYPE(wxEVT_PALETTE_CHANGED
) 
 233 DEFINE_EVENT_TYPE(wxEVT_JOY_BUTTON_DOWN
) 
 234 DEFINE_EVENT_TYPE(wxEVT_JOY_BUTTON_UP
) 
 235 DEFINE_EVENT_TYPE(wxEVT_JOY_MOVE
) 
 236 DEFINE_EVENT_TYPE(wxEVT_JOY_ZMOVE
) 
 237 DEFINE_EVENT_TYPE(wxEVT_DROP_FILES
) 
 238 DEFINE_EVENT_TYPE(wxEVT_DRAW_ITEM
) 
 239 DEFINE_EVENT_TYPE(wxEVT_MEASURE_ITEM
) 
 240 DEFINE_EVENT_TYPE(wxEVT_COMPARE_ITEM
) 
 241 DEFINE_EVENT_TYPE(wxEVT_INIT_DIALOG
) 
 242 DEFINE_EVENT_TYPE(wxEVT_IDLE
) 
 243 DEFINE_EVENT_TYPE(wxEVT_UPDATE_UI
) 
 245 // Generic command events 
 246 // Note: a click is a higher-level event than button down/up 
 247 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_CLICK
) 
 248 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_DCLICK
) 
 249 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RIGHT_CLICK
) 
 250 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RIGHT_DCLICK
) 
 251 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SET_FOCUS
) 
 252 DEFINE_EVENT_TYPE(wxEVT_COMMAND_KILL_FOCUS
) 
 253 DEFINE_EVENT_TYPE(wxEVT_COMMAND_ENTER
) 
 256 DEFINE_EVENT_TYPE(wxEVT_HELP
) 
 257 DEFINE_EVENT_TYPE(wxEVT_DETAILED_HELP
) 
 259 #endif // !WXWIN_COMPATIBILITY_EVENT_TYPES 
 261 // ============================================================================ 
 263 // ============================================================================ 
 265 // ---------------------------------------------------------------------------- 
 266 // event initialization 
 267 // ---------------------------------------------------------------------------- 
 272     static int s_lastUsedEventType 
= wxEVT_FIRST
; 
 274 #if WXWIN_COMPATIBILITY_2 
 275     // check that we don't overlap with the user-defined types: if it does 
 276     // happen, the best solution is probably to update the existing code to 
 277     // use wxNewEventType() instead of wxEVT_USER_FIRST 
 279     // due to the uncertainty 
 280     wxASSERT_MSG( s_lastUsedEventType 
< wxEVT_USER_FIRST 
- 1, 
 281                   _T("possible event type conflict") ); 
 282 #endif // WXWIN_COMPATIBILITY_2 
 284     return s_lastUsedEventType
++; 
 287 // ---------------------------------------------------------------------------- 
 289 // ---------------------------------------------------------------------------- 
 292  * General wxWindows events, covering 
 293  * all interesting things that might happen (button clicking, resizing, 
 294  * setting text in widgets, etc.). 
 296  * For each completely new event type, derive a new event class. 
 300 wxEvent::wxEvent(int theId
, wxEventType commandType 
) 
 302     m_eventType 
= commandType
; 
 303     m_eventObject 
= (wxObject 
*) NULL
; 
 307     m_callbackUserData 
= (wxObject 
*) NULL
; 
 308     m_isCommandEvent 
= FALSE
; 
 311 wxEvent::wxEvent(const wxEvent 
&src
) 
 313     , m_eventObject(src
.m_eventObject
) 
 314     , m_eventType(src
.m_eventType
) 
 315     , m_timeStamp(src
.m_timeStamp
) 
 317     , m_callbackUserData(src
.m_callbackUserData
) 
 318     , m_skipped(src
.m_skipped
) 
 319     , m_isCommandEvent(src
.m_isCommandEvent
) 
 330 wxCommandEvent::wxCommandEvent(wxEventType commandType
, int theId
) 
 331   : wxEvent(theId
, commandType
) 
 333     m_clientData 
= (char *) NULL
; 
 334     m_clientObject 
= (wxClientData 
*) NULL
; 
 337     m_commandString 
= wxEmptyString
; 
 338     m_isCommandEvent 
= TRUE
; 
 345 wxScrollEvent::wxScrollEvent(wxEventType commandType
, 
 349     : wxCommandEvent(commandType
, id
) 
 351     m_extraLong 
= orient
; 
 359 wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType
, 
 363     m_eventType 
= commandType
; 
 364     m_extraLong 
= orient
; 
 373 wxMouseEvent::wxMouseEvent(wxEventType commandType
) 
 375     m_eventType 
= commandType
; 
 378     m_controlDown 
= FALSE
; 
 382     m_middleDown 
= FALSE
; 
 387     m_linesPerAction 
= 0; 
 390 void wxMouseEvent::Assign(const wxMouseEvent
& event
) 
 392     m_eventType 
= event
.m_eventType
; 
 397     m_leftDown 
= event
.m_leftDown
; 
 398     m_middleDown 
= event
.m_middleDown
; 
 399     m_rightDown 
= event
.m_rightDown
; 
 401     m_controlDown 
= event
.m_controlDown
; 
 402     m_shiftDown 
= event
.m_shiftDown
; 
 403     m_altDown 
= event
.m_altDown
; 
 404     m_metaDown 
= event
.m_metaDown
; 
 406     m_wheelRotation 
= event
.m_wheelRotation
; 
 407     m_wheelDelta 
= event
.m_wheelDelta
; 
 408     m_linesPerAction 
= event
.m_linesPerAction
; 
 411 // True if was a button dclick event (1 = left, 2 = middle, 3 = right) 
 412 // or any button dclick event (but = -1) 
 413 bool wxMouseEvent::ButtonDClick(int but
) const 
 418             return (LeftDClick() || MiddleDClick() || RightDClick()); 
 422             return MiddleDClick(); 
 424             return RightDClick(); 
 426             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDClick")); 
 432 // True if was a button down event (1 = left, 2 = middle, 3 = right) 
 433 // or any button down event (but = -1) 
 434 bool wxMouseEvent::ButtonDown(int but
) const 
 439             return (LeftDown() || MiddleDown() || RightDown()); 
 447             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDown")); 
 453 // True if was a button up event (1 = left, 2 = middle, 3 = right) 
 454 // or any button up event (but = -1) 
 455 bool wxMouseEvent::ButtonUp(int but
) const 
 460             return (LeftUp() || MiddleUp() || RightUp()); 
 468             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonUp")); 
 474 // True if the given button is currently changing state 
 475 bool wxMouseEvent::Button(int but
) const 
 480             return (ButtonUp(-1) || ButtonDown(-1) || ButtonDClick(-1)); 
 482             return (LeftDown() || LeftUp() || LeftDClick()); 
 484             return (MiddleDown() || MiddleUp() || MiddleDClick()); 
 486             return (RightDown() || RightUp() || RightDClick()); 
 488             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::Button")); 
 494 bool wxMouseEvent::ButtonIsDown(int but
) const 
 499             return (LeftIsDown() || MiddleIsDown() || RightIsDown()); 
 503             return MiddleIsDown(); 
 505             return RightIsDown(); 
 507             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonIsDown")); 
 513 int wxMouseEvent::GetButton() const 
 515     for ( int i 
= 1; i 
<= 3; i
++ ) 
 526 // Find the logical position of the event given the DC 
 527 wxPoint 
wxMouseEvent::GetLogicalPosition(const wxDC
& dc
) const 
 529     wxPoint 
pt(dc
.DeviceToLogicalX(m_x
), dc
.DeviceToLogicalY(m_y
)); 
 539 wxKeyEvent::wxKeyEvent(wxEventType type
) 
 543     m_controlDown 
= FALSE
; 
 553 wxKeyEvent::wxKeyEvent(const wxKeyEvent
& evt
)  
 559     m_keyCode 
= evt
.m_keyCode
; 
 561     m_controlDown 
= evt
.m_controlDown
; 
 562     m_shiftDown 
= evt
.m_shiftDown
; 
 563     m_altDown 
= evt
.m_altDown
; 
 564     m_metaDown 
= evt
.m_metaDown
; 
 565     m_scanCode 
= evt
.m_scanCode
; 
 566     m_rawCode 
= evt
.m_rawCode
; 
 567     m_rawFlags 
= evt
.m_rawFlags
; 
 570     m_uniChar 
= evt
.m_uniChar
; 
 574 long wxKeyEvent::KeyCode() const 
 579 wxWindowCreateEvent::wxWindowCreateEvent(wxWindow 
*win
) 
 581     SetEventType(wxEVT_CREATE
); 
 585 wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow 
*win
) 
 587     SetEventType(wxEVT_DESTROY
); 
 591 wxChildFocusEvent::wxChildFocusEvent(wxWindow 
*win
) 
 592                  : wxCommandEvent(wxEVT_CHILD_FOCUS
) 
 599 // ---------------------------------------------------------------------------- 
 601 // ---------------------------------------------------------------------------- 
 607 wxEvtHandler::wxEvtHandler() 
 609     m_nextHandler 
= (wxEvtHandler 
*) NULL
; 
 610     m_previousHandler 
= (wxEvtHandler 
*) NULL
; 
 612     m_dynamicEvents 
= (wxList 
*) NULL
; 
 614     m_pendingEvents 
= (wxList 
*) NULL
; 
 616 #  if !defined(__VISAGECPP__) 
 617     m_eventsLocker 
= new wxCriticalSection
; 
 620     // no client data (yet) 
 622     m_clientDataType 
= wxClientData_None
; 
 625 wxEvtHandler::~wxEvtHandler() 
 627     // Takes itself out of the list of handlers 
 628     if (m_previousHandler
) 
 629         m_previousHandler
->m_nextHandler 
= m_nextHandler
; 
 632         m_nextHandler
->m_previousHandler 
= m_previousHandler
; 
 636         wxNode 
*node 
= m_dynamicEvents
->First(); 
 639 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
 640             wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 641 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
 642             wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->Data(); 
 643 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
 645             if (entry
->m_callbackUserData
) 
 646                 delete entry
->m_callbackUserData
; 
 650         delete m_dynamicEvents
; 
 653     delete m_pendingEvents
; 
 656 #  if !defined(__VISAGECPP__) 
 657     delete m_eventsLocker
; 
 661     // we only delete object data, not untyped 
 662     if ( m_clientDataType 
== wxClientData_Object 
) 
 663         delete m_clientObject
; 
 668 bool wxEvtHandler::ProcessThreadEvent(wxEvent
& event
) 
 670     // check that we are really in a child thread 
 671     wxASSERT_MSG( !wxThread::IsMain(), 
 672                   wxT("use ProcessEvent() in main thread") ); 
 674     AddPendingEvent(event
); 
 679 #endif // wxUSE_THREADS 
 681 void wxEvtHandler::AddPendingEvent(wxEvent
& event
) 
 683     // 1) Add event to list of pending events of this event handler 
 685     wxEvent 
*eventCopy 
= event
.Clone(); 
 687     // we must be able to copy the events here so the event class must 
 688     // implement Clone() properly instead of just providing a NULL stab for it 
 689     wxCHECK_RET( eventCopy
, 
 690                  _T("events of this type aren't supposed to be posted") ); 
 692 #if defined(__VISAGECPP__) 
 693     wxENTER_CRIT_SECT( m_eventsLocker
); 
 695     wxENTER_CRIT_SECT( *m_eventsLocker
); 
 698     if ( !m_pendingEvents 
) 
 699       m_pendingEvents 
= new wxList
; 
 701     m_pendingEvents
->Append(eventCopy
); 
 703 #if defined(__VISAGECPP__) 
 704     wxLEAVE_CRIT_SECT( m_eventsLocker
); 
 706     wxLEAVE_CRIT_SECT( *m_eventsLocker
); 
 709     // 2) Add this event handler to list of event handlers that 
 710     //    have pending events. 
 712     wxENTER_CRIT_SECT(*wxPendingEventsLocker
); 
 714     if ( !wxPendingEvents 
) 
 715         wxPendingEvents 
= new wxList
; 
 716     wxPendingEvents
->Append(this); 
 718     wxLEAVE_CRIT_SECT(*wxPendingEventsLocker
); 
 720     // 3) Inform the system that new pending events are somwehere, 
 721     //    and that these should be processed in idle time. 
 725 void wxEvtHandler::ProcessPendingEvents() 
 727 #if defined(__VISAGECPP__) 
 728     wxENTER_CRIT_SECT( m_eventsLocker
); 
 730     wxENTER_CRIT_SECT( *m_eventsLocker
); 
 733     wxNode 
*node 
= m_pendingEvents
->First(); 
 736         wxEvent 
*event 
= (wxEvent 
*)node
->Data(); 
 739         // In ProcessEvent, new events might get added and 
 740         // we can safely leave the crtical section here. 
 741 #if defined(__VISAGECPP__) 
 742         wxLEAVE_CRIT_SECT( m_eventsLocker
); 
 744         wxLEAVE_CRIT_SECT( *m_eventsLocker
); 
 746         ProcessEvent(*event
); 
 748 #if defined(__VISAGECPP__) 
 749         wxENTER_CRIT_SECT( m_eventsLocker
); 
 751         wxENTER_CRIT_SECT( *m_eventsLocker
); 
 754         node 
= m_pendingEvents
->First(); 
 757 #if defined(__VISAGECPP__) 
 758     wxLEAVE_CRIT_SECT( m_eventsLocker
); 
 760     wxLEAVE_CRIT_SECT( *m_eventsLocker
); 
 768 bool wxEvtHandler::ProcessEvent(wxEvent
& event
) 
 772     // We have to use the actual window or processing events from 
 773     // wxWindowNative destructor won't work (we don't see the wxWindow class) 
 775     // check that our flag corresponds to reality 
 776     wxClassInfo
* info 
= NULL
; 
 777 #ifdef __WXUNIVERSAL__ 
 778 #  if defined(__WXMSW__) 
 779     info 
= CLASSINFO(wxWindowMSW
); 
 780 #  elif defined(__WXGTK__) 
 781     info 
= CLASSINFO(wxWindowGTK
); 
 782 #  elif defined(__WXX11__) 
 783     info 
= CLASSINFO(wxWindowX11
); 
 784 #  elif defined(__WXMGL__) 
 785     info 
= CLASSINFO(wxWindowMGL
); 
 786 #  elif defined(__WXPM__) 
 787     info 
= CLASSINFO(wxWindowOS2
); 
 788 #  elif defined(__WXMAC__) 
 789     info 
= CLASSINFO(wxWindowMac
); 
 790 #  elif defined(__WXMOTIF__) 
 791     info 
= CLASSINFO(wxWindowMotif
); 
 794     info 
= CLASSINFO(wxWindow
); 
 797     if ( m_isWindow 
!= IsKindOf(info
) ) 
 799         wxString msg 
= GetClassInfo()->GetClassName(); 
 800         msg 
+= _T(" should [not] be a window but it is [not]"); 
 805 #endif // __WXDEBUG__ 
 809     // allow the application to hook into event processing 
 812         int rc 
= wxTheApp
->FilterEvent(event
); 
 815             wxASSERT_MSG( rc 
== 1 || rc 
== 0, 
 816                           _T("unexpected wxApp::FilterEvent return value") ); 
 820         //else: proceed normally 
 823     // An event handler can be enabled or disabled 
 824     if ( GetEvtHandlerEnabled() ) 
 829         What is this? When using GUI threads, a non main 
 830         threads can send an event and process it itself. 
 831         This breaks GTK's GUI threads, so please explain. 
 834         // Check whether we are in a child thread. 
 835         if ( !wxThread::IsMain() ) 
 836           return ProcessThreadEvent(event
); 
 839         // Handle per-instance dynamic event tables first 
 840         if ( m_dynamicEvents 
&& SearchDynamicEventTable(event
) ) 
 843         // Then static per-class event tables 
 844         const wxEventTable 
*table 
= GetEventTable(); 
 846 #if wxUSE_GUI && wxUSE_VALIDATORS 
 847         // Try the associated validator first, if this is a window. 
 848         // Problem: if the event handler of the window has been replaced, 
 849         // this wxEvtHandler may no longer be a window. 
 850         // Therefore validators won't be processed if the handler 
 851         // has been replaced with SetEventHandler. 
 852         // THIS CAN BE CURED if PushEventHandler is used instead of 
 853         // SetEventHandler, and then processing will be passed down the 
 854         // chain of event handlers. 
 857             wxWindow 
*win 
= (wxWindow 
*)this; 
 859             // Can only use the validator of the window which 
 860             // is receiving the event 
 861             if ( win 
== event
.GetEventObject() ) 
 863                 wxValidator 
*validator 
= win
->GetValidator(); 
 864                 if ( validator 
&& validator
->ProcessEvent(event
) ) 
 872         // Search upwards through the inheritance hierarchy 
 875             if ( SearchEventTable((wxEventTable
&)*table
, event
) ) 
 877             table 
= table
->baseTable
; 
 881     // Try going down the event handler chain 
 882     if ( GetNextHandler() ) 
 884         if ( GetNextHandler()->ProcessEvent(event
) ) 
 889     // Carry on up the parent-child hierarchy, but only if event is a command 
 890     // event: it wouldn't make sense for a parent to receive a child's size 
 891     // event, for example 
 892     if ( m_isWindow 
&& event
.IsCommandEvent() ) 
 894         wxWindow 
*win 
= (wxWindow 
*)this; 
 896         // honour the requests to stop propagation at this window: this is 
 897         // used by the dialogs, for example, to prevent processing the events 
 898         // from the dialog controls in the parent frame which rarely, if ever, 
 900         if ( !(win
->GetExtraStyle() & wxWS_EX_BLOCK_EVENTS
) ) 
 902             wxWindow 
*parent 
= win
->GetParent(); 
 903             if ( parent 
&& !parent
->IsBeingDeleted() ) 
 904                 return parent
->GetEventHandler()->ProcessEvent(event
); 
 909     // Last try - application object. 
 910     if ( wxTheApp 
&& (this != wxTheApp
) ) 
 912         // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always 
 913         // swallow it. wxEVT_IDLE is sent explicitly to wxApp so it will be 
 914         // processed appropriately via SearchEventTable. 
 915         if ( event
.GetEventType() != wxEVT_IDLE 
) 
 917             if ( wxTheApp
->ProcessEvent(event
) ) 
 925 bool wxEvtHandler::SearchEventTable(wxEventTable
& table
, wxEvent
& event
) 
 927     wxEventType eventType 
= event
.GetEventType(); 
 928     int eventId 
= event
.GetId(); 
 930     // BC++ doesn't like testing for m_fn without != 0 
 931     for ( int i 
= 0; table
.entries
[i
].m_fn 
!= 0; i
++ ) 
 933         // the line using reference exposes a bug in gcc: although it _seems_ 
 934         // to work, it leads to weird crashes later on during program 
 937         wxEventTableEntry entry 
= table
.entries
[i
]; 
 939         const wxEventTableEntry
& entry 
= table
.entries
[i
]; 
 942         // match only if the event type is the same and the id is either -1 in 
 943         // the event table (meaning "any") or the event id matches the id 
 944         // specified in the event table either exactly or by falling into 
 945         // range between first and last 
 946         if ( eventType 
== entry
.m_eventType 
) 
 948             int tableId1 
= entry
.m_id
, 
 949                 tableId2 
= entry
.m_lastId
; 
 951             if ( (tableId1 
== -1) || 
 952                  (tableId2 
== -1 && eventId 
== tableId1
) || 
 954                     (eventId 
>= tableId1 
&& eventId 
<= tableId2
)) ) 
 957                 event
.m_callbackUserData 
= entry
.m_callbackUserData
; 
 959                 (this->*((wxEventFunction
) (entry
.m_fn
)))(event
); 
 961                 return !event
.GetSkipped(); 
 969 void wxEvtHandler::Connect( int id
, int lastId
, 
 971                             wxObjectEventFunction func
, 
 974 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
 975     wxEventTableEntry 
*entry 
= new wxEventTableEntry
; 
 976     entry
->m_eventType 
= eventType
; 
 978     entry
->m_lastId 
= lastId
; 
 980     entry
->m_callbackUserData 
= userData
; 
 981 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
 982     wxDynamicEventTableEntry 
*entry 
= 
 983         new wxDynamicEventTableEntry(eventType
, id
, lastId
, func
, userData
); 
 984 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
 986     if (!m_dynamicEvents
) 
 987         m_dynamicEvents 
= new wxList
; 
 989     m_dynamicEvents
->Append( (wxObject
*) entry 
); 
 992 bool wxEvtHandler::Disconnect( int id
, int lastId
, wxEventType eventType
, 
 993                   wxObjectEventFunction func
, 
 996     if (!m_dynamicEvents
) 
 999     wxNode 
*node 
= m_dynamicEvents
->First(); 
1002 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
1003             wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
1004 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
1005             wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->Data(); 
1006 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
1008         if ((entry
->m_id 
== id
) && 
1009             ((entry
->m_lastId 
== lastId
) || (lastId 
== -1)) && 
1010             ((entry
->m_eventType 
== eventType
) || (eventType 
== wxEVT_NULL
)) && 
1011             ((entry
->m_fn 
== func
) || (func 
== (wxObjectEventFunction
)NULL
)) && 
1012             ((entry
->m_callbackUserData 
== userData
) || (userData 
== (wxObject
*)NULL
))) 
1014             if (entry
->m_callbackUserData
) 
1015                 delete entry
->m_callbackUserData
; 
1016             m_dynamicEvents
->DeleteNode( node 
); 
1020         node 
= node
->Next(); 
1025 bool wxEvtHandler::SearchDynamicEventTable( wxEvent
& event 
) 
1027     wxCHECK_MSG( m_dynamicEvents
, FALSE
, 
1028                  wxT("caller should check that we have dynamic events") ); 
1030     int commandId 
= event
.GetId(); 
1032     wxNode 
*node 
= m_dynamicEvents
->First(); 
1035 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
1036             wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
1037 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
1038             wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->Data(); 
1039 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
1043             // Match, if event spec says any id will do (id == -1) 
1044             if ( (event
.GetEventType() == entry
->m_eventType
) && 
1045                  (entry
->m_id 
== -1 || 
1046                   (entry
->m_lastId 
== -1 && commandId 
== entry
->m_id
) || 
1047                   (entry
->m_lastId 
!= -1 && 
1048                   (commandId 
>= entry
->m_id 
&& commandId 
<= entry
->m_lastId
))) ) 
1051                 event
.m_callbackUserData 
= entry
->m_callbackUserData
; 
1053                 (this->*((wxEventFunction
) (entry
->m_fn
)))(event
); 
1055                 if (event
.GetSkipped()) 
1061         node 
= node
->Next(); 
1066 void wxEvtHandler::DoSetClientObject( wxClientData 
*data 
) 
1068     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Void
, 
1069                   wxT("can't have both object and void client data") ); 
1071     if ( m_clientObject 
) 
1072         delete m_clientObject
; 
1074     m_clientObject 
= data
; 
1075     m_clientDataType 
= wxClientData_Object
; 
1078 wxClientData 
*wxEvtHandler::DoGetClientObject() const 
1080     // it's not an error to call GetClientObject() on a window which doesn't 
1081     // have client data at all - NULL will be returned 
1082     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Void
, 
1083                   wxT("this window doesn't have object client data") ); 
1085     return m_clientObject
; 
1088 void wxEvtHandler::DoSetClientData( void *data 
) 
1090     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Object
, 
1091                   wxT("can't have both object and void client data") ); 
1093     m_clientData 
= data
; 
1094     m_clientDataType 
= wxClientData_Void
; 
1097 void *wxEvtHandler::DoGetClientData() const 
1099     // it's not an error to call GetClientData() on a window which doesn't have 
1100     // client data at all - NULL will be returned 
1101     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Object
, 
1102                   wxT("this window doesn't have void client data") ); 
1104     return m_clientData
; 
1108 #if WXWIN_COMPATIBILITY 
1109 bool wxEvtHandler::OnClose() 
1111     if (GetNextHandler()) 
1112         return GetNextHandler()->OnClose(); 
1116 #endif // WXWIN_COMPATIBILITY 
1120 // Find a window with the focus, that is also a descendant of the given window. 
1121 // This is used to determine the window to initially send commands to. 
1122 wxWindow
* wxFindFocusDescendant(wxWindow
* ancestor
) 
1124     // Process events starting with the window with the focus, if any. 
1125     wxWindow
* focusWin 
= wxWindow::FindFocus(); 
1126     wxWindow
* win 
= focusWin
; 
1128     // Check if this is a descendant of this frame. 
1129     // If not, win will be set to NULL. 
1132         if (win 
== ancestor
) 
1135             win 
= win
->GetParent(); 
1137     if (win 
== (wxWindow
*) NULL
) 
1138         focusWin 
= (wxWindow
*) NULL
;