]> git.saurik.com Git - wxWidgets.git/blob - src/common/event.cpp
Added wxEVT_SCROLL[WIN]_THUMBRELEASE
[wxWidgets.git] / src / common / event.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: event.cpp
3 // Purpose: Event classes
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "event.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/defs.h"
33 #include "wx/app.h"
34 #include "wx/list.h"
35
36 #if wxUSE_GUI
37 #include "wx/control.h"
38 #include "wx/utils.h"
39 #include "wx/dc.h"
40 #endif // wxUSE_GUI
41 #endif
42
43 #include "wx/event.h"
44
45 #if wxUSE_GUI
46 #include "wx/validate.h"
47 #endif // wxUSE_GUI
48
49
50 #if defined(__VISAGECPP__) && __IBMCPP__ >= 400
51 // must define these static for VA or else you get multiply defined symbols everywhere
52 const wxEventType wxEVT_NULL = 0;
53 const wxEventType wxEVT_FIRST = 10000;
54
55 const wxEventType wxEVT_COMMAND_BUTTON_CLICKED = wxEVT_FIRST + 1;
56 const wxEventType wxEVT_COMMAND_CHECKBOX_CLICKED = wxEVT_FIRST + 2;
57 const wxEventType wxEVT_COMMAND_CHOICE_SELECTED = wxEVT_FIRST + 3;
58 const wxEventType wxEVT_COMMAND_LISTBOX_SELECTED = wxEVT_FIRST + 4;
59 const wxEventType wxEVT_COMMAND_LISTBOX_DOUBLECLICKED = wxEVT_FIRST + 5;
60 const wxEventType wxEVT_COMMAND_CHECKLISTBOX_TOGGLED = wxEVT_FIRST + 6;
61 const wxEventType wxEVT_COMMAND_TEXT_UPDATED = wxEVT_FIRST + 7;
62 const wxEventType wxEVT_COMMAND_TEXT_ENTER = wxEVT_FIRST + 8;
63 const wxEventType wxEVT_COMMAND_MENU_SELECTED = wxEVT_FIRST + 9;
64 const wxEventType wxEVT_COMMAND_TOOL_CLICKED = wxEVT_COMMAND_MENU_SELECTED;
65 const wxEventType wxEVT_COMMAND_SLIDER_UPDATED = wxEVT_FIRST + 10;
66 const wxEventType wxEVT_COMMAND_RADIOBOX_SELECTED = wxEVT_FIRST + 11;
67 const wxEventType wxEVT_COMMAND_RADIOBUTTON_SELECTED = wxEVT_FIRST + 12;
68 //const wxEventType wxEVT_COMMAND_SCROLLBAR_UPDATED is now obsolete since we use wxEVT_SCROLL... events
69 const wxEventType wxEVT_COMMAND_SCROLLBAR_UPDATED = wxEVT_FIRST + 13;
70 const wxEventType wxEVT_COMMAND_VLBOX_SELECTED = wxEVT_FIRST + 14;
71 const wxEventType wxEVT_COMMAND_COMBOBOX_SELECTED = wxEVT_FIRST + 15;
72 const wxEventType wxEVT_COMMAND_TOOL_RCLICKED = wxEVT_FIRST + 16;
73 const wxEventType wxEVT_COMMAND_TOOL_ENTER = wxEVT_FIRST + 17;
74 const wxEventType wxEVT_COMMAND_SPINCTRL_UPDATED = wxEVT_FIRST + 18;
75
76 /* Sockets send events, too */
77 const wxEventType wxEVT_SOCKET = wxEVT_FIRST + 50;
78 const wxEventType wxEVT_TIMER = wxEVT_FIRST + 80;
79
80 /* Mouse event types */
81 const wxEventType wxEVT_LEFT_DOWN = wxEVT_FIRST + 100;
82 const wxEventType wxEVT_LEFT_UP = wxEVT_FIRST + 101;
83 const wxEventType wxEVT_MIDDLE_DOWN = wxEVT_FIRST + 102;
84 const wxEventType wxEVT_MIDDLE_UP = wxEVT_FIRST + 103;
85 const wxEventType wxEVT_RIGHT_DOWN = wxEVT_FIRST + 104;
86 const wxEventType wxEVT_RIGHT_UP = wxEVT_FIRST + 105;
87 const wxEventType wxEVT_MOTION = wxEVT_FIRST + 106;
88 const wxEventType wxEVT_ENTER_WINDOW = wxEVT_FIRST + 107;
89 const wxEventType wxEVT_LEAVE_WINDOW = wxEVT_FIRST + 108;
90 const wxEventType wxEVT_LEFT_DCLICK = wxEVT_FIRST + 109;
91 const wxEventType wxEVT_MIDDLE_DCLICK = wxEVT_FIRST + 110;
92 const wxEventType wxEVT_RIGHT_DCLICK = wxEVT_FIRST + 111;
93 const wxEventType wxEVT_SET_FOCUS = wxEVT_FIRST + 112;
94 const wxEventType wxEVT_KILL_FOCUS = wxEVT_FIRST + 113;
95
96 /* Non-client mouse events */
97 const wxEventType wxEVT_NC_LEFT_DOWN = wxEVT_FIRST + 200;
98 const wxEventType wxEVT_NC_LEFT_UP = wxEVT_FIRST + 201;
99 const wxEventType wxEVT_NC_MIDDLE_DOWN = wxEVT_FIRST + 202;
100 const wxEventType wxEVT_NC_MIDDLE_UP = wxEVT_FIRST + 203;
101 const wxEventType wxEVT_NC_RIGHT_DOWN = wxEVT_FIRST + 204;
102 const wxEventType wxEVT_NC_RIGHT_UP = wxEVT_FIRST + 205;
103 const wxEventType wxEVT_NC_MOTION = wxEVT_FIRST + 206;
104 const wxEventType wxEVT_NC_ENTER_WINDOW = wxEVT_FIRST + 207;
105 const wxEventType wxEVT_NC_LEAVE_WINDOW = wxEVT_FIRST + 208;
106 const wxEventType wxEVT_NC_LEFT_DCLICK = wxEVT_FIRST + 209;
107 const wxEventType wxEVT_NC_MIDDLE_DCLICK = wxEVT_FIRST + 210;
108 const wxEventType wxEVT_NC_RIGHT_DCLICK = wxEVT_FIRST + 211;
109
110 /* Character input event type */
111 const wxEventType wxEVT_CHAR = wxEVT_FIRST + 212;
112 const wxEventType wxEVT_CHAR_HOOK = wxEVT_FIRST + 213;
113 const wxEventType wxEVT_NAVIGATION_KEY = wxEVT_FIRST + 214;
114 const wxEventType wxEVT_KEY_DOWN = wxEVT_FIRST + 215;
115 const wxEventType wxEVT_KEY_UP = wxEVT_FIRST + 216;
116
117 /*
118 * wxScrollbar and wxSlider event identifiers
119 */
120 const wxEventType wxEVT_SCROLL_TOP = wxEVT_FIRST + 300;
121 const wxEventType wxEVT_SCROLL_BOTTOM = wxEVT_FIRST + 301;
122 const wxEventType wxEVT_SCROLL_LINEUP = wxEVT_FIRST + 302;
123 const wxEventType wxEVT_SCROLL_LINEDOWN = wxEVT_FIRST + 303;
124 const wxEventType wxEVT_SCROLL_PAGEUP = wxEVT_FIRST + 304;
125 const wxEventType wxEVT_SCROLL_PAGEDOWN = wxEVT_FIRST + 305;
126 const wxEventType wxEVT_SCROLL_THUMBTRACK = wxEVT_FIRST + 306;
127 const wxEventType wxEVT_SCROLL_THUMBRELEASE = wxEVT_FIRST + 307;
128
129 /*
130 * Scroll events from wxWindow
131 */
132 const wxEventType wxEVT_SCROLLWIN_TOP = wxEVT_FIRST + 320;
133 const wxEventType wxEVT_SCROLLWIN_BOTTOM = wxEVT_FIRST + 321;
134 const wxEventType wxEVT_SCROLLWIN_LINEUP = wxEVT_FIRST + 322;
135 const wxEventType wxEVT_SCROLLWIN_LINEDOWN = wxEVT_FIRST + 323;
136 const wxEventType wxEVT_SCROLLWIN_PAGEUP = wxEVT_FIRST + 324;
137 const wxEventType wxEVT_SCROLLWIN_PAGEDOWN = wxEVT_FIRST + 325;
138 const wxEventType wxEVT_SCROLLWIN_THUMBTRACK = wxEVT_FIRST + 326;
139 const wxEventType wxEVT_SCROLLWIN_THUMBRELEASE = wxEVT_FIRST + 327;
140
141 /*
142 * System events
143 */
144 const wxEventType wxEVT_SIZE = wxEVT_FIRST + 400;
145 const wxEventType wxEVT_MOVE = wxEVT_FIRST + 401;
146 const wxEventType wxEVT_CLOSE_WINDOW = wxEVT_FIRST + 402;
147 const wxEventType wxEVT_END_SESSION = wxEVT_FIRST + 403;
148 const wxEventType wxEVT_QUERY_END_SESSION = wxEVT_FIRST + 404;
149 const wxEventType wxEVT_ACTIVATE_APP = wxEVT_FIRST + 405;
150 const wxEventType wxEVT_POWER = wxEVT_FIRST + 406;
151 const wxEventType wxEVT_ACTIVATE = wxEVT_FIRST + 409;
152 const wxEventType wxEVT_CREATE = wxEVT_FIRST + 410;
153 const wxEventType wxEVT_DESTROY = wxEVT_FIRST + 411;
154 const wxEventType wxEVT_SHOW = wxEVT_FIRST + 412;
155 const wxEventType wxEVT_ICONIZE = wxEVT_FIRST + 413;
156 const wxEventType wxEVT_MAXIMIZE = wxEVT_FIRST + 414;
157 const wxEventType wxEVT_MOUSE_CAPTURE_CHANGED = wxEVT_FIRST + 415;
158 const wxEventType wxEVT_PAINT = wxEVT_FIRST + 416;
159 const wxEventType wxEVT_ERASE_BACKGROUND = wxEVT_FIRST + 417;
160 const wxEventType wxEVT_NC_PAINT = wxEVT_FIRST + 418;
161 const wxEventType wxEVT_PAINT_ICON = wxEVT_FIRST + 419;
162 const wxEventType wxEVT_MENU_CHAR = wxEVT_FIRST + 420;
163 const wxEventType wxEVT_MENU_INIT = wxEVT_FIRST + 421;
164 const wxEventType wxEVT_MENU_HIGHLIGHT = wxEVT_FIRST + 422;
165 const wxEventType wxEVT_POPUP_MENU_INIT = wxEVT_FIRST + 423;
166 const wxEventType wxEVT_CONTEXT_MENU = wxEVT_FIRST + 424;
167 const wxEventType wxEVT_SYS_COLOUR_CHANGED = wxEVT_FIRST + 425;
168 const wxEventType wxEVT_SETTING_CHANGED = wxEVT_FIRST + 426;
169 const wxEventType wxEVT_QUERY_NEW_PALETTE = wxEVT_FIRST + 427;
170 const wxEventType wxEVT_PALETTE_CHANGED = wxEVT_FIRST + 428;
171 const wxEventType wxEVT_JOY_BUTTON_DOWN = wxEVT_FIRST + 429;
172 const wxEventType wxEVT_JOY_BUTTON_UP = wxEVT_FIRST + 430;
173 const wxEventType wxEVT_JOY_MOVE = wxEVT_FIRST + 431;
174 const wxEventType wxEVT_JOY_ZMOVE = wxEVT_FIRST + 432;
175 const wxEventType wxEVT_DROP_FILES = wxEVT_FIRST + 433;
176 const wxEventType wxEVT_DRAW_ITEM = wxEVT_FIRST + 434;
177 const wxEventType wxEVT_MEASURE_ITEM = wxEVT_FIRST + 435;
178 const wxEventType wxEVT_COMPARE_ITEM = wxEVT_FIRST + 436;
179 const wxEventType wxEVT_INIT_DIALOG = wxEVT_FIRST + 437;
180 const wxEventType wxEVT_IDLE = wxEVT_FIRST + 438;
181 const wxEventType wxEVT_UPDATE_UI = wxEVT_FIRST + 439;
182
183 /* System misc. */
184 const wxEventType wxEVT_END_PROCESS = wxEVT_FIRST + 440;
185
186 /* Dial up events */
187 const wxEventType wxEVT_DIALUP_CONNECTED = wxEVT_FIRST + 450;
188 const wxEventType wxEVT_DIALUP_DISCONNECTED = wxEVT_FIRST + 451;
189
190 /* Generic command events */
191 /* Note: a click is a higher-level event than button down/up */
192 const wxEventType wxEVT_COMMAND_LEFT_CLICK = wxEVT_FIRST + 500;
193 const wxEventType wxEVT_COMMAND_LEFT_DCLICK = wxEVT_FIRST + 501;
194 const wxEventType wxEVT_COMMAND_RIGHT_CLICK = wxEVT_FIRST + 502;
195 const wxEventType wxEVT_COMMAND_RIGHT_DCLICK = wxEVT_FIRST + 503;
196 const wxEventType wxEVT_COMMAND_SET_FOCUS = wxEVT_FIRST + 504;
197 const wxEventType wxEVT_COMMAND_KILL_FOCUS = wxEVT_FIRST + 505;
198 const wxEventType wxEVT_COMMAND_ENTER = wxEVT_FIRST + 506;
199
200 /* Tree control event types */
201 const wxEventType wxEVT_COMMAND_TREE_BEGIN_DRAG = wxEVT_FIRST + 600;
202 const wxEventType wxEVT_COMMAND_TREE_BEGIN_RDRAG = wxEVT_FIRST + 601;
203 const wxEventType wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT = wxEVT_FIRST + 602;
204 const wxEventType wxEVT_COMMAND_TREE_END_LABEL_EDIT = wxEVT_FIRST + 603;
205 const wxEventType wxEVT_COMMAND_TREE_DELETE_ITEM = wxEVT_FIRST + 604;
206 const wxEventType wxEVT_COMMAND_TREE_GET_INFO = wxEVT_FIRST + 605;
207 const wxEventType wxEVT_COMMAND_TREE_SET_INFO = wxEVT_FIRST + 606;
208 const wxEventType wxEVT_COMMAND_TREE_ITEM_EXPANDED = wxEVT_FIRST + 607;
209 const wxEventType wxEVT_COMMAND_TREE_ITEM_EXPANDING = wxEVT_FIRST + 608;
210 const wxEventType wxEVT_COMMAND_TREE_ITEM_COLLAPSED = wxEVT_FIRST + 609;
211 const wxEventType wxEVT_COMMAND_TREE_ITEM_COLLAPSING = wxEVT_FIRST + 610;
212 const wxEventType wxEVT_COMMAND_TREE_SEL_CHANGED = wxEVT_FIRST + 611;
213 const wxEventType wxEVT_COMMAND_TREE_SEL_CHANGING = wxEVT_FIRST + 612;
214 const wxEventType wxEVT_COMMAND_TREE_KEY_DOWN = wxEVT_FIRST + 613;
215 const wxEventType wxEVT_COMMAND_TREE_ITEM_ACTIVATED = wxEVT_FIRST + 614;
216 const wxEventType wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK = wxEVT_FIRST + 615;
217 const wxEventType wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK = wxEVT_FIRST + 616;
218
219 /* List control event types */
220 const wxEventType wxEVT_COMMAND_LIST_BEGIN_DRAG = wxEVT_FIRST + 700;
221 const wxEventType wxEVT_COMMAND_LIST_BEGIN_RDRAG = wxEVT_FIRST + 701;
222 const wxEventType wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT = wxEVT_FIRST + 702;
223 const wxEventType wxEVT_COMMAND_LIST_END_LABEL_EDIT = wxEVT_FIRST + 703;
224 const wxEventType wxEVT_COMMAND_LIST_DELETE_ITEM = wxEVT_FIRST + 704;
225 const wxEventType wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS = wxEVT_FIRST + 705;
226 const wxEventType wxEVT_COMMAND_LIST_GET_INFO = wxEVT_FIRST + 706;
227 const wxEventType wxEVT_COMMAND_LIST_SET_INFO = wxEVT_FIRST + 707;
228 const wxEventType wxEVT_COMMAND_LIST_ITEM_SELECTED = wxEVT_FIRST + 708;
229 const wxEventType wxEVT_COMMAND_LIST_ITEM_DESELECTED = wxEVT_FIRST + 709;
230 const wxEventType wxEVT_COMMAND_LIST_KEY_DOWN = wxEVT_FIRST + 710;
231 const wxEventType wxEVT_COMMAND_LIST_INSERT_ITEM = wxEVT_FIRST + 711;
232 const wxEventType wxEVT_COMMAND_LIST_COL_CLICK = wxEVT_FIRST + 712;
233 const wxEventType wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK = wxEVT_FIRST + 713;
234 const wxEventType wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK = wxEVT_FIRST + 714;
235 const wxEventType wxEVT_COMMAND_LIST_ITEM_ACTIVATED = wxEVT_FIRST + 715;
236
237 /* Tab and notebook control event types */
238 const wxEventType wxEVT_COMMAND_TAB_SEL_CHANGED = wxEVT_FIRST + 800;
239 const wxEventType wxEVT_COMMAND_TAB_SEL_CHANGING = wxEVT_FIRST + 801;
240 const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED = wxEVT_FIRST + 802;
241 const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING = wxEVT_FIRST + 803;
242
243 /* Splitter events */
244 const wxEventType wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED = wxEVT_FIRST + 850;
245 const wxEventType wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING = wxEVT_FIRST + 851;
246 const wxEventType wxEVT_COMMAND_SPLITTER_DOUBLECLICKED = wxEVT_FIRST + 852;
247 const wxEventType wxEVT_COMMAND_SPLITTER_UNSPLIT = wxEVT_FIRST + 853;
248
249 /* Wizard events */
250 const wxEventType wxEVT_WIZARD_PAGE_CHANGED = wxEVT_FIRST + 900;
251 const wxEventType wxEVT_WIZARD_PAGE_CHANGING = wxEVT_FIRST + 901;
252 const wxEventType wxEVT_WIZARD_CANCEL = wxEVT_FIRST + 902;
253
254 /* Calendar events */
255 const wxEventType wxEVT_CALENDAR_SEL_CHANGED = wxEVT_FIRST + 950;
256 const wxEventType wxEVT_CALENDAR_DAY_CHANGED = wxEVT_FIRST + 951;
257 const wxEventType wxEVT_CALENDAR_MONTH_CHANGED = wxEVT_FIRST + 952;
258 const wxEventType wxEVT_CALENDAR_YEAR_CHANGED = wxEVT_FIRST + 953;
259 const wxEventType wxEVT_CALENDAR_DOUBLECLICKED = wxEVT_FIRST + 954;
260 const wxEventType wxEVT_CALENDAR_WEEKDAY_CLICKED = wxEVT_FIRST + 955;
261
262 const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000;
263 #endif
264
265 // ----------------------------------------------------------------------------
266 // wxWin macros
267 // ----------------------------------------------------------------------------
268
269 IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
270 IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
271 IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
272
273 #if wxUSE_GUI
274 IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
275 IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent, wxCommandEvent)
276 IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
277 IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent, wxEvent)
278 IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent, wxEvent)
279 IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent, wxEvent)
280 IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent, wxEvent)
281 IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent, wxEvent)
282 IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent, wxEvent)
283 IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent, wxEvent)
284 IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent, wxEvent)
285 IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent, wxEvent)
286 IMPLEMENT_DYNAMIC_CLASS(wxShowEvent, wxEvent)
287 IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent, wxEvent)
288 IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent, wxEvent)
289 IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent, wxEvent)
290 IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent, wxEvent)
291 IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent, wxEvent)
292 IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent, wxEvent)
293 IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent, wxEvent)
294 IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent)
295 IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxCommandEvent)
296 IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent, wxCommandEvent)
297 IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent, wxEvent)
298 IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent, wxEvent)
299 IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent, wxEvent)
300 IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent, wxEvent)
301 #endif // wxUSE_GUI
302
303 const wxEventTable *wxEvtHandler::GetEventTable() const
304 { return &wxEvtHandler::sm_eventTable; }
305
306 const wxEventTable wxEvtHandler::sm_eventTable =
307 { (const wxEventTable *)NULL, &wxEvtHandler::sm_eventTableEntries[0] };
308
309 const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] =
310 { { 0, 0, 0, (wxObjectEventFunction) NULL, (wxObject*) NULL } };
311
312
313 // ----------------------------------------------------------------------------
314 // global variables
315 // ----------------------------------------------------------------------------
316
317 // To put pending event handlers
318 wxList *wxPendingEvents = (wxList *)NULL;
319
320 #if wxUSE_THREADS
321 // protects wxPendingEvents list
322 wxCriticalSection *wxPendingEventsLocker = (wxCriticalSection *)NULL;
323 #endif
324
325 // ============================================================================
326 // implementation
327 // ============================================================================
328
329 // ----------------------------------------------------------------------------
330 // wxEvent
331 // ----------------------------------------------------------------------------
332
333 /*
334 * General wxWindows events, covering
335 * all interesting things that might happen (button clicking, resizing,
336 * setting text in widgets, etc.).
337 *
338 * For each completely new event type, derive a new event class.
339 *
340 */
341
342 wxEvent::wxEvent(int theId)
343 {
344 m_eventType = wxEVT_NULL;
345 m_eventObject = (wxObject *) NULL;
346 m_timeStamp = 0;
347 m_id = theId;
348 m_skipped = FALSE;
349 m_callbackUserData = (wxObject *) NULL;
350 m_isCommandEvent = FALSE;
351 }
352
353 void wxEvent::CopyObject(wxObject& object_dest) const
354 {
355 wxEvent *obj = (wxEvent *)&object_dest;
356 wxObject::CopyObject(object_dest);
357
358 obj->m_eventType = m_eventType;
359 obj->m_eventObject = m_eventObject;
360 obj->m_timeStamp = m_timeStamp;
361 obj->m_id = m_id;
362 obj->m_skipped = m_skipped;
363 obj->m_callbackUserData = m_callbackUserData;
364 obj->m_isCommandEvent = m_isCommandEvent;
365 }
366
367 #if wxUSE_GUI
368
369 /*
370 * Command events
371 *
372 */
373
374 wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId)
375 {
376 m_eventType = commandType;
377 m_clientData = (char *) NULL;
378 m_clientObject = (wxClientData *) NULL;
379 m_extraLong = 0;
380 m_commandInt = 0;
381 m_id = theId;
382 m_commandString = wxEmptyString;
383 m_isCommandEvent = TRUE;
384 }
385
386 void wxCommandEvent::CopyObject(wxObject& obj_d) const
387 {
388 wxCommandEvent *obj = (wxCommandEvent *)&obj_d;
389
390 wxEvent::CopyObject(obj_d);
391
392 obj->m_clientData = m_clientData;
393 obj->m_clientObject = m_clientObject;
394 obj->m_extraLong = m_extraLong;
395 obj->m_commandInt = m_commandInt;
396 obj->m_commandString = m_commandString;
397 }
398
399 /*
400 * Notify events
401 */
402
403 void wxNotifyEvent::CopyObject(wxObject& obj_d) const
404 {
405 wxNotifyEvent *obj = (wxNotifyEvent *)&obj_d;
406
407 wxEvent::CopyObject(obj_d);
408
409 if (!m_bAllow) obj->Veto();
410 }
411
412 /*
413 * Scroll events
414 */
415
416 wxScrollEvent::wxScrollEvent(wxEventType commandType,
417 int id,
418 int pos,
419 int orient)
420 : wxCommandEvent(commandType, id)
421 {
422 m_extraLong = orient;
423 m_commandInt = pos;
424 }
425
426 /*
427 * ScrollWin events
428 */
429
430 wxScrollWinEvent::wxScrollWinEvent(wxEventType commandType,
431 int pos,
432 int orient)
433 {
434 m_eventType = commandType;
435 m_extraLong = orient;
436 m_commandInt = pos;
437 }
438
439 void wxScrollWinEvent::CopyObject(wxObject& obj_d) const
440 {
441 wxScrollWinEvent *obj = (wxScrollWinEvent*)&obj_d;
442
443 wxEvent::CopyObject(obj_d);
444
445 obj->m_extraLong = m_extraLong;
446 obj->m_commandInt = m_commandInt;
447 }
448
449 /*
450 * Mouse events
451 *
452 */
453
454 wxMouseEvent::wxMouseEvent(wxEventType commandType)
455 {
456 m_eventType = commandType;
457 m_metaDown = FALSE;
458 m_altDown = FALSE;
459 m_controlDown = FALSE;
460 m_shiftDown = FALSE;
461 m_leftDown = FALSE;
462 m_rightDown = FALSE;
463 m_middleDown = FALSE;
464 m_x = 0;
465 m_y = 0;
466 }
467
468 void wxMouseEvent::CopyObject(wxObject& obj_d) const
469 {
470 wxMouseEvent *obj = (wxMouseEvent *)&obj_d;
471
472 wxEvent::CopyObject(obj_d);
473
474 obj->m_metaDown = m_metaDown;
475 obj->m_altDown = m_altDown;
476 obj->m_controlDown = m_controlDown;
477 obj->m_shiftDown = m_shiftDown;
478 obj->m_leftDown = m_leftDown;
479 obj->m_rightDown = m_rightDown;
480 obj->m_middleDown = m_middleDown;
481 obj->m_x = m_x;
482 obj->m_y = m_y;
483 }
484
485 // True if was a button dclick event (1 = left, 2 = middle, 3 = right)
486 // or any button dclick event (but = -1)
487 bool wxMouseEvent::ButtonDClick(int but) const
488 {
489 switch (but)
490 {
491 case -1:
492 return (LeftDClick() || MiddleDClick() || RightDClick());
493 case 1:
494 return LeftDClick();
495 case 2:
496 return MiddleDClick();
497 case 3:
498 return RightDClick();
499 default:
500 wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDClick"));
501 }
502
503 return FALSE;
504 }
505
506 // True if was a button down event (1 = left, 2 = middle, 3 = right)
507 // or any button down event (but = -1)
508 bool wxMouseEvent::ButtonDown(int but) const
509 {
510 switch (but)
511 {
512 case -1:
513 return (LeftDown() || MiddleDown() || RightDown());
514 case 1:
515 return LeftDown();
516 case 2:
517 return MiddleDown();
518 case 3:
519 return RightDown();
520 default:
521 wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonDown"));
522 }
523
524 return FALSE;
525 }
526
527 // True if was a button up event (1 = left, 2 = middle, 3 = right)
528 // or any button up event (but = -1)
529 bool wxMouseEvent::ButtonUp(int but) const
530 {
531 switch (but) {
532 case -1:
533 return (LeftUp() || MiddleUp() || RightUp());
534 case 1:
535 return LeftUp();
536 case 2:
537 return MiddleUp();
538 case 3:
539 return RightUp();
540 default:
541 wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonUp"));
542 }
543
544 return FALSE;
545 }
546
547 // True if the given button is currently changing state
548 bool wxMouseEvent::Button(int but) const
549 {
550 switch (but) {
551 case -1:
552 return (ButtonUp(-1) || ButtonDown(-1) || ButtonDClick(-1));
553 case 1:
554 return (LeftDown() || LeftUp() || LeftDClick());
555 case 2:
556 return (MiddleDown() || MiddleUp() || MiddleDClick());
557 case 3:
558 return (RightDown() || RightUp() || RightDClick());
559 default:
560 wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::Button"));
561 }
562
563 return FALSE;
564 }
565
566 bool wxMouseEvent::ButtonIsDown(int but) const
567 {
568 switch (but) {
569 case -1:
570 return (LeftIsDown() || MiddleIsDown() || RightIsDown());
571 case 1:
572 return LeftIsDown();
573 case 2:
574 return MiddleIsDown();
575 case 3:
576 return RightIsDown();
577 default:
578 wxFAIL_MSG(wxT("invalid parameter in wxMouseEvent::ButtonIsDown"));
579 }
580
581 return FALSE;
582 }
583
584 // Find the logical position of the event given the DC
585 wxPoint wxMouseEvent::GetLogicalPosition(const wxDC& dc) const
586 {
587 wxPoint pt(dc.DeviceToLogicalX(m_x), dc.DeviceToLogicalY(m_y));
588 return pt;
589 }
590
591
592 /*
593 * Keyboard events
594 *
595 */
596
597 wxKeyEvent::wxKeyEvent(wxEventType type)
598 {
599 m_eventType = type;
600 m_shiftDown = FALSE;
601 m_controlDown = FALSE;
602 m_metaDown = FALSE;
603 m_altDown = FALSE;
604 m_keyCode = 0;
605 m_scanCode = 0;
606 }
607
608 void wxKeyEvent::CopyObject(wxObject& obj_d) const
609 {
610 wxKeyEvent *obj = (wxKeyEvent *)&obj_d;
611 wxEvent::CopyObject(obj_d);
612
613 obj->m_x = m_x;
614 obj->m_y = m_y;
615 obj->m_keyCode = m_keyCode;
616
617 obj->m_shiftDown = m_shiftDown;
618 obj->m_controlDown = m_controlDown;
619 obj->m_metaDown = m_metaDown;
620 obj->m_altDown = m_altDown;
621 obj->m_keyCode = m_keyCode;
622 }
623
624
625 /*
626 * Misc events
627 */
628
629 void wxSizeEvent::CopyObject(wxObject& obj_d) const
630 {
631 wxSizeEvent *obj = (wxSizeEvent *)&obj_d;
632 wxEvent::CopyObject(obj_d);
633
634 obj->m_size = m_size;
635 }
636
637 void wxMoveEvent::CopyObject(wxObject& obj_d) const
638 {
639 wxMoveEvent *obj = (wxMoveEvent *)&obj_d;
640 wxEvent::CopyObject(obj_d);
641
642 obj->m_pos = m_pos;
643 }
644
645 void wxEraseEvent::CopyObject(wxObject& obj_d) const
646 {
647 wxEraseEvent *obj = (wxEraseEvent *)&obj_d;
648 wxEvent::CopyObject(obj_d);
649
650 obj->m_dc = m_dc;
651 }
652
653 void wxActivateEvent::CopyObject(wxObject& obj_d) const
654 {
655 wxActivateEvent *obj = (wxActivateEvent *)&obj_d;
656 wxEvent::CopyObject(obj_d);
657
658 obj->m_active = m_active;
659 }
660
661 void wxMenuEvent::CopyObject(wxObject& obj_d) const
662 {
663 wxMenuEvent *obj = (wxMenuEvent *)&obj_d;
664 wxEvent::CopyObject(obj_d);
665
666 obj->m_menuId = m_menuId;
667 }
668
669 void wxCloseEvent::CopyObject(wxObject& obj_d) const
670 {
671 wxCloseEvent *obj = (wxCloseEvent *)&obj_d;
672 wxEvent::CopyObject(obj_d);
673
674 obj->m_loggingOff = m_loggingOff;
675 obj->m_veto = m_veto;
676 #if WXWIN_COMPATIBILITY
677 obj->m_force = m_force;
678 #endif
679 obj->m_canVeto = m_canVeto;
680 }
681
682 void wxShowEvent::CopyObject(wxObject& obj_d) const
683 {
684 wxShowEvent *obj = (wxShowEvent *)&obj_d;
685 wxEvent::CopyObject(obj_d);
686
687 obj->m_show = m_show;
688 }
689
690 void wxJoystickEvent::CopyObject(wxObject& obj_d) const
691 {
692 wxJoystickEvent *obj = (wxJoystickEvent *)&obj_d;
693 wxEvent::CopyObject(obj_d);
694
695 obj->m_pos = m_pos;
696 obj->m_zPosition = m_zPosition;
697 obj->m_buttonChange = m_buttonChange;
698 obj->m_buttonState = m_buttonState;
699 obj->m_joyStick = m_joyStick;
700 }
701
702 void wxDropFilesEvent::CopyObject(wxObject& obj_d) const
703 {
704 wxDropFilesEvent *obj = (wxDropFilesEvent *)&obj_d;
705 wxEvent::CopyObject(obj_d);
706
707 obj->m_noFiles = m_noFiles;
708 obj->m_pos = m_pos;
709 // TODO: Problem with obj->m_files. It should be deallocated by the
710 // destructor of the event.
711 }
712
713 void wxUpdateUIEvent::CopyObject(wxObject &obj_d) const
714 {
715 wxUpdateUIEvent *obj = (wxUpdateUIEvent *)&obj_d;
716 wxEvent::CopyObject(obj_d);
717
718 obj->m_checked = m_checked;
719 obj->m_enabled = m_enabled;
720 obj->m_text = m_text;
721 obj->m_setText = m_setText;
722 obj->m_setChecked = m_setChecked;
723 obj->m_setEnabled = m_setEnabled;
724 }
725
726 void wxPaletteChangedEvent::CopyObject(wxObject &obj_d) const
727 {
728 wxPaletteChangedEvent *obj = (wxPaletteChangedEvent *)&obj_d;
729 wxEvent::CopyObject(obj_d);
730
731 obj->m_changedWindow = m_changedWindow;
732 }
733
734 void wxQueryNewPaletteEvent::CopyObject(wxObject& obj_d) const
735 {
736 wxQueryNewPaletteEvent *obj = (wxQueryNewPaletteEvent *)&obj_d;
737 wxEvent::CopyObject(obj_d);
738
739 obj->m_paletteRealized = m_paletteRealized;
740 }
741
742 wxWindowCreateEvent::wxWindowCreateEvent(wxWindow *win)
743 : wxEvent()
744 {
745 SetEventType(wxEVT_CREATE);
746 SetEventObject(win);
747 }
748
749 wxWindowDestroyEvent::wxWindowDestroyEvent(wxWindow *win)
750 : wxEvent()
751 {
752 SetEventType(wxEVT_DESTROY);
753 SetEventObject(win);
754 }
755
756 #endif // wxUSE_GUI
757
758 void wxIdleEvent::CopyObject(wxObject& obj_d) const
759 {
760 wxIdleEvent *obj = (wxIdleEvent *)&obj_d;
761 wxEvent::CopyObject(obj_d);
762
763 obj->m_requestMore = m_requestMore;
764 }
765
766 /*
767 * Event handler
768 */
769
770 wxEvtHandler::wxEvtHandler()
771 {
772 m_nextHandler = (wxEvtHandler *) NULL;
773 m_previousHandler = (wxEvtHandler *) NULL;
774 m_enabled = TRUE;
775 m_dynamicEvents = (wxList *) NULL;
776 m_isWindow = FALSE;
777 m_pendingEvents = (wxList *) NULL;
778 #if wxUSE_THREADS
779 # if !defined(__VISAGECPP__)
780 m_eventsLocker = new wxCriticalSection;
781 # endif
782 #endif
783 }
784
785 wxEvtHandler::~wxEvtHandler()
786 {
787 // Takes itself out of the list of handlers
788 if (m_previousHandler)
789 m_previousHandler->m_nextHandler = m_nextHandler;
790
791 if (m_nextHandler)
792 m_nextHandler->m_previousHandler = m_previousHandler;
793
794 if (m_dynamicEvents)
795 {
796 wxNode *node = m_dynamicEvents->First();
797 while (node)
798 {
799 wxEventTableEntry *entry = (wxEventTableEntry*)node->Data();
800 if (entry->m_callbackUserData) delete entry->m_callbackUserData;
801 delete entry;
802 node = node->Next();
803 }
804 delete m_dynamicEvents;
805 };
806
807 delete m_pendingEvents;
808
809 #if wxUSE_THREADS
810 # if !defined(__VISAGECPP__)
811 delete m_eventsLocker;
812 # endif
813 #endif
814 }
815
816 #if wxUSE_THREADS
817
818 bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
819 {
820 // check that we are really in a child thread
821 wxASSERT_MSG( !wxThread::IsMain(),
822 wxT("use ProcessEvent() in main thread") );
823
824 AddPendingEvent(event);
825
826 return TRUE;
827 }
828
829 #endif // wxUSE_THREADS
830
831 void wxEvtHandler::AddPendingEvent(wxEvent& event)
832 {
833 // 1) Add event to list of pending events of this event handler
834
835 #if defined(__VISAGECPP__)
836 wxENTER_CRIT_SECT( m_eventsLocker);
837 #else
838 wxENTER_CRIT_SECT( *m_eventsLocker);
839 #endif
840
841 if ( !m_pendingEvents )
842 m_pendingEvents = new wxList;
843
844 wxEvent *event2 = (wxEvent *)event.Clone();
845
846 m_pendingEvents->Append(event2);
847
848 #if defined(__VISAGECPP__)
849 wxLEAVE_CRIT_SECT( m_eventsLocker);
850 #else
851 wxLEAVE_CRIT_SECT( *m_eventsLocker);
852 #endif
853
854 // 2) Add this event handler to list of event handlers that
855 // have pending events.
856
857 wxENTER_CRIT_SECT(*wxPendingEventsLocker);
858
859 if ( !wxPendingEvents )
860 wxPendingEvents = new wxList;
861 wxPendingEvents->Append(this);
862
863 wxLEAVE_CRIT_SECT(*wxPendingEventsLocker);
864
865 // 3) Inform the system that new pending events are somwehere,
866 // and that these should be processed in idle time.
867 wxWakeUpIdle();
868 }
869
870 void wxEvtHandler::ProcessPendingEvents()
871 {
872 #if defined(__VISAGECPP__)
873 wxENTER_CRIT_SECT( m_eventsLocker);
874 #else
875 wxENTER_CRIT_SECT( *m_eventsLocker);
876 #endif
877
878 wxNode *node = m_pendingEvents->First();
879 while ( node )
880 {
881 wxEvent *event = (wxEvent *)node->Data();
882 delete node;
883
884 // In ProcessEvent, new events might get added and
885 // we can safely leave the crtical section here.
886 #if defined(__VISAGECPP__)
887 wxLEAVE_CRIT_SECT( m_eventsLocker);
888 #else
889 wxLEAVE_CRIT_SECT( *m_eventsLocker);
890 #endif
891 ProcessEvent(*event);
892 delete event;
893 #if defined(__VISAGECPP__)
894 wxENTER_CRIT_SECT( m_eventsLocker);
895 #else
896 wxENTER_CRIT_SECT( *m_eventsLocker);
897 #endif
898
899 node = m_pendingEvents->First();
900 }
901
902 #if defined(__VISAGECPP__)
903 wxLEAVE_CRIT_SECT( m_eventsLocker);
904 #else
905 wxLEAVE_CRIT_SECT( *m_eventsLocker);
906 #endif
907 }
908
909 /*
910 * Event table stuff
911 */
912
913 bool wxEvtHandler::ProcessEvent(wxEvent& event)
914 {
915 #if wxUSE_GUI
916 // check that our flag corresponds to reality
917 wxASSERT( m_isWindow == IsKindOf(CLASSINFO(wxWindow)) );
918 #endif // wxUSE_GUI
919
920 // An event handler can be enabled or disabled
921 if ( GetEvtHandlerEnabled() )
922 {
923
924 #if 0
925 /*
926 What is this? When using GUI threads, a non main
927 threads can send an event and process it itself.
928 This breaks GTK's GUI threads, so please explain.
929 */
930
931 // Check whether we are in a child thread.
932 if ( !wxThread::IsMain() )
933 return ProcessThreadEvent(event);
934 #endif
935
936 // Handle per-instance dynamic event tables first
937 if ( m_dynamicEvents && SearchDynamicEventTable(event) )
938 return TRUE;
939
940 // Then static per-class event tables
941 const wxEventTable *table = GetEventTable();
942
943 #if wxUSE_GUI && wxUSE_VALIDATORS
944 // Try the associated validator first, if this is a window.
945 // Problem: if the event handler of the window has been replaced,
946 // this wxEvtHandler may no longer be a window.
947 // Therefore validators won't be processed if the handler
948 // has been replaced with SetEventHandler.
949 // THIS CAN BE CURED if PushEventHandler is used instead of
950 // SetEventHandler, and then processing will be passed down the
951 // chain of event handlers.
952 if (m_isWindow)
953 {
954 wxWindow *win = (wxWindow *)this;
955
956 // Can only use the validator of the window which
957 // is receiving the event
958 if ( win == event.GetEventObject() )
959 {
960 wxValidator *validator = win->GetValidator();
961 if ( validator && validator->ProcessEvent(event) )
962 {
963 return TRUE;
964 }
965 }
966 }
967 #endif
968
969 // Search upwards through the inheritance hierarchy
970 while (table)
971 {
972 if ( SearchEventTable((wxEventTable&)*table, event) )
973 return TRUE;
974 table = table->baseTable;
975 }
976 }
977
978 // Try going down the event handler chain
979 if ( GetNextHandler() )
980 {
981 if ( GetNextHandler()->ProcessEvent(event) )
982 return TRUE;
983 }
984
985 #if wxUSE_GUI
986 // Carry on up the parent-child hierarchy,
987 // but only if event is a command event: it wouldn't
988 // make sense for a parent to receive a child's size event, for example
989 if ( m_isWindow && event.IsCommandEvent() )
990 {
991 wxWindow *win = (wxWindow *)this;
992 wxWindow *parent = win->GetParent();
993 if (parent && !parent->IsBeingDeleted())
994 return parent->GetEventHandler()->ProcessEvent(event);
995 }
996 #endif // wxUSE_GUI
997
998 // Last try - application object.
999 if ( wxTheApp && (this != wxTheApp) )
1000 {
1001 // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always
1002 // swallow it. wxEVT_IDLE is sent explicitly to wxApp so it will be
1003 // processed appropriately via SearchEventTable.
1004 if ( event.GetEventType() != wxEVT_IDLE )
1005 {
1006 if ( wxTheApp->ProcessEvent(event) )
1007 return TRUE;
1008 }
1009 }
1010
1011 return FALSE;
1012 }
1013
1014 bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
1015 {
1016 int i = 0;
1017 int commandId = event.GetId();
1018
1019 // BC++ doesn't like while (table.entries[i].m_fn)
1020
1021 #ifdef __SC__
1022 while (table.entries[i].m_fn != 0)
1023 #else
1024 while (table.entries[i].m_fn != 0L)
1025 #endif
1026 {
1027 if ((event.GetEventType() == table.entries[i].m_eventType) &&
1028 (table.entries[i].m_id == -1 || // Match, if event spec says any id will do (id == -1)
1029 (table.entries[i].m_lastId == -1 && commandId == table.entries[i].m_id) ||
1030 (table.entries[i].m_lastId != -1 &&
1031 (commandId >= table.entries[i].m_id && commandId <= table.entries[i].m_lastId))))
1032 {
1033 event.Skip(FALSE);
1034 event.m_callbackUserData = table.entries[i].m_callbackUserData;
1035
1036 (this->*((wxEventFunction) (table.entries[i].m_fn)))(event);
1037
1038 if ( event.GetSkipped() )
1039 return FALSE;
1040 else
1041 return TRUE;
1042 }
1043 i++;
1044 }
1045 return FALSE;
1046 }
1047
1048 void wxEvtHandler::Connect( int id, int lastId,
1049 wxEventType eventType,
1050 wxObjectEventFunction func,
1051 wxObject *userData )
1052 {
1053 wxEventTableEntry *entry = new wxEventTableEntry;
1054 entry->m_id = id;
1055 entry->m_lastId = lastId;
1056 entry->m_eventType = eventType;
1057 entry->m_fn = func;
1058 entry->m_callbackUserData = userData;
1059
1060 if (!m_dynamicEvents)
1061 m_dynamicEvents = new wxList;
1062
1063 m_dynamicEvents->Append( (wxObject*) entry );
1064 }
1065
1066 bool wxEvtHandler::Disconnect( int id, int lastId, wxEventType eventType,
1067 wxObjectEventFunction func,
1068 wxObject *userData )
1069 {
1070 if (!m_dynamicEvents)
1071 return FALSE;
1072
1073 wxNode *node = m_dynamicEvents->First();
1074 while (node)
1075 {
1076 wxEventTableEntry *entry = (wxEventTableEntry*)node->Data();
1077 if ((entry->m_id == id) &&
1078 ((entry->m_lastId == lastId) || (lastId == -1)) &&
1079 ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
1080 ((entry->m_fn == func) || (func == (wxObjectEventFunction)NULL)) &&
1081 ((entry->m_callbackUserData == userData) || (userData == (wxObject*)NULL)))
1082 {
1083 if (entry->m_callbackUserData) delete entry->m_callbackUserData;
1084 m_dynamicEvents->DeleteNode( node );
1085 delete entry;
1086 return TRUE;
1087 }
1088 node = node->Next();
1089 }
1090 return FALSE;
1091 }
1092
1093 bool wxEvtHandler::SearchDynamicEventTable( wxEvent& event )
1094 {
1095 wxCHECK_MSG( m_dynamicEvents, FALSE,
1096 wxT("caller should check that we have dynamic events") );
1097
1098 int commandId = event.GetId();
1099
1100 wxNode *node = m_dynamicEvents->First();
1101 while (node)
1102 {
1103 wxEventTableEntry *entry = (wxEventTableEntry*)node->Data();
1104
1105 if (entry->m_fn)
1106 {
1107 // Match, if event spec says any id will do (id == -1)
1108 if ( (event.GetEventType() == entry->m_eventType) &&
1109 (entry->m_id == -1 ||
1110 (entry->m_lastId == -1 && commandId == entry->m_id) ||
1111 (entry->m_lastId != -1 &&
1112 (commandId >= entry->m_id && commandId <= entry->m_lastId))) )
1113 {
1114 event.Skip(FALSE);
1115 event.m_callbackUserData = entry->m_callbackUserData;
1116
1117 (this->*((wxEventFunction) (entry->m_fn)))(event);
1118
1119 if (event.GetSkipped())
1120 return FALSE;
1121 else
1122 return TRUE;
1123 }
1124 }
1125 node = node->Next();
1126 }
1127 return FALSE;
1128 };
1129
1130 #if WXWIN_COMPATIBILITY
1131 bool wxEvtHandler::OnClose()
1132 {
1133 if (GetNextHandler())
1134 return GetNextHandler()->OnClose();
1135 else
1136 return FALSE;
1137 }
1138 #endif // WXWIN_COMPATIBILITY
1139
1140 #if wxUSE_GUI
1141
1142 // Find a window with the focus, that is also a descendant of the given window.
1143 // This is used to determine the window to initially send commands to.
1144 wxWindow* wxFindFocusDescendant(wxWindow* ancestor)
1145 {
1146 // Process events starting with the window with the focus, if any.
1147 wxWindow* focusWin = wxWindow::FindFocus();
1148 wxWindow* win = focusWin;
1149
1150 // Check if this is a descendant of this frame.
1151 // If not, win will be set to NULL.
1152 while (win)
1153 {
1154 if (win == ancestor)
1155 break;
1156 else
1157 win = win->GetParent();
1158 }
1159 if (win == (wxWindow*) NULL)
1160 focusWin = (wxWindow*) NULL;
1161
1162 return focusWin;
1163 }
1164
1165 #endif // wxUSE_GUI