]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/event.h
Augmented version to b5
[wxWidgets.git] / include / wx / event.h
index 80f227490191bd1ec4bf977f2975aa96db835b39..fc04af3fbaaac2b212c0c0d0677b00ecdaed4a2f 100644 (file)
 #include "wx/object.h"
 #include "wx/gdicmn.h"
 
+#if wxUSE_THREADS
+    #include "wx/thread.h"
+#endif
+
 /*
  * Event types
  *
@@ -91,7 +95,7 @@ const wxEventType wxEVT_KEY_DOWN =                          wxEVT_FIRST + 215;
 const wxEventType wxEVT_KEY_UP =                            wxEVT_FIRST + 216;
 
  /*
-  * Scrollbar event identifiers
+  * wxScrollbar and wxSlider event identifiers
   */
 const wxEventType wxEVT_SCROLL_TOP =                        wxEVT_FIRST + 300;
 const wxEventType wxEVT_SCROLL_BOTTOM =                     wxEVT_FIRST + 301;
@@ -101,6 +105,20 @@ const wxEventType wxEVT_SCROLL_PAGEUP =                     wxEVT_FIRST + 304;
 const wxEventType wxEVT_SCROLL_PAGEDOWN =                   wxEVT_FIRST + 305;
 const wxEventType wxEVT_SCROLL_THUMBTRACK =                 wxEVT_FIRST + 306;
 
+ /*
+  * Scroll events from wxWindow
+  */
+const wxEventType wxEVT_SCROLLWIN_TOP =                     wxEVT_FIRST + 320;
+const wxEventType wxEVT_SCROLLWIN_BOTTOM =                  wxEVT_FIRST + 321;
+const wxEventType wxEVT_SCROLLWIN_LINEUP =                  wxEVT_FIRST + 322;
+const wxEventType wxEVT_SCROLLWIN_LINEDOWN =                wxEVT_FIRST + 323;
+const wxEventType wxEVT_SCROLLWIN_PAGEUP =                  wxEVT_FIRST + 324;
+const wxEventType wxEVT_SCROLLWIN_PAGEDOWN =                wxEVT_FIRST + 325;
+const wxEventType wxEVT_SCROLLWIN_THUMBTRACK =              wxEVT_FIRST + 326;
+
+ /*
+  * System events
+  */
 const wxEventType wxEVT_SIZE =                              wxEVT_FIRST + 400;
 const wxEventType wxEVT_MOVE =                              wxEVT_FIRST + 401;
 const wxEventType wxEVT_CLOSE_WINDOW =                      wxEVT_FIRST + 402;
@@ -200,6 +218,11 @@ const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED =     wxEVT_FIRST + 802;
 const wxEventType wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING =    wxEVT_FIRST + 803;
 #endif
 
+/* Splitter events */
+const wxEventType wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED = wxEVT_FIRST + 850;
+const wxEventType wxEVT_COMMAND_SPLITTER_DOUBLECLICKED = wxEVT_FIRST + 851;
+const wxEventType wxEVT_COMMAND_SPLITTER_UNSPLIT = wxEVT_FIRST + 852;
+
 const wxEventType wxEVT_USER_FIRST =                        wxEVT_FIRST + 2000;
 
 /* Compatibility */
@@ -283,14 +306,23 @@ public:
     void Skip(bool skip = TRUE) { m_skipped = skip; }
     bool GetSkipped() const { return m_skipped; };
 
+    // implementation only: this test is explicitlty anti OO and this functions
+    // exists only for optimization purposes
+    bool IsCommandEvent() const { return m_isCommandEvent; }
+
+    void CopyObject(wxObject& object_dest) const;
+
 public:
-    bool              m_skipped;
     wxObject*         m_eventObject;
-    char*             m_eventHandle;         // Handle of an underlying windowing system event
     wxEventType       m_eventType;
     long              m_timeStamp;
     int               m_id;
     wxObject*         m_callbackUserData;
+    bool              m_skipped;
+
+    // optimization: instead of using costly IsKindOf() we keep a flag telling
+    // whether we're a command event (by far the most common case)
+    bool              m_isCommandEvent;
 };
 
 // Item or menu event class
@@ -338,8 +370,8 @@ public:
     int GetSelection() const { return m_commandInt; }
 
     // Set/Get listbox/choice selection string
-    void SetString(char* s) { m_commandString = s; }
-    char *GetString() const { return m_commandString; }
+    void SetString(const wxString& s) { m_commandString = s; }
+    wxString GetString() const { return m_commandString; }
 
     // Get checkbox value
     bool Checked() const { return (m_commandInt != 0); }
@@ -353,8 +385,10 @@ public:
     void SetInt(int i) { m_commandInt = i; }
     long GetInt() const { return m_commandInt ; }
 
+    void CopyObject(wxObject& obj) const;
+
 public:
-    char*             m_commandString; // String event argument
+    wxString          m_commandString; // String event argument
     int               m_commandInt;
     long              m_extraLong;     // Additional information (e.g. select/deselect)
     void*             m_clientData;    // Arbitrary client data
@@ -381,7 +415,8 @@ private:
     DECLARE_DYNAMIC_CLASS(wxNotifyEvent)
 };
 
-// Scroll event class
+// Scroll event class, derived form wxCommandEvent. wxScrollEvents are
+// sent by wxSlider and wxScrollbar.
 /*
  wxEVT_SCROLL_TOP
  wxEVT_SCROLL_BOTTOM
@@ -412,6 +447,41 @@ public:
     void SetPosition(int pos) { m_commandInt = pos; }
 };
 
+// ScrollWin event class, derived fom wxEvent. wxScrollWinEvents
+// are sent by wxWindow.
+/*
+ wxEVT_SCROLLWIN_TOP
+ wxEVT_SCROLLWIN_BOTTOM
+ wxEVT_SCROLLWIN_LINEUP
+ wxEVT_SCROLLWIN_LINEDOWN
+ wxEVT_SCROLLWIN_PAGEUP
+ wxEVT_SCROLLWIN_PAGEDOWN
+ wxEVT_SCROLLWIN_THUMBTRACK
+*/
+
+class WXDLLEXPORT wxScrollWinEvent : public wxEvent
+{
+    DECLARE_DYNAMIC_CLASS(wxScrollWinEvent)
+
+public:
+    wxScrollWinEvent(wxEventType commandType = wxEVT_NULL,
+                     int pos = 0, int orient = 0);
+    ~wxScrollWinEvent() {}
+
+    /*
+     * Accessors
+     */
+
+    int GetOrientation() const { return (int) m_extraLong ; }
+    int GetPosition() const { return m_commandInt ; }
+    void SetOrientation(int orient) { m_extraLong = (long) orient; }
+    void SetPosition(int pos) { m_commandInt = pos; }
+
+public:
+    int               m_commandInt;    // Additional information
+    long              m_extraLong;     
+};
+
 // Mouse event class
 
 /*
@@ -509,6 +579,7 @@ public:
     bool Leaving() const { return (m_eventType == wxEVT_LEAVE_WINDOW); }
 
     // Find the position of the event
+    void GetPosition(long *xpos, long *ypos) const { *xpos = m_x; *ypos = m_y; }
     void Position(long *xpos, long *ypos) const { *xpos = m_x; *ypos = m_y; }
 
     // Find the position of the event
@@ -531,6 +602,8 @@ public:
     // Get Y position
     long GetY() const { return m_y; }
 
+    void CopyObject(wxObject& obj) const;
+
 public:
     long          m_x;
     long          m_y;
@@ -567,18 +640,20 @@ public:
     bool ShiftDown() const { return m_shiftDown; }
     long KeyCode() const { return m_keyCode; }
 
-#if WXWIN_COMPATIBILITY
     // Find the position of the event
-    void Position(float *xpos, float *ypos) const
-        { *xpos = (float)m_x; *ypos = (float)m_y; }
+    void GetPosition(long *xpos, long *ypos) const
+        { *xpos = m_x; *ypos = m_y; }
+
+    wxPoint GetPosition() const
+        { return wxPoint(m_x, m_y); }
 
     // Get X position
-    float GetX() const { return (float)m_x; }
+    long GetX() const { return m_x; }
 
     // Get Y position
-    float GetY() const { return (float)m_y; }
+    long GetY() const { return m_y; }
 
-#endif // WXWIN_COMPATIBILITY
+    void CopyObject(wxObject& obj) const;
 
 public:
     long          m_x;
@@ -588,6 +663,7 @@ public:
     bool          m_shiftDown;
     bool          m_altDown;
     bool          m_metaDown;
+    bool          m_scanCode;
 };
 
 // Size event class
@@ -608,6 +684,8 @@ public:
         { m_eventType = wxEVT_SIZE; m_id = id; }
 
     wxSize GetSize() const { return m_size; }
+
+    void CopyObject(wxObject& obj) const;
 };
 
 // Move event class
@@ -629,6 +707,8 @@ public:
         { m_eventType = wxEVT_MOVE; m_id = id; }
 
     wxPoint GetPosition() const { return m_pos; }
+
+    void CopyObject(wxObject& obj) const;
 };
 
 // Paint event class
@@ -662,6 +742,8 @@ public:
     wxEraseEvent(int Id = 0, wxDC *dc = (wxDC *) NULL)
         { m_eventType = wxEVT_ERASE_BACKGROUND; m_id = Id; m_dc = dc; }
     wxDC *GetDC() const { return m_dc; }
+
+    void CopyObject(wxObject& obj) const;
 };
 
 // Focus event class
@@ -694,6 +776,8 @@ public:
         { m_eventType = type; m_active = active; m_id = Id; }
     bool GetActive() const { return m_active; }
 
+    void CopyObject(wxObject& obj) const;
+
 private:
     bool m_active;
 };
@@ -726,13 +810,14 @@ class WXDLLEXPORT wxMenuEvent : public wxEvent
     DECLARE_DYNAMIC_CLASS(wxMenuEvent)
 
 public:
-  wxMenuEvent(wxEventType type = wxEVT_NULL, int id = 0)
-    { m_eventType = type; m_menuId = id; }
+    wxMenuEvent(wxEventType type = wxEVT_NULL, int id = 0)
+      { m_eventType = type; m_menuId = id; }
 
-  int GetMenuId() const { return m_menuId; }
+    int GetMenuId() const { return m_menuId; }
 
+    void CopyObject(wxObject& obj) const;
 private:
-  int m_menuId;
+    int m_menuId;
 };
 
 // Window close or session close event class
@@ -766,7 +851,7 @@ public:
     {
         // GetVeto() will return FALSE anyhow...
         wxCHECK_RET( m_canVeto,
-                     "call to Veto() ignored (can't veto this event)" );
+                     _T("call to Veto() ignored (can't veto this event)") );
 
         m_veto = veto;
     }
@@ -783,6 +868,8 @@ public:
     bool GetForce() const { return m_force; }
 #endif
 
+    void CopyObject(wxObject& obj) const;
+
 protected:
     bool m_loggingOff;
     bool m_veto, m_canVeto;
@@ -808,6 +895,8 @@ public:
     void SetShow(bool show) { m_show = show; }
     bool GetShow() const { return m_show; }
 
+    void CopyObject(wxObject& obj) const;
+
 protected:
     bool m_show;
 };
@@ -917,6 +1006,8 @@ public:
     bool ButtonIsDown(int but =  wxJOY_BUTTON_ANY) const
     { return (((but == wxJOY_BUTTON_ANY) && (m_buttonState != 0)) ||
             ((m_buttonState & but) == but)); }
+
+    void CopyObject(wxObject& obj) const;
 };
 
 // Drop files event class
@@ -941,6 +1032,8 @@ public:
     wxPoint GetPosition() const { return m_pos; }
     int GetNumberOfFiles() const { return m_noFiles; }
     wxString *GetFiles() const { return m_files; }
+
+    void CopyObject(wxObject& obj) const;
 };
 
 // Idle event
@@ -959,6 +1052,8 @@ public:
     void RequestMore(bool needMore = TRUE) { m_requestMore = needMore; }
     bool MoreRequested() const { return m_requestMore; }
 
+    void CopyObject(wxObject& obj) const;
+
 protected:
     bool m_requestMore;
 };
@@ -999,6 +1094,8 @@ public:
     void Enable(bool enable) { m_enabled = enable; m_setEnabled = TRUE; }
     void SetText(const wxString& text) { m_text = text; m_setText = TRUE; }
 
+    void CopyObject(wxObject& obj) const;
+
 protected:
     bool          m_checked;
     bool          m_enabled;
@@ -1040,6 +1137,8 @@ public:
     void SetChangedWindow(wxWindow* win) { m_changedWindow = win; }
     wxWindow* GetChangedWindow() const { return m_changedWindow; }
 
+    void CopyObject(wxObject& obj) const;
+
 protected:
     wxWindow*     m_changedWindow;
 };
@@ -1061,6 +1160,8 @@ public:
     void SetPaletteRealized(bool realized) { m_paletteRealized = realized; }
     bool GetPaletteRealized() const { return m_paletteRealized; }
 
+    void CopyObject(wxObject& obj) const;
+
 protected:
     bool m_paletteRealized;
 };
@@ -1070,7 +1171,7 @@ protected:
  wxEVT_NAVIGATION_KEY
  */
 // must derive from command event to be propagated to the parent
-class WXDLLEXPORT wxNavigationKeyEvent  : public wxCommandEvent
+class WXDLLEXPORT wxNavigationKeyEvent : public wxCommandEvent
 {
     DECLARE_DYNAMIC_CLASS(wxNavigationKeyEvent)
 
@@ -1092,10 +1193,38 @@ public:
     void SetCurrentFocus(wxWindow *win) { m_clientData = (void *)win; }
 };
 
+// Window creation/destruction events: the first is sent as soon as window is
+// created (i.e. the underlying GUI object exists), but when the C++ object is
+// fully initialized (so virtual functions may be called). The second,
+// wxEVT_DESTROY, is sent right before the window is destroyed - again, it's
+// still safe to call virtual functions at this moment
+/*
+ wxEVT_CREATE
+ wxEVT_DESTROY
+ */
+
+class WXDLLEXPORT wxWindowCreateEvent : public wxEvent
+{
+    DECLARE_DYNAMIC_CLASS(wxWindowCreateEvent)
+
+public:
+    wxWindowCreateEvent(wxWindow *win = NULL);
+
+    wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); }
+};
+
+class WXDLLEXPORT wxWindowDestroyEvent : public wxEvent
+{
+    DECLARE_DYNAMIC_CLASS(wxWindowDestroyEvent)
+
+public:
+    wxWindowDestroyEvent(wxWindow *win = NULL);
+
+    wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); }
+};
+
 /* TODO
  wxEVT_POWER,
- wxEVT_CREATE,
- wxEVT_DESTROY,
  wxEVT_MOUSE_CAPTURE_CHANGED,
  wxEVT_SETTING_CHANGED, // WM_WININICHANGE (NT) / WM_SETTINGCHANGE (Win95)
 // wxEVT_FONT_CHANGED,  // WM_FONTCHANGE: roll into wxEVT_SETTING_CHANGED, but remember to propagate
@@ -1146,6 +1275,7 @@ public:
     void SetEvtHandlerEnabled(bool en) { m_enabled = en; }
     bool GetEvtHandlerEnabled() const { return m_enabled; }
 
+#if WXWIN_COMPATIBILITY_2
     virtual void OnCommand(wxWindow& WXUNUSED(win),
                            wxCommandEvent& WXUNUSED(event))
     {
@@ -1156,11 +1286,16 @@ public:
     // Default behaviour
     virtual long Default()
         { return GetNextHandler() ? GetNextHandler()->Default() : 0; };
+#endif // WXWIN_COMPATIBILITY_2
 
 #if WXWIN_COMPATIBILITY
     virtual bool OnClose();
 #endif
 
+#if wxUSE_THREADS
+    bool ProcessThreadEvent(wxEvent& event);
+    void ProcessPendingEvents();
+#endif
     virtual bool ProcessEvent(wxEvent& event);
     virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
 
@@ -1178,22 +1313,37 @@ public:
 
     bool SearchDynamicEventTable( wxEvent& event );
 
+#if wxUSE_THREADS
+    void ClearEventLocker() { delete m_eventsLocker; m_eventsLocker = NULL; };
+#endif
+
 private:
     static const wxEventTableEntry         sm_eventTableEntries[];
 
 protected:
-    static const wxEventTable        sm_eventTable;
-    virtual const wxEventTable*        GetEventTable() const;
+    static const wxEventTable sm_eventTable;
+
+    virtual const wxEventTable *GetEventTable() const;
+
 protected:
-    wxEvtHandler*     m_nextHandler;
-    wxEvtHandler*     m_previousHandler;
-    bool              m_enabled;                      // Is event handler enabled?
-    wxList*           m_dynamicEvents;
+    wxEvtHandler*       m_nextHandler;
+    wxEvtHandler*       m_previousHandler;
+    bool                m_enabled;           // Is event handler enabled?
+    wxList*             m_dynamicEvents;
+    wxList*             m_pendingEvents;
+#if wxUSE_THREADS
+    wxCriticalSection*  m_eventsLocker;
+#endif
+
+    // optimization: instead of using costly IsKindOf() to decide whether we're
+    // a window (which is true in 99% of cases), use this flag
+    bool                m_isWindow;
 };
 
 typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
 typedef void (wxEvtHandler::*wxCommandEventFunction)(wxCommandEvent&);
 typedef void (wxEvtHandler::*wxScrollEventFunction)(wxScrollEvent&);
+typedef void (wxEvtHandler::*wxScrollWinEventFunction)(wxScrollWinEvent&);
 typedef void (wxEvtHandler::*wxSizeEventFunction)(wxSizeEvent&);
 typedef void (wxEvtHandler::*wxMoveEventFunction)(wxMoveEvent&);
 typedef void (wxEvtHandler::*wxPaintEventFunction)(wxPaintEvent&);
@@ -1273,6 +1423,8 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
 #define EVT_NAVIGATION_KEY(func) { wxEVT_NAVIGATION_KEY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNavigationKeyEventFunction) & func, (wxObject *) NULL },
 #define EVT_PALETTE_CHANGED(func) { wxEVT_PALETTE_CHANGED, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxPaletteChangedEventFunction) & func, (wxObject *) NULL },
 #define EVT_QUERY_NEW_PALETTE(func) { wxEVT_QUERY_NEW_PALETTE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL },
+#define EVT_WINDOW_CREATE(func) { wxEVT_CREATE, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL },
+#define EVT_WINDOW_DESTROY(func) { wxEVT_DESTROY, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxQueryNewPaletteEventFunction) & func, (wxObject *) NULL },
 
 // Mouse events
 #define EVT_LEFT_DOWN(func) { wxEVT_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxMouseEventFunction) & func, (wxObject *) NULL },
@@ -1307,7 +1459,25 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
 #define EVT_COMMAND(id, event, fn)  { event, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL },
 #define EVT_COMMAND_RANGE(id1, id2, event, fn)  { event, id1, id2, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) & fn, (wxObject *) NULL },
 
-// Scrolling
+// Scrolling from wxWindow (sent to wxScrolledWindow)
+#define EVT_SCROLLWIN(func) \
+  { wxEVT_SCROLLWIN_TOP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },\
+  { wxEVT_SCROLLWIN_BOTTOM, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },\
+  { wxEVT_SCROLLWIN_LINEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },\
+  { wxEVT_SCROLLWIN_LINEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },\
+  { wxEVT_SCROLLWIN_PAGEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },\
+  { wxEVT_SCROLLWIN_PAGEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },\
+  { wxEVT_SCROLLWIN_THUMBTRACK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+
+#define EVT_SCROLLWIN_TOP(func) { wxEVT_SCROLLWIN_TOP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+#define EVT_SCROLLWIN_BOTTOM(func) { wxEVT_SCROLLWIN_BOTTOM, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+#define EVT_SCROLLWIN_LINEUP(func) { wxEVT_SCROLLWIN_LINEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+#define EVT_SCROLLWIN_LINEDOWN(func) { wxEVT_SCROLLWIN_LINEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+#define EVT_SCROLLWIN_PAGEUP(func) { wxEVT_SCROLLWIN_PAGEUP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+#define EVT_SCROLLWIN_PAGEDOWN(func) { wxEVT_SCROLLWIN_PAGEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+#define EVT_SCROLLWIN_THUMBTRACK(func) { wxEVT_SCROLLWIN_THUMBTRACK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollWinEventFunction) & func, (wxObject *) NULL },
+
+// Scrolling from wxSlider and wxScrollBar
 #define EVT_SCROLL(func) \
   { wxEVT_SCROLL_TOP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func, (wxObject *) NULL },\
   { wxEVT_SCROLL_BOTTOM, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func, (wxObject *) NULL },\
@@ -1325,7 +1495,7 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
 #define EVT_SCROLL_PAGEDOWN(func) { wxEVT_SCROLL_PAGEDOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func, (wxObject *) NULL },
 #define EVT_SCROLL_THUMBTRACK(func) { wxEVT_SCROLL_THUMBTRACK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func, (wxObject *) NULL },
 
-// Scrolling, with an id
+// Scrolling from wxSlider and wxScrollBar, with an id
 #define EVT_COMMAND_SCROLL(id, func) \
   { wxEVT_SCROLL_TOP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func, (wxObject *) NULL },\
   { wxEVT_SCROLL_BOTTOM, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxScrollEventFunction) & func, (wxObject *) NULL },\
@@ -1401,5 +1571,13 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
 #define EVT_UPDATE_UI(id, func) \
  { wxEVT_UPDATE_UI, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxUpdateUIEventFunction) & func, (wxObject *) NULL },\
 
+/*
+ * Helper functions
+ */
+
+// Find a window with the focus, that is also a descendant of the given window.
+// This is used to determine the window to initially send commands to.
+wxWindow* wxFindFocusDescendant(wxWindow* ancestor);
+
 #endif
         // _WX_EVENTH__