event.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,452 行 · 第 1/3 页

CPP
1,452
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        event.cpp
// Purpose:     Event classes
// Author:      Julian Smart
// Modified by:
// Created:     01/02/97
// RCS-ID:      $Id: event.cpp,v 1.166 2005/06/30 00:52:05 MW Exp $
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) && !defined(__EMX__)
// Some older compilers (such as EMX) cannot handle
// #pragma interface/implementation correctly, iff
// #pragma implementation is used in _two_ translation
// units (as created by e.g. event.cpp compiled for
// libwx_base and event.cpp compiled for libwx_gui_core).
// So we must not use those pragmas for those compilers in
// such files.
    #pragma implementation "event.h"
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/defs.h"
    #include "wx/app.h"
    #include "wx/list.h"

    #if wxUSE_GUI
        #include "wx/control.h"
        #include "wx/utils.h"
        #include "wx/dc.h"
        #include "wx/textctrl.h"
    #endif // wxUSE_GUI
#endif

#include "wx/event.h"
#include "wx/module.h"

#if wxUSE_GUI
    #include "wx/validate.h"
#if wxUSE_STOPWATCH
    #include "wx/stopwatch.h"
#endif
#endif // wxUSE_GUI

// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------

#if wxUSE_BASE
    IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
    IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
#endif // wxUSE_BASE

#if wxUSE_GUI
    IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent, wxCommandEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxScrollWinEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxNcPaintEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxChildFocusEvent, wxCommandEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxShowEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxSetCursorEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxDisplayChangedEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent, wxCommandEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent, wxEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent, wxCommandEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxContextMenuEvent, wxCommandEvent)
    IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureChangedEvent, wxEvent)
#endif // wxUSE_GUI

#if wxUSE_BASE

const wxEventTable *wxEvtHandler::GetEventTable() const
    { return &wxEvtHandler::sm_eventTable; }

const wxEventTable wxEvtHandler::sm_eventTable =
    { (const wxEventTable *)NULL, &wxEvtHandler::sm_eventTableEntries[0] };

wxEventHashTable &wxEvtHandler::GetEventHashTable() const
    { return wxEvtHandler::sm_eventHashTable; }

wxEventHashTable wxEvtHandler::sm_eventHashTable(wxEvtHandler::sm_eventTable);

const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] =
    { DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL, 0, 0, (wxObjectEventFunction)NULL, NULL) };


#ifdef __WXDEBUG__
// Clear up event hash table contents or we can get problems
// when C++ is cleaning up the static object
class wxEventTableEntryModule: public wxModule
{
DECLARE_DYNAMIC_CLASS(wxEventTableEntryModule)
public:
    wxEventTableEntryModule() {}
    bool OnInit() { return true; }
    void OnExit()
    {
        wxEventHashTable::ClearAll();
    }
};
IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule, wxModule)
#endif

// ----------------------------------------------------------------------------
// global variables
// ----------------------------------------------------------------------------

// To put pending event handlers
wxList *wxPendingEvents = (wxList *)NULL;

#if wxUSE_THREADS
    // protects wxPendingEvents list
    wxCriticalSection *wxPendingEventsLocker = (wxCriticalSection *)NULL;
#endif

#if !WXWIN_COMPATIBILITY_EVENT_TYPES

// common event types are defined here, other event types are defined by the
// components which use them

const wxEventType wxEVT_FIRST = 10000;
const wxEventType wxEVT_USER_FIRST = wxEVT_FIRST + 2000;

DEFINE_EVENT_TYPE(wxEVT_NULL)
DEFINE_EVENT_TYPE(wxEVT_IDLE)
DEFINE_EVENT_TYPE(wxEVT_SOCKET)

#endif // !WXWIN_COMPATIBILITY_EVENT_TYPES

#endif // wxUSE_BASE

#if wxUSE_GUI

#if !WXWIN_COMPATIBILITY_EVENT_TYPES

DEFINE_EVENT_TYPE(wxEVT_COMMAND_BUTTON_CLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKBOX_CLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHOICE_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_MENU_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SLIDER_UPDATED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RADIOBOX_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RADIOBUTTON_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SCROLLBAR_UPDATED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_VLBOX_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_COMBOBOX_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_RCLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED)

// Sockets and timers send events, too
DEFINE_EVENT_TYPE(wxEVT_TIMER)

// Mouse event types
DEFINE_EVENT_TYPE(wxEVT_LEFT_DOWN)
DEFINE_EVENT_TYPE(wxEVT_LEFT_UP)
DEFINE_EVENT_TYPE(wxEVT_MIDDLE_DOWN)
DEFINE_EVENT_TYPE(wxEVT_MIDDLE_UP)
DEFINE_EVENT_TYPE(wxEVT_RIGHT_DOWN)
DEFINE_EVENT_TYPE(wxEVT_RIGHT_UP)
DEFINE_EVENT_TYPE(wxEVT_MOTION)
DEFINE_EVENT_TYPE(wxEVT_ENTER_WINDOW)
DEFINE_EVENT_TYPE(wxEVT_LEAVE_WINDOW)
DEFINE_EVENT_TYPE(wxEVT_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_MIDDLE_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_RIGHT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_SET_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_KILL_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_CHILD_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_MOUSEWHEEL)

// Non-client mouse events
DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DOWN)
DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_UP)
DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_DOWN)
DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_UP)
DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_DOWN)
DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_UP)
DEFINE_EVENT_TYPE(wxEVT_NC_MOTION)
DEFINE_EVENT_TYPE(wxEVT_NC_ENTER_WINDOW)
DEFINE_EVENT_TYPE(wxEVT_NC_LEAVE_WINDOW)
DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_NC_MIDDLE_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_NC_RIGHT_DCLICK)

// Character input event type
DEFINE_EVENT_TYPE(wxEVT_CHAR)
DEFINE_EVENT_TYPE(wxEVT_CHAR_HOOK)
DEFINE_EVENT_TYPE(wxEVT_NAVIGATION_KEY)
DEFINE_EVENT_TYPE(wxEVT_KEY_DOWN)
DEFINE_EVENT_TYPE(wxEVT_KEY_UP)
#if wxUSE_HOTKEY
DEFINE_EVENT_TYPE(wxEVT_HOTKEY)
#endif

// Set cursor event
DEFINE_EVENT_TYPE(wxEVT_SET_CURSOR)

// wxScrollbar and wxSlider event identifiers
DEFINE_EVENT_TYPE(wxEVT_SCROLL_TOP)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_BOTTOM)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_LINEUP)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_LINEDOWN)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_PAGEUP)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_PAGEDOWN)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_THUMBTRACK)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_THUMBRELEASE)
DEFINE_EVENT_TYPE(wxEVT_SCROLL_CHANGED)

// see comments in wx/event.h, near wxEVT_SCROLL_ENDSCROLL declaration
#if wxCHECK_VERSION(2, 7, 0)
    #error "Remove the lines below, not needed any more"
#endif
#undef wxEVT_SCROLL_ENDSCROLL
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_SCROLL_ENDSCROLL;
const wxEventType wxEVT_SCROLL_ENDSCROLL = wxEVT_SCROLL_CHANGED;

// Scroll events from wxWindow
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_TOP)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_BOTTOM)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_LINEUP)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_LINEDOWN)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_PAGEUP)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_PAGEDOWN)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_THUMBTRACK)
DEFINE_EVENT_TYPE(wxEVT_SCROLLWIN_THUMBRELEASE)

// System events
DEFINE_EVENT_TYPE(wxEVT_SIZE)
DEFINE_EVENT_TYPE(wxEVT_SIZING)
DEFINE_EVENT_TYPE(wxEVT_MOVE)
DEFINE_EVENT_TYPE(wxEVT_MOVING)
DEFINE_EVENT_TYPE(wxEVT_CLOSE_WINDOW)
DEFINE_EVENT_TYPE(wxEVT_END_SESSION)
DEFINE_EVENT_TYPE(wxEVT_QUERY_END_SESSION)
DEFINE_EVENT_TYPE(wxEVT_HIBERNATE)
DEFINE_EVENT_TYPE(wxEVT_ACTIVATE_APP)
DEFINE_EVENT_TYPE(wxEVT_POWER)
DEFINE_EVENT_TYPE(wxEVT_ACTIVATE)
DEFINE_EVENT_TYPE(wxEVT_CREATE)
DEFINE_EVENT_TYPE(wxEVT_DESTROY)
DEFINE_EVENT_TYPE(wxEVT_SHOW)
DEFINE_EVENT_TYPE(wxEVT_ICONIZE)
DEFINE_EVENT_TYPE(wxEVT_MAXIMIZE)
DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_PAINT)
DEFINE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND)
DEFINE_EVENT_TYPE(wxEVT_NC_PAINT)
DEFINE_EVENT_TYPE(wxEVT_PAINT_ICON)
DEFINE_EVENT_TYPE(wxEVT_MENU_OPEN)
DEFINE_EVENT_TYPE(wxEVT_MENU_CLOSE)
DEFINE_EVENT_TYPE(wxEVT_MENU_HIGHLIGHT)
DEFINE_EVENT_TYPE(wxEVT_CONTEXT_MENU)
DEFINE_EVENT_TYPE(wxEVT_SYS_COLOUR_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_DISPLAY_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_SETTING_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_QUERY_NEW_PALETTE)
DEFINE_EVENT_TYPE(wxEVT_PALETTE_CHANGED)
DEFINE_EVENT_TYPE(wxEVT_JOY_BUTTON_DOWN)
DEFINE_EVENT_TYPE(wxEVT_JOY_BUTTON_UP)
DEFINE_EVENT_TYPE(wxEVT_JOY_MOVE)
DEFINE_EVENT_TYPE(wxEVT_JOY_ZMOVE)
DEFINE_EVENT_TYPE(wxEVT_DROP_FILES)
DEFINE_EVENT_TYPE(wxEVT_DRAW_ITEM)
DEFINE_EVENT_TYPE(wxEVT_MEASURE_ITEM)
DEFINE_EVENT_TYPE(wxEVT_COMPARE_ITEM)
DEFINE_EVENT_TYPE(wxEVT_INIT_DIALOG)
DEFINE_EVENT_TYPE(wxEVT_UPDATE_UI)

// Generic command events
// Note: a click is a higher-level event than button down/up
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_CLICK)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LEFT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RIGHT_CLICK)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_RIGHT_DCLICK)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SET_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_KILL_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_ENTER)

// Help events
DEFINE_EVENT_TYPE(wxEVT_HELP)
DEFINE_EVENT_TYPE(wxEVT_DETAILED_HELP)

#endif // !WXWIN_COMPATIBILITY_EVENT_TYPES

#endif // wxUSE_GUI

#if wxUSE_BASE

// ============================================================================
// implementation
// ============================================================================

// ----------------------------------------------------------------------------
// event initialization
// ----------------------------------------------------------------------------

int wxNewEventType()
{
    // MT-FIXME
    static int s_lastUsedEventType = wxEVT_FIRST;

    return s_lastUsedEventType++;
}

// ----------------------------------------------------------------------------
// wxEvent
// ----------------------------------------------------------------------------

/*
 * General wxWidgets events, covering
 * all interesting things that might happen (button clicking, resizing,
 * setting text in widgets, etc.).
 *
 * For each completely new event type, derive a new event class.
 *
 */

wxEvent::wxEvent(int theId, wxEventType commandType )
{
    m_eventType = commandType;
    m_eventObject = (wxObject *) NULL;
    m_timeStamp = 0;
    m_id = theId;
    m_skipped = false;
    m_callbackUserData = (wxObject *) NULL;
    m_isCommandEvent = false;
    m_propagationLevel = wxEVENT_PROPAGATE_NONE;
}

wxEvent::wxEvent(const wxEvent &src)
    : wxObject()
    , m_eventObject(src.m_eventObject)
    , m_eventType(src.m_eventType)
    , m_timeStamp(src.m_timeStamp)
    , m_id(src.m_id)
    , m_callbackUserData(src.m_callbackUserData)
    , m_propagationLevel(src.m_propagationLevel)
    , m_skipped(src.m_skipped)
    , m_isCommandEvent(src.m_isCommandEvent)
{
}

#endif // wxUSE_BASE

#if wxUSE_GUI

/*
 * Command events
 *
 */

#ifdef __VISUALC__
    // 'this' : used in base member initializer list (for m_commandString)
    #pragma warning(disable:4355)
#endif

wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId)
              : wxEvent(theId, commandType)
#if WXWIN_COMPATIBILITY_2_4
              , m_commandString(this)
#endif
{
    m_clientData = (char *) NULL;
    m_clientObject = (wxClientData *) NULL;
    m_extraLong = 0;
    m_commandInt = 0;
    m_isCommandEvent = true;

    // the command events are propagated upwards by default
    m_propagationLevel = wxEVENT_PROPAGATE_MAX;
}

#ifdef __VISUALC__
    #pragma warning(default:4355)
#endif

wxString wxCommandEvent::GetString() const
{
    if(m_eventType != wxEVT_COMMAND_TEXT_UPDATED || !m_eventObject)
        return m_cmdString;
    else
    {
#if wxUSE_TEXTCTRL
        wxTextCtrl *txt = wxDynamicCast(m_eventObject, wxTextCtrl);
        if(txt)
            return txt->GetValue();
        else
#endif // wxUSE_TEXTCTRL
            return m_cmdString;
    }
}

/*
 * UI update events
 */

#if wxUSE_LONGLONG
wxLongLong wxUpdateUIEvent::sm_lastUpdate = 0;
#endif

long wxUpdateUIEvent::sm_updateInterval = 0;

wxUpdateUIMode wxUpdateUIEvent::sm_updateMode = wxUPDATE_UI_PROCESS_ALL;

// Can we update?
bool wxUpdateUIEvent::CanUpdate(wxWindowBase *win)
{
    // Don't update if we've switched global updating off
    // and this window doesn't support updates.
    if (win &&
       (GetMode() == wxUPDATE_UI_PROCESS_SPECIFIED &&
       ((win->GetExtraStyle() & wxWS_EX_PROCESS_UI_UPDATES) == 0)))
        return false;

    if (sm_updateInterval == -1)
        return false;

    if (sm_updateInterval == 0)
        return true;

#if wxUSE_STOPWATCH && wxUSE_LONGLONG
    wxLongLong now = wxGetLocalTimeMillis();
    if (now > (sm_lastUpdate + sm_updateInterval))
    {
        return true;
    }

    return false;
#else
    // If we don't have wxStopWatch or wxLongLong, we
    // should err on the safe side and update now anyway.
    return true;
#endif
}

// Reset the update time to provide a delay until the next
// time we should update
void wxUpdateUIEvent::ResetUpdateTime()
{
#if wxUSE_STOPWATCH && wxUSE_LONGLONG
    if (sm_updateInterval > 0)
    {
        wxLongLong now = wxGetLocalTimeMillis();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?