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" 
  32         #include "wx/control.h" 
  35         #include "wx/textctrl.h" 
  40 #include "wx/module.h" 
  43     #include "wx/validate.h" 
  45     #include "wx/stopwatch.h" 
  49 // ---------------------------------------------------------------------------- 
  51 // ---------------------------------------------------------------------------- 
  54     IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler
, wxObject
) 
  55     IMPLEMENT_ABSTRACT_CLASS(wxEvent
, wxObject
) 
  59     IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent
, wxEvent
) 
  60     IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent
, wxEvent
) 
  61     IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent
, wxCommandEvent
) 
  62     IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent
, wxCommandEvent
) 
  63     IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent
, wxEvent
) 
  64     IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent
, wxEvent
) 
  65     IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent
, wxEvent
) 
  66     IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent
, wxEvent
) 
  67     IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent
, wxEvent
) 
  68     IMPLEMENT_DYNAMIC_CLASS(wxNcPaintEvent
, wxEvent
) 
  69     IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent
, wxEvent
) 
  70     IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent
, wxEvent
) 
  71     IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent
, wxEvent
) 
  72     IMPLEMENT_DYNAMIC_CLASS(wxChildFocusEvent
, wxCommandEvent
) 
  73     IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent
, wxEvent
) 
  74     IMPLEMENT_DYNAMIC_CLASS(wxShowEvent
, wxEvent
) 
  75     IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent
, wxEvent
) 
  76     IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent
, wxEvent
) 
  77     IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent
, wxEvent
) 
  78     IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent
, wxEvent
) 
  79     IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent
, wxEvent
) 
  80     IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent
, wxEvent
) 
  81     IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent
, wxEvent
) 
  82     IMPLEMENT_DYNAMIC_CLASS(wxSetCursorEvent
, wxEvent
) 
  83     IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent
, wxEvent
) 
  84     IMPLEMENT_DYNAMIC_CLASS(wxDisplayChangedEvent
, wxEvent
) 
  85     IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent
, wxCommandEvent
) 
  86     IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent
, wxEvent
) 
  87     IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent
, wxEvent
) 
  88     IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent
, wxEvent
) 
  89     IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent
, wxEvent
) 
  90     IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent
, wxEvent
) 
  91     IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent
, wxCommandEvent
) 
  92     IMPLEMENT_DYNAMIC_CLASS(wxContextMenuEvent
, wxCommandEvent
) 
  93     IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureChangedEvent
, wxEvent
) 
  98 const wxEventTable 
*wxEvtHandler::GetEventTable() const 
  99     { return &wxEvtHandler::sm_eventTable
; } 
 101 const wxEventTable 
wxEvtHandler::sm_eventTable 
= 
 102     { (const wxEventTable 
*)NULL
, &wxEvtHandler::sm_eventTableEntries
[0] }; 
 104 wxEventHashTable 
&wxEvtHandler::GetEventHashTable() const 
 105     { return wxEvtHandler::sm_eventHashTable
; } 
 107 wxEventHashTable 
wxEvtHandler::sm_eventHashTable(wxEvtHandler::sm_eventTable
); 
 109 const wxEventTableEntry 
wxEvtHandler::sm_eventTableEntries
[] = 
 110     { DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL
, 0, 0, (wxObjectEventFunction
)NULL
, NULL
) }; 
 114 // Clear up event hash table contents or we can get problems 
 115 // when C++ is cleaning up the static object 
 116 class wxEventTableEntryModule
: public wxModule
 
 118 DECLARE_DYNAMIC_CLASS(wxEventTableEntryModule
) 
 120     wxEventTableEntryModule() {} 
 121     bool OnInit() { return true; } 
 124         wxEventHashTable::ClearAll(); 
 127 IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule
, wxModule
) 
 130 // ---------------------------------------------------------------------------- 
 132 // ---------------------------------------------------------------------------- 
 134 // To put pending event handlers 
 135 wxList 
*wxPendingEvents 
= (wxList 
*)NULL
; 
 138     // protects wxPendingEvents list 
 139     wxCriticalSection 
*wxPendingEventsLocker 
= (wxCriticalSection 
*)NULL
; 
 142 #if !WXWIN_COMPATIBILITY_EVENT_TYPES 
 144 // common event types are defined here, other event types are defined by the 
 145 // components which use them 
 147 const wxEventType wxEVT_FIRST 
= 10000; 
 148 const wxEventType wxEVT_USER_FIRST 
= wxEVT_FIRST 
+ 2000; 
 150 DEFINE_EVENT_TYPE(wxEVT_NULL
) 
 151 DEFINE_EVENT_TYPE(wxEVT_IDLE
) 
 152 DEFINE_EVENT_TYPE(wxEVT_SOCKET
) 
 154 #endif // !WXWIN_COMPATIBILITY_EVENT_TYPES 
 160 #if !WXWIN_COMPATIBILITY_EVENT_TYPES 
 162 DEFINE_EVENT_TYPE(wxEVT_COMMAND_BUTTON_CLICKED
) 
 163 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKBOX_CLICKED
) 
 164 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHOICE_SELECTED
) 
 165 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_SELECTED
) 
 166 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
) 
 167 DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
) 
 168 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MENU_SELECTED
) 
 169 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SLIDER_UPDATED
) 
 170 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RADIOBOX_SELECTED
) 
 171 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RADIOBUTTON_SELECTED
) 
 172 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SCROLLBAR_UPDATED
) 
 173 DEFINE_EVENT_TYPE(wxEVT_COMMAND_VLBOX_SELECTED
) 
 174 DEFINE_EVENT_TYPE(wxEVT_COMMAND_COMBOBOX_SELECTED
) 
 175 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_RCLICKED
) 
 176 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER
) 
 177 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED
) 
 179 // Sockets and timers send events, too 
 180 DEFINE_EVENT_TYPE(wxEVT_TIMER
) 
 183 DEFINE_EVENT_TYPE(wxEVT_LEFT_DOWN
) 
 184 DEFINE_EVENT_TYPE(wxEVT_LEFT_UP
) 
 185 DEFINE_EVENT_TYPE(wxEVT_MIDDLE_DOWN
) 
 186 DEFINE_EVENT_TYPE(wxEVT_MIDDLE_UP
) 
 187 DEFINE_EVENT_TYPE(wxEVT_RIGHT_DOWN
) 
 188 DEFINE_EVENT_TYPE(wxEVT_RIGHT_UP
) 
 189 DEFINE_EVENT_TYPE(wxEVT_MOTION
) 
 190 DEFINE_EVENT_TYPE(wxEVT_ENTER_WINDOW
) 
 191 DEFINE_EVENT_TYPE(wxEVT_LEAVE_WINDOW
) 
 192 DEFINE_EVENT_TYPE(wxEVT_LEFT_DCLICK
) 
 193 DEFINE_EVENT_TYPE(wxEVT_MIDDLE_DCLICK
) 
 194 DEFINE_EVENT_TYPE(wxEVT_RIGHT_DCLICK
) 
 195 DEFINE_EVENT_TYPE(wxEVT_SET_FOCUS
) 
 196 DEFINE_EVENT_TYPE(wxEVT_KILL_FOCUS
) 
 197 DEFINE_EVENT_TYPE(wxEVT_CHILD_FOCUS
) 
 198 DEFINE_EVENT_TYPE(wxEVT_MOUSEWHEEL
) 
 200 // Non-client mouse events 
 201 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DOWN
) 
 202 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_UP
) 
 203 DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_DOWN
) 
 204 DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_UP
) 
 205 DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_DOWN
) 
 206 DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_UP
) 
 207 DEFINE_EVENT_TYPE(wxEVT_NC_MOTION
) 
 208 DEFINE_EVENT_TYPE(wxEVT_NC_ENTER_WINDOW
) 
 209 DEFINE_EVENT_TYPE(wxEVT_NC_LEAVE_WINDOW
) 
 210 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DCLICK
) 
 211 DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_DCLICK
) 
 212 DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_DCLICK
) 
 214 // Character input event type 
 215 DEFINE_EVENT_TYPE(wxEVT_CHAR
) 
 216 DEFINE_EVENT_TYPE(wxEVT_CHAR_HOOK
) 
 217 DEFINE_EVENT_TYPE(wxEVT_NAVIGATION_KEY
) 
 218 DEFINE_EVENT_TYPE(wxEVT_KEY_DOWN
) 
 219 DEFINE_EVENT_TYPE(wxEVT_KEY_UP
) 
 221 DEFINE_EVENT_TYPE(wxEVT_HOTKEY
) 
 225 DEFINE_EVENT_TYPE(wxEVT_SET_CURSOR
) 
 227 // wxScrollbar and wxSlider event identifiers 
 228 DEFINE_EVENT_TYPE(wxEVT_SCROLL_TOP
) 
 229 DEFINE_EVENT_TYPE(wxEVT_SCROLL_BOTTOM
) 
 230 DEFINE_EVENT_TYPE(wxEVT_SCROLL_LINEUP
) 
 231 DEFINE_EVENT_TYPE(wxEVT_SCROLL_LINEDOWN
) 
 232 DEFINE_EVENT_TYPE(wxEVT_SCROLL_PAGEUP
) 
 233 DEFINE_EVENT_TYPE(wxEVT_SCROLL_PAGEDOWN
) 
 234 DEFINE_EVENT_TYPE(wxEVT_SCROLL_THUMBTRACK
) 
 235 DEFINE_EVENT_TYPE(wxEVT_SCROLL_THUMBRELEASE
) 
 236 DEFINE_EVENT_TYPE(wxEVT_SCROLL_CHANGED
) 
 238 // Scroll events from wxWindow 
 239 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_TOP
) 
 240 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_BOTTOM
) 
 241 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_LINEUP
) 
 242 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_LINEDOWN
) 
 243 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_PAGEUP
) 
 244 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_PAGEDOWN
) 
 245 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_THUMBTRACK
) 
 246 DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_THUMBRELEASE
) 
 249 DEFINE_EVENT_TYPE(wxEVT_SIZE
) 
 250 DEFINE_EVENT_TYPE(wxEVT_SIZING
) 
 251 DEFINE_EVENT_TYPE(wxEVT_MOVE
) 
 252 DEFINE_EVENT_TYPE(wxEVT_MOVING
) 
 253 DEFINE_EVENT_TYPE(wxEVT_CLOSE_WINDOW
) 
 254 DEFINE_EVENT_TYPE(wxEVT_END_SESSION
) 
 255 DEFINE_EVENT_TYPE(wxEVT_QUERY_END_SESSION
) 
 256 DEFINE_EVENT_TYPE(wxEVT_HIBERNATE
) 
 257 DEFINE_EVENT_TYPE(wxEVT_ACTIVATE_APP
) 
 258 DEFINE_EVENT_TYPE(wxEVT_POWER
) 
 259 DEFINE_EVENT_TYPE(wxEVT_ACTIVATE
) 
 260 DEFINE_EVENT_TYPE(wxEVT_CREATE
) 
 261 DEFINE_EVENT_TYPE(wxEVT_DESTROY
) 
 262 DEFINE_EVENT_TYPE(wxEVT_SHOW
) 
 263 DEFINE_EVENT_TYPE(wxEVT_ICONIZE
) 
 264 DEFINE_EVENT_TYPE(wxEVT_MAXIMIZE
) 
 265 DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_CHANGED
) 
 266 DEFINE_EVENT_TYPE(wxEVT_PAINT
) 
 267 DEFINE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND
) 
 268 DEFINE_EVENT_TYPE(wxEVT_NC_PAINT
) 
 269 DEFINE_EVENT_TYPE(wxEVT_PAINT_ICON
) 
 270 DEFINE_EVENT_TYPE(wxEVT_MENU_OPEN
) 
 271 DEFINE_EVENT_TYPE(wxEVT_MENU_CLOSE
) 
 272 DEFINE_EVENT_TYPE(wxEVT_MENU_HIGHLIGHT
) 
 273 DEFINE_EVENT_TYPE(wxEVT_CONTEXT_MENU
) 
 274 DEFINE_EVENT_TYPE(wxEVT_SYS_COLOUR_CHANGED
) 
 275 DEFINE_EVENT_TYPE(wxEVT_DISPLAY_CHANGED
) 
 276 DEFINE_EVENT_TYPE(wxEVT_SETTING_CHANGED
) 
 277 DEFINE_EVENT_TYPE(wxEVT_QUERY_NEW_PALETTE
) 
 278 DEFINE_EVENT_TYPE(wxEVT_PALETTE_CHANGED
) 
 279 DEFINE_EVENT_TYPE(wxEVT_JOY_BUTTON_DOWN
) 
 280 DEFINE_EVENT_TYPE(wxEVT_JOY_BUTTON_UP
) 
 281 DEFINE_EVENT_TYPE(wxEVT_JOY_MOVE
) 
 282 DEFINE_EVENT_TYPE(wxEVT_JOY_ZMOVE
) 
 283 DEFINE_EVENT_TYPE(wxEVT_DROP_FILES
) 
 284 DEFINE_EVENT_TYPE(wxEVT_DRAW_ITEM
) 
 285 DEFINE_EVENT_TYPE(wxEVT_MEASURE_ITEM
) 
 286 DEFINE_EVENT_TYPE(wxEVT_COMPARE_ITEM
) 
 287 DEFINE_EVENT_TYPE(wxEVT_INIT_DIALOG
) 
 288 DEFINE_EVENT_TYPE(wxEVT_UPDATE_UI
) 
 290 // Generic command events 
 291 // Note: a click is a higher-level event than button down/up 
 292 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_CLICK
) 
 293 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_DCLICK
) 
 294 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RIGHT_CLICK
) 
 295 DEFINE_EVENT_TYPE(wxEVT_COMMAND_RIGHT_DCLICK
) 
 296 DEFINE_EVENT_TYPE(wxEVT_COMMAND_SET_FOCUS
) 
 297 DEFINE_EVENT_TYPE(wxEVT_COMMAND_KILL_FOCUS
) 
 298 DEFINE_EVENT_TYPE(wxEVT_COMMAND_ENTER
) 
 301 DEFINE_EVENT_TYPE(wxEVT_HELP
) 
 302 DEFINE_EVENT_TYPE(wxEVT_DETAILED_HELP
) 
 304 #endif // !WXWIN_COMPATIBILITY_EVENT_TYPES 
 310 // ============================================================================ 
 312 // ============================================================================ 
 314 // ---------------------------------------------------------------------------- 
 315 // event initialization 
 316 // ---------------------------------------------------------------------------- 
 321     static int s_lastUsedEventType 
= wxEVT_FIRST
; 
 323     return s_lastUsedEventType
++; 
 326 // ---------------------------------------------------------------------------- 
 328 // ---------------------------------------------------------------------------- 
 331  * General wxWidgets events, covering 
 332  * all interesting things that might happen (button clicking, resizing, 
 333  * setting text in widgets, etc.). 
 335  * For each completely new event type, derive a new event class. 
 339 wxEvent::wxEvent(int theId
, wxEventType commandType 
) 
 341     m_eventType 
= commandType
; 
 342     m_eventObject 
= (wxObject 
*) NULL
; 
 346     m_callbackUserData 
= (wxObject 
*) NULL
; 
 347     m_isCommandEvent 
= false; 
 348     m_propagationLevel 
= wxEVENT_PROPAGATE_NONE
; 
 351 wxEvent::wxEvent(const wxEvent 
&src
) 
 353     , m_eventObject(src
.m_eventObject
) 
 354     , m_eventType(src
.m_eventType
) 
 355     , m_timeStamp(src
.m_timeStamp
) 
 357     , m_callbackUserData(src
.m_callbackUserData
) 
 358     , m_propagationLevel(src
.m_propagationLevel
) 
 359     , m_skipped(src
.m_skipped
) 
 360     , m_isCommandEvent(src
.m_isCommandEvent
) 
 374     // 'this' : used in base member initializer list (for m_commandString) 
 375     #pragma warning(disable:4355) 
 378 wxCommandEvent::wxCommandEvent(wxEventType commandType
, int theId
) 
 379               : wxEvent(theId
, commandType
) 
 380 #if WXWIN_COMPATIBILITY_2_4 
 381               , m_commandString(this) 
 384     m_clientData 
= (char *) NULL
; 
 385     m_clientObject 
= (wxClientData 
*) NULL
; 
 388     m_isCommandEvent 
= true; 
 390     // the command events are propagated upwards by default 
 391     m_propagationLevel 
= wxEVENT_PROPAGATE_MAX
; 
 395     #pragma warning(default:4355) 
 398 wxString 
wxCommandEvent::GetString() const 
 400     if(m_eventType 
!= wxEVT_COMMAND_TEXT_UPDATED 
|| !m_eventObject
) 
 405         wxTextCtrl 
*txt 
= wxDynamicCast(m_eventObject
, wxTextCtrl
); 
 407             return txt
->GetValue(); 
 409 #endif // wxUSE_TEXTCTRL 
 419 wxLongLong 
wxUpdateUIEvent::sm_lastUpdate 
= 0; 
 422 long wxUpdateUIEvent::sm_updateInterval 
= 0; 
 424 wxUpdateUIMode 
wxUpdateUIEvent::sm_updateMode 
= wxUPDATE_UI_PROCESS_ALL
; 
 427 bool wxUpdateUIEvent::CanUpdate(wxWindowBase 
*win
) 
 429     // Don't update if we've switched global updating off 
 430     // and this window doesn't support updates. 
 432        (GetMode() == wxUPDATE_UI_PROCESS_SPECIFIED 
&& 
 433        ((win
->GetExtraStyle() & wxWS_EX_PROCESS_UI_UPDATES
) == 0))) 
 436     if (sm_updateInterval 
== -1) 
 439     if (sm_updateInterval 
== 0) 
 442 #if wxUSE_STOPWATCH && wxUSE_LONGLONG 
 443     wxLongLong now 
= wxGetLocalTimeMillis(); 
 444     if (now 
> (sm_lastUpdate 
+ sm_updateInterval
)) 
 451     // If we don't have wxStopWatch or wxLongLong, we 
 452     // should err on the safe side and update now anyway. 
 457 // Reset the update time to provide a delay until the next 
 458 // time we should update 
 459 void wxUpdateUIEvent::ResetUpdateTime() 
 461 #if wxUSE_STOPWATCH && wxUSE_LONGLONG 
 462     if (sm_updateInterval 
> 0) 
 464         wxLongLong now 
= wxGetLocalTimeMillis(); 
 465         if (now 
> (sm_lastUpdate 
+ sm_updateInterval
)) 
 477 wxIdleMode 
wxIdleEvent::sm_idleMode 
= wxIDLE_PROCESS_ALL
; 
 479 // Can we send an idle event? 
 480 bool wxIdleEvent::CanSend(wxWindow
* win
) 
 482     // Don't update if we've switched global updating off 
 483     // and this window doesn't support updates. 
 485        (GetMode() == wxIDLE_PROCESS_SPECIFIED 
&& 
 486        ((win
->GetExtraStyle() & wxWS_EX_PROCESS_IDLE
) == 0))) 
 496 wxScrollEvent::wxScrollEvent(wxEventType commandType
, 
 500     : wxCommandEvent(commandType
, id
) 
 502     m_extraLong 
= orient
; 
 510 wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType
, 
 514     m_eventType 
= commandType
; 
 515     m_extraLong 
= orient
; 
 524 wxMouseEvent::wxMouseEvent(wxEventType commandType
) 
 526     m_eventType 
= commandType
; 
 529     m_controlDown 
= false; 
 533     m_middleDown 
= false; 
 538     m_linesPerAction 
= 0; 
 541 void wxMouseEvent::Assign(const wxMouseEvent
& event
) 
 543     m_eventType 
= event
.m_eventType
; 
 548     m_leftDown 
= event
.m_leftDown
; 
 549     m_middleDown 
= event
.m_middleDown
; 
 550     m_rightDown 
= event
.m_rightDown
; 
 552     m_controlDown 
= event
.m_controlDown
; 
 553     m_shiftDown 
= event
.m_shiftDown
; 
 554     m_altDown 
= event
.m_altDown
; 
 555     m_metaDown 
= event
.m_metaDown
; 
 557     m_wheelRotation 
= event
.m_wheelRotation
; 
 558     m_wheelDelta 
= event
.m_wheelDelta
; 
 559     m_linesPerAction 
= event
.m_linesPerAction
; 
 562 // return true if was a button dclick event 
 563 bool wxMouseEvent::ButtonDClick(int but
) const 
 568             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDClick")); 
 571         case wxMOUSE_BTN_ANY
: 
 572             return (LeftDClick() || MiddleDClick() || RightDClick()); 
 574         case wxMOUSE_BTN_LEFT
: 
 577         case wxMOUSE_BTN_MIDDLE
: 
 578             return MiddleDClick(); 
 580         case wxMOUSE_BTN_RIGHT
: 
 581             return RightDClick(); 
 585 // return true if was a button down event 
 586 bool wxMouseEvent::ButtonDown(int but
) const 
 591             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDown")); 
 594         case wxMOUSE_BTN_ANY
: 
 595             return (LeftDown() || MiddleDown() || RightDown()); 
 597         case wxMOUSE_BTN_LEFT
: 
 600         case wxMOUSE_BTN_MIDDLE
: 
 603         case wxMOUSE_BTN_RIGHT
: 
 608 // return true if was a button up event 
 609 bool wxMouseEvent::ButtonUp(int but
) const 
 614             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonUp")); 
 617         case wxMOUSE_BTN_ANY
: 
 618             return (LeftUp() || MiddleUp() || RightUp()); 
 620         case wxMOUSE_BTN_LEFT
: 
 623         case wxMOUSE_BTN_MIDDLE
: 
 626         case wxMOUSE_BTN_RIGHT
: 
 631 // return true if the given button is currently changing state 
 632 bool wxMouseEvent::Button(int but
) const 
 637             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::Button")); 
 640         case wxMOUSE_BTN_ANY
: 
 641             return ButtonUp(wxMOUSE_BTN_ANY
) || 
 642                     ButtonDown(wxMOUSE_BTN_ANY
) || 
 643                         ButtonDClick(wxMOUSE_BTN_ANY
); 
 645         case wxMOUSE_BTN_LEFT
: 
 646             return LeftDown() || LeftUp() || LeftDClick(); 
 648         case wxMOUSE_BTN_MIDDLE
: 
 649             return MiddleDown() || MiddleUp() || MiddleDClick(); 
 651         case wxMOUSE_BTN_RIGHT
: 
 652             return RightDown() || RightUp() || RightDClick(); 
 656 bool wxMouseEvent::ButtonIsDown(int but
) const 
 661             wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonIsDown")); 
 664         case wxMOUSE_BTN_ANY
: 
 665             return LeftIsDown() || MiddleIsDown() || RightIsDown(); 
 667         case wxMOUSE_BTN_LEFT
: 
 670         case wxMOUSE_BTN_MIDDLE
: 
 671             return MiddleIsDown(); 
 673         case wxMOUSE_BTN_RIGHT
: 
 674             return RightIsDown(); 
 678 int wxMouseEvent::GetButton() const 
 680     for ( int i 
= 1; i 
<= 3; i
++ ) 
 688     return wxMOUSE_BTN_NONE
; 
 691 // Find the logical position of the event given the DC 
 692 wxPoint 
wxMouseEvent::GetLogicalPosition(const wxDC
& dc
) const 
 694     wxPoint 
pt(dc
.DeviceToLogicalX(m_x
), dc
.DeviceToLogicalY(m_y
)); 
 704 wxKeyEvent::wxKeyEvent(wxEventType type
) 
 708     m_controlDown 
= false; 
 718 wxKeyEvent::wxKeyEvent(const wxKeyEvent
& evt
) 
 724     m_keyCode 
= evt
.m_keyCode
; 
 726     m_controlDown 
= evt
.m_controlDown
; 
 727     m_shiftDown 
= evt
.m_shiftDown
; 
 728     m_altDown 
= evt
.m_altDown
; 
 729     m_metaDown 
= evt
.m_metaDown
; 
 730     m_scanCode 
= evt
.m_scanCode
; 
 731     m_rawCode 
= evt
.m_rawCode
; 
 732     m_rawFlags 
= evt
.m_rawFlags
; 
 735     m_uniChar 
= evt
.m_uniChar
; 
 739 long wxKeyEvent::KeyCode() const 
 744 wxWindowCreateEvent::wxWindowCreateEvent(wxWindow 
*win
) 
 746     SetEventType(wxEVT_CREATE
); 
 750 wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow 
*win
) 
 752     SetEventType(wxEVT_DESTROY
); 
 756 wxChildFocusEvent::wxChildFocusEvent(wxWindow 
*win
) 
 757                  : wxCommandEvent(wxEVT_CHILD_FOCUS
) 
 767 // ---------------------------------------------------------------------------- 
 769 // ---------------------------------------------------------------------------- 
 771 static const int EVENT_TYPE_TABLE_INIT_SIZE 
= 31; // Not too big not too small... 
 773 wxEventHashTable
* wxEventHashTable::sm_first 
= NULL
; 
 775 wxEventHashTable::wxEventHashTable(const wxEventTable 
&table
) 
 779     AllocEventTypeTable(EVENT_TYPE_TABLE_INIT_SIZE
); 
 783         m_next
->m_previous 
= this; 
 787 wxEventHashTable::~wxEventHashTable() 
 790         m_next
->m_previous 
= m_previous
; 
 792         m_previous
->m_next 
= m_next
; 
 793     if (sm_first 
== this) 
 799 void wxEventHashTable::Clear() 
 802     for(i 
= 0; i 
< m_size
; i
++) 
 804         EventTypeTablePointer  eTTnode 
= m_eventTypeTable
[i
]; 
 811     // Necessary in order to not invoke the 
 812     // overloaded delete operator when statics are cleaned up 
 813     if (m_eventTypeTable
) 
 814         delete[] m_eventTypeTable
; 
 816     m_eventTypeTable 
= NULL
; 
 821 void wxEventHashTable::ClearAll() 
 823     wxEventHashTable
* table 
= sm_first
; 
 827         table 
= table
->m_next
; 
 831 bool wxEventHashTable::HandleEvent(wxEvent 
&event
, wxEvtHandler 
*self
) 
 836         m_rebuildHash 
= false; 
 839     if (!m_eventTypeTable
) 
 842     // Find all entries for the given event type. 
 843     wxEventType eventType 
= event
.GetEventType(); 
 844     const EventTypeTablePointer eTTnode 
= m_eventTypeTable
[eventType 
% m_size
]; 
 845     if (eTTnode 
&& eTTnode
->eventType 
== eventType
) 
 847         // Now start the search for an event handler 
 848         // that can handle an event with the given ID. 
 849         const wxEventTableEntryPointerArray
& 
 850             eventEntryTable 
= eTTnode
->eventEntryTable
; 
 852         const size_t count 
= eventEntryTable
.GetCount(); 
 853         for (size_t n 
= 0; n 
< count
; n
++) 
 856                     ProcessEventIfMatches(*eventEntryTable
[n
], self
, event
) ) 
 866 void wxEventHashTable::InitHashTable() 
 868     // Loop over the event tables and all its base tables. 
 869     const wxEventTable 
*table 
= &m_table
; 
 872         // Retrieve all valid event handler entries 
 873         const wxEventTableEntry 
*entry 
= table
->entries
; 
 874         while (entry
->m_fn 
!= 0) 
 876             // Add the event entry in the Hash. 
 882         table 
= table
->baseTable
; 
 885     // Lets free some memory. 
 887     for(i 
= 0; i 
< m_size
; i
++) 
 889         EventTypeTablePointer  eTTnode 
= m_eventTypeTable
[i
]; 
 892             eTTnode
->eventEntryTable
.Shrink(); 
 897 void wxEventHashTable::AddEntry(const wxEventTableEntry 
&entry
) 
 899     // This might happen 'accidentally' as the app is exiting 
 900     if (!m_eventTypeTable
) 
 903     EventTypeTablePointer 
*peTTnode 
= &m_eventTypeTable
[entry
.m_eventType 
% m_size
]; 
 904     EventTypeTablePointer  eTTnode 
= *peTTnode
; 
 908         if (eTTnode
->eventType 
!= entry
.m_eventType
) 
 911             GrowEventTypeTable(); 
 912             // Try again to add it. 
 919         eTTnode 
= new EventTypeTable
; 
 920         eTTnode
->eventType 
= entry
.m_eventType
; 
 924     // Fill all hash entries between entry.m_id and entry.m_lastId... 
 925     eTTnode
->eventEntryTable
.Add(&entry
); 
 928 void wxEventHashTable::AllocEventTypeTable(size_t size
) 
 930     m_eventTypeTable 
= new EventTypeTablePointer
[size
]; 
 931     memset((void *)m_eventTypeTable
, 0, sizeof(EventTypeTablePointer
)*size
); 
 935 void wxEventHashTable::GrowEventTypeTable() 
 937     size_t oldSize 
= m_size
; 
 938     EventTypeTablePointer 
*oldEventTypeTable 
= m_eventTypeTable
; 
 940     // TODO: Search the most optimal grow sequence 
 941     AllocEventTypeTable(/* GetNextPrime(oldSize) */oldSize
*2+1); 
 943     for ( size_t i 
= 0; i 
< oldSize
; /* */ ) 
 945         EventTypeTablePointer  eTToldNode 
= oldEventTypeTable
[i
]; 
 948             EventTypeTablePointer 
*peTTnode 
= &m_eventTypeTable
[eTToldNode
->eventType 
% m_size
]; 
 949             EventTypeTablePointer  eTTnode 
= *peTTnode
; 
 951             // Check for collision, we don't want any. 
 954                 GrowEventTypeTable(); 
 955                 continue; // Don't increment the counter, 
 956                           // as we still need to add this element. 
 960                 // Get the old value and put it in the new table. 
 961                 *peTTnode 
= oldEventTypeTable
[i
]; 
 968     delete[] oldEventTypeTable
; 
 972 // ---------------------------------------------------------------------------- 
 974 // ---------------------------------------------------------------------------- 
 980 wxEvtHandler::wxEvtHandler() 
 982     m_nextHandler 
= (wxEvtHandler 
*) NULL
; 
 983     m_previousHandler 
= (wxEvtHandler 
*) NULL
; 
 985     m_dynamicEvents 
= (wxList 
*) NULL
; 
 986     m_pendingEvents 
= (wxList 
*) NULL
; 
 988 #  if !defined(__VISAGECPP__) 
 989     m_eventsLocker 
= new wxCriticalSection
; 
 992     // no client data (yet) 
 994     m_clientDataType 
= wxClientData_None
; 
 997 wxEvtHandler::~wxEvtHandler() 
 999     // Takes itself out of the list of handlers 
1000     if (m_previousHandler
) 
1001         m_previousHandler
->m_nextHandler 
= m_nextHandler
; 
1004         m_nextHandler
->m_previousHandler 
= m_previousHandler
; 
1006     if (m_dynamicEvents
) 
1008         wxList::iterator it 
= m_dynamicEvents
->begin(), 
1009                          en 
= m_dynamicEvents
->end(); 
1010         for (;it 
!= en
; ++it
) 
1012 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
1013             wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)*it
; 
1014 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
1015             wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)*it
; 
1016 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
1018             if (entry
->m_callbackUserData
) 
1019                 delete entry
->m_callbackUserData
; 
1022         delete m_dynamicEvents
; 
1025     if (m_pendingEvents
) 
1026         m_pendingEvents
->DeleteContents(true); 
1027     delete m_pendingEvents
; 
1030 #  if !defined(__VISAGECPP__) 
1031     delete m_eventsLocker
; 
1034     // Remove us from wxPendingEvents if necessary. 
1035     if(wxPendingEventsLocker
) 
1036         wxENTER_CRIT_SECT(*wxPendingEventsLocker
); 
1037     if ( wxPendingEvents 
) 
1039         // Delete all occurences of this from the list of pending events 
1040         while (wxPendingEvents
->DeleteObject(this)) { } // Do nothing 
1042     if(wxPendingEventsLocker
) 
1043         wxLEAVE_CRIT_SECT(*wxPendingEventsLocker
); 
1046     // we only delete object data, not untyped 
1047     if ( m_clientDataType 
== wxClientData_Object 
) 
1048         delete m_clientObject
; 
1053 bool wxEvtHandler::ProcessThreadEvent(wxEvent
& event
) 
1055     // check that we are really in a child thread 
1056     wxASSERT_MSG( !wxThread::IsMain(), 
1057                   wxT("use ProcessEvent() in main thread") ); 
1059     AddPendingEvent(event
); 
1064 void wxEvtHandler::ClearEventLocker() 
1066 #if !defined(__VISAGECPP__) 
1067     delete m_eventsLocker
; 
1068     m_eventsLocker 
= NULL
; 
1072 #endif // wxUSE_THREADS 
1074 void wxEvtHandler::AddPendingEvent(wxEvent
& event
) 
1076     // 1) Add event to list of pending events of this event handler 
1078     wxEvent 
*eventCopy 
= event
.Clone(); 
1080     // we must be able to copy the events here so the event class must 
1081     // implement Clone() properly instead of just providing a NULL stab for it 
1082     wxCHECK_RET( eventCopy
, 
1083                  _T("events of this type aren't supposed to be posted") ); 
1085     wxENTER_CRIT_SECT( Lock() ); 
1087     if ( !m_pendingEvents 
) 
1088       m_pendingEvents 
= new wxList
; 
1090     m_pendingEvents
->Append(eventCopy
); 
1092     wxLEAVE_CRIT_SECT( Lock() ); 
1094     // 2) Add this event handler to list of event handlers that 
1095     //    have pending events. 
1097     wxENTER_CRIT_SECT(*wxPendingEventsLocker
); 
1099     if ( !wxPendingEvents 
) 
1100         wxPendingEvents 
= new wxList
; 
1101     wxPendingEvents
->Append(this); 
1103     wxLEAVE_CRIT_SECT(*wxPendingEventsLocker
); 
1105     // 3) Inform the system that new pending events are somewhere, 
1106     //    and that these should be processed in idle time. 
1110 void wxEvtHandler::ProcessPendingEvents() 
1112     // this method is only called by wxApp if this handler does have pending 
1114     wxCHECK_RET( m_pendingEvents
, 
1115                  wxT("Please call wxApp::ProcessPendingEvents() instead") ); 
1117     wxENTER_CRIT_SECT( Lock() ); 
1119     // we leave the loop once we have processed all events that were present at 
1120     // the start of ProcessPendingEvents because otherwise we could get into 
1121     // infinite loop if the pending event handler execution resulted in another 
1122     // event being posted 
1123     size_t n 
= m_pendingEvents
->size(); 
1124     for ( wxList::compatibility_iterator node 
= m_pendingEvents
->GetFirst(); 
1126           node 
= m_pendingEvents
->GetFirst() ) 
1128         wxEvent 
*event 
= (wxEvent 
*)node
->GetData(); 
1130         // It's importan we remove event from list before processing it. 
1131         // Else a nested event loop, for example from a modal dialog, might 
1132         // process the same event again. 
1133         m_pendingEvents
->Erase(node
); 
1135         wxLEAVE_CRIT_SECT( Lock() ); 
1137         ProcessEvent(*event
); 
1140         wxENTER_CRIT_SECT( Lock() ); 
1146     wxLEAVE_CRIT_SECT( Lock() ); 
1153 wxEvtHandler::ProcessEventIfMatches(const wxEventTableEntryBase
& entry
, 
1154                                     wxEvtHandler 
*handler
, 
1157     int tableId1 
= entry
.m_id
, 
1158         tableId2 
= entry
.m_lastId
; 
1160     // match only if the event type is the same and the id is either -1 in 
1161     // the event table (meaning "any") or the event id matches the id 
1162     // specified in the event table either exactly or by falling into 
1163     // range between first and last 
1164     if ((tableId1 
== wxID_ANY
) || 
1165         (tableId2 
== wxID_ANY 
&& tableId1 
== event
.GetId()) || 
1166         (tableId2 
!= wxID_ANY 
&& 
1167          (event
.GetId() >= tableId1 
&& event
.GetId() <= tableId2
))) 
1170         event
.m_callbackUserData 
= entry
.m_callbackUserData
; 
1172 #if wxUSE_EXCEPTIONS 
1175             // call the handler via wxApp method which allows the user to catch 
1176             // any exceptions which may be thrown by any handler in the program 
1178             wxTheApp
->HandleEvent(handler
, (wxEventFunction
)entry
.m_fn
, event
); 
1181 #endif // wxUSE_EXCEPTIONS 
1183             // no need for an extra virtual function call 
1184             (handler
->*((wxEventFunction
) (entry
.m_fn
)))(event
); 
1187         if (!event
.GetSkipped()) 
1194 bool wxEvtHandler::TryParent(wxEvent
& event
) 
1196     if ( wxTheApp 
&& (this != wxTheApp
) ) 
1198         // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always 
1199         // swallow it. wxEVT_IDLE is sent explicitly to wxApp so it will be 
1200         // processed appropriately via SearchEventTable. 
1201         if ( event
.GetEventType() != wxEVT_IDLE 
) 
1203             if ( wxTheApp
->ProcessEvent(event
) ) 
1211 bool wxEvtHandler::ProcessEvent(wxEvent
& event
) 
1213     // allow the application to hook into event processing 
1216         int rc 
= wxTheApp
->FilterEvent(event
); 
1219             wxASSERT_MSG( rc 
== 1 || rc 
== 0, 
1220                           _T("unexpected wxApp::FilterEvent return value") ); 
1224         //else: proceed normally 
1227     // An event handler can be enabled or disabled 
1228     if ( GetEvtHandlerEnabled() ) 
1230         // if we have a validator, it has higher priority than our own event 
1232         if ( TryValidator(event
) ) 
1235         // Handle per-instance dynamic event tables first 
1236         if ( m_dynamicEvents 
&& SearchDynamicEventTable(event
) ) 
1239         // Then static per-class event tables 
1240         if ( GetEventHashTable().HandleEvent(event
, this) ) 
1244     // Try going down the event handler chain 
1245     if ( GetNextHandler() ) 
1247         if ( GetNextHandler()->ProcessEvent(event
) ) 
1251     // Finally propagate the event upwards the window chain and/or to the 
1252     // application object as necessary 
1253     return TryParent(event
); 
1257 bool wxEvtHandler::SearchEventTable(wxEventTable
& table
, wxEvent
& event
) 
1259     const wxEventType eventType 
= event
.GetEventType(); 
1260     for ( int i 
= 0; table
.entries
[i
].m_fn 
!= 0; i
++ ) 
1262         const wxEventTableEntry
& entry 
= table
.entries
[i
]; 
1263         if ( eventType 
== entry
.m_eventType 
) 
1265             if ( ProcessEventIfMatches(entry
, this, event
) ) 
1273 void wxEvtHandler::Connect( int id
, int lastId
, 
1275                             wxObjectEventFunction func
, 
1277                             wxEvtHandler
* eventSink 
) 
1279 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
1280     wxEventTableEntry 
*entry 
= new wxEventTableEntry
; 
1281     entry
->m_eventType 
= eventType
; 
1283     entry
->m_lastId 
= lastId
; 
1285     entry
->m_callbackUserData 
= userData
; 
1286 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
1287     wxDynamicEventTableEntry 
*entry 
= 
1288         new wxDynamicEventTableEntry(eventType
, id
, lastId
, func
, userData
, eventSink
); 
1289 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
1291     if (!m_dynamicEvents
) 
1292         m_dynamicEvents 
= new wxList
; 
1294     // Insert at the front of the list so most recent additions are found first 
1295     m_dynamicEvents
->Insert( (wxObject
*) entry 
); 
1298 bool wxEvtHandler::Disconnect( int id
, int lastId
, wxEventType eventType
, 
1299                   wxObjectEventFunction func
, 
1301                   wxEvtHandler
* eventSink 
) 
1303     if (!m_dynamicEvents
) 
1306     wxList::compatibility_iterator node 
= m_dynamicEvents
->GetFirst(); 
1309 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
1310             wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->GetData(); 
1311 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
1312             wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->GetData(); 
1313 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
1315         if ((entry
->m_id 
== id
) && 
1316             ((entry
->m_lastId 
== lastId
) || (lastId 
== wxID_ANY
)) && 
1317             ((entry
->m_eventType 
== eventType
) || (eventType 
== wxEVT_NULL
)) && 
1318             ((entry
->m_fn 
== func
) || (func 
== (wxObjectEventFunction
)NULL
)) && 
1319             ((entry
->m_eventSink 
== eventSink
) || (eventSink 
== (wxEvtHandler
*)NULL
)) && 
1320             ((entry
->m_callbackUserData 
== userData
) || (userData 
== (wxObject
*)NULL
))) 
1322             if (entry
->m_callbackUserData
) 
1323                 delete entry
->m_callbackUserData
; 
1324             m_dynamicEvents
->Erase( node 
); 
1328         node 
= node
->GetNext(); 
1333 bool wxEvtHandler::SearchDynamicEventTable( wxEvent
& event 
) 
1335     wxCHECK_MSG( m_dynamicEvents
, false, 
1336                  wxT("caller should check that we have dynamic events") ); 
1338     wxList::compatibility_iterator node 
= m_dynamicEvents
->GetFirst(); 
1341 #if WXWIN_COMPATIBILITY_EVENT_TYPES 
1342         wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->GetData(); 
1343 #else // !WXWIN_COMPATIBILITY_EVENT_TYPES 
1344         wxDynamicEventTableEntry 
*entry 
= (wxDynamicEventTableEntry
*)node
->GetData(); 
1345 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES/!WXWIN_COMPATIBILITY_EVENT_TYPES 
1347         // get next node before (maybe) calling the event handler as it could 
1348         // call Disconnect() invalidating the current node 
1349         node 
= node
->GetNext(); 
1351         if ((event
.GetEventType() == entry
->m_eventType
) && (entry
->m_fn 
!= 0)) 
1353             wxEvtHandler 
*handler 
= 
1354 #if !WXWIN_COMPATIBILITY_EVENT_TYPES 
1355                                     entry
->m_eventSink 
? entry
->m_eventSink
 
1360             if ( ProcessEventIfMatches(*entry
, handler
, event
) ) 
1370 void wxEvtHandler::DoSetClientObject( wxClientData 
*data 
) 
1372     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Void
, 
1373                   wxT("can't have both object and void client data") ); 
1375     if ( m_clientObject 
) 
1376         delete m_clientObject
; 
1378     m_clientObject 
= data
; 
1379     m_clientDataType 
= wxClientData_Object
; 
1382 wxClientData 
*wxEvtHandler::DoGetClientObject() const 
1384     // it's not an error to call GetClientObject() on a window which doesn't 
1385     // have client data at all - NULL will be returned 
1386     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Void
, 
1387                   wxT("this window doesn't have object client data") ); 
1389     return m_clientObject
; 
1392 void wxEvtHandler::DoSetClientData( void *data 
) 
1394     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Object
, 
1395                   wxT("can't have both object and void client data") ); 
1397     m_clientData 
= data
; 
1398     m_clientDataType 
= wxClientData_Void
; 
1401 void *wxEvtHandler::DoGetClientData() const 
1403     // it's not an error to call GetClientData() on a window which doesn't have 
1404     // client data at all - NULL will be returned 
1405     wxASSERT_MSG( m_clientDataType 
!= wxClientData_Object
, 
1406                   wxT("this window doesn't have void client data") ); 
1408     return m_clientData
; 
1411 #endif // wxUSE_BASE 
1415 // Find a window with the focus, that is also a descendant of the given window. 
1416 // This is used to determine the window to initially send commands to. 
1417 wxWindow
* wxFindFocusDescendant(wxWindow
* ancestor
) 
1419     // Process events starting with the window with the focus, if any. 
1420     wxWindow
* focusWin 
= wxWindow::FindFocus(); 
1421     wxWindow
* win 
= focusWin
; 
1423     // Check if this is a descendant of this frame. 
1424     // If not, win will be set to NULL. 
1427         if (win 
== ancestor
) 
1430             win 
= win
->GetParent(); 
1432     if (win 
== (wxWindow
*) NULL
) 
1433         focusWin 
= (wxWindow
*) NULL
;