wincmn.cpp

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

CPP
2,214
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        common/window.cpp
// Purpose:     common (to all ports) wxWindow functions
// Author:      Julian Smart, Vadim Zeitlin
// Modified by:
// Created:     13/07/98
// RCS-ID:      $Id: wincmn.cpp,v 1.237.2.5 2006/03/04 20:52:21 ABX Exp $
// Copyright:   (c) wxWidgets team
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

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

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

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
    #pragma implementation "windowbase.h"
#endif

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

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/string.h"
    #include "wx/log.h"
    #include "wx/intl.h"
    #include "wx/frame.h"
    #include "wx/defs.h"
    #include "wx/window.h"
    #include "wx/control.h"
    #include "wx/checkbox.h"
    #include "wx/radiobut.h"
    #include "wx/statbox.h"
    #include "wx/textctrl.h"
    #include "wx/settings.h"
    #include "wx/dialog.h"
    #include "wx/msgdlg.h"
    #include "wx/statusbr.h"
    #include "wx/toolbar.h"
    #include "wx/dcclient.h"
#endif //WX_PRECOMP

#if defined(__WXMAC__) && wxUSE_SCROLLBAR
    #include "wx/scrolbar.h"
#endif

#if wxUSE_CONSTRAINTS
    #include "wx/layout.h"
#endif // wxUSE_CONSTRAINTS

#include "wx/sizer.h"

#if wxUSE_DRAG_AND_DROP
    #include "wx/dnd.h"
#endif // wxUSE_DRAG_AND_DROP

#if wxUSE_ACCESSIBILITY
    #include "wx/access.h"
#endif

#if wxUSE_HELP
    #include "wx/cshelp.h"
#endif // wxUSE_HELP

#if wxUSE_TOOLTIPS
    #include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS

#if wxUSE_CARET
    #include "wx/caret.h"
#endif // wxUSE_CARET

#if wxUSE_DISPLAY
    #include "wx/display.h"
#endif

#if wxUSE_SYSTEM_OPTIONS
    #include "wx/sysopt.h"
#endif

// ----------------------------------------------------------------------------
// static data
// ----------------------------------------------------------------------------

#if defined(__WXPALMOS__)
int wxWindowBase::ms_lastControlId = 32767;
#elif defined(__WXPM__)
int wxWindowBase::ms_lastControlId = 2000;
#else
int wxWindowBase::ms_lastControlId = -200;
#endif

IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)

// ----------------------------------------------------------------------------
// event table
// ----------------------------------------------------------------------------

BEGIN_EVENT_TABLE(wxWindowBase, wxEvtHandler)
    EVT_SYS_COLOUR_CHANGED(wxWindowBase::OnSysColourChanged)
    EVT_INIT_DIALOG(wxWindowBase::OnInitDialog)
    EVT_MIDDLE_DOWN(wxWindowBase::OnMiddleClick)

#if wxUSE_HELP
    EVT_HELP(wxID_ANY, wxWindowBase::OnHelp)
#endif // wxUSE_HELP

END_EVENT_TABLE()

// ============================================================================
// implementation of the common functionality of the wxWindow class
// ============================================================================

// ----------------------------------------------------------------------------
// initialization
// ----------------------------------------------------------------------------

// the default initialization
wxWindowBase::wxWindowBase()
{
    // no window yet, no parent nor children
    m_parent = (wxWindow *)NULL;
    m_windowId = wxID_ANY;

    // no constraints on the minimal window size
    m_minWidth =
    m_maxWidth = wxDefaultCoord;
    m_minHeight =
    m_maxHeight = wxDefaultCoord;

    // invalidiated cache value
    m_bestSizeCache = wxDefaultSize;

    // window are created enabled and visible by default
    m_isShown =
    m_isEnabled = true;

    // the default event handler is just this window
    m_eventHandler = this;

#if wxUSE_VALIDATORS
    // no validator
    m_windowValidator = (wxValidator *) NULL;
#endif // wxUSE_VALIDATORS

    // the colours/fonts are default for now, so leave m_font,
    // m_backgroundColour and m_foregroundColour uninitialized and set those
    m_hasBgCol =
    m_hasFgCol =
    m_hasFont = false;
    m_inheritBgCol =
    m_inheritFgCol =
    m_inheritFont = false;

    // no style bits
    m_exStyle =
    m_windowStyle = 0;

    m_backgroundStyle = wxBG_STYLE_SYSTEM;

#if wxUSE_CONSTRAINTS
    // no constraints whatsoever
    m_constraints = (wxLayoutConstraints *) NULL;
    m_constraintsInvolvedIn = (wxWindowList *) NULL;
#endif // wxUSE_CONSTRAINTS

    m_windowSizer = (wxSizer *) NULL;
    m_containingSizer = (wxSizer *) NULL;
    m_autoLayout = false;

#if wxUSE_DRAG_AND_DROP
    m_dropTarget = (wxDropTarget *)NULL;
#endif // wxUSE_DRAG_AND_DROP

#if wxUSE_TOOLTIPS
    m_tooltip = (wxToolTip *)NULL;
#endif // wxUSE_TOOLTIPS

#if wxUSE_CARET
    m_caret = (wxCaret *)NULL;
#endif // wxUSE_CARET

#if wxUSE_PALETTE
    m_hasCustomPalette = false;
#endif // wxUSE_PALETTE

#if wxUSE_ACCESSIBILITY
    m_accessible = NULL;
#endif

    m_virtualSize = wxDefaultSize;

    m_minVirtualWidth =
    m_maxVirtualWidth = wxDefaultCoord;
    m_minVirtualHeight =
    m_maxVirtualHeight = wxDefaultCoord;

    m_windowVariant = wxWINDOW_VARIANT_NORMAL;
#if wxUSE_SYSTEM_OPTIONS
    if ( wxSystemOptions::HasOption(wxWINDOW_DEFAULT_VARIANT) )
    {
       m_windowVariant = (wxWindowVariant) wxSystemOptions::GetOptionInt( wxWINDOW_DEFAULT_VARIANT ) ;
    }
#endif

    // Whether we're using the current theme for this window (wxGTK only for now)
    m_themeEnabled = false;

    // VZ: this one shouldn't exist...
    m_isBeingDeleted = false;

    // Reserved for future use
    m_windowReserved = NULL;
}

// common part of window creation process
bool wxWindowBase::CreateBase(wxWindowBase *parent,
                              wxWindowID id,
                              const wxPoint& WXUNUSED(pos),
                              const wxSize& WXUNUSED(size),
                              long style,
                              const wxValidator& wxVALIDATOR_PARAM(validator),
                              const wxString& name)
{
#if wxUSE_STATBOX
    // wxGTK doesn't allow to create controls with static box as the parent so
    // this will result in a crash when the program is ported to wxGTK so warn
    // the user about it

    // if you get this assert, the correct solution is to create the controls
    // as siblings of the static box
    wxASSERT_MSG( !parent || !wxDynamicCast(parent, wxStaticBox),
                  _T("wxStaticBox can't be used as a window parent!") );
#endif // wxUSE_STATBOX

    // ids are limited to 16 bits under MSW so if you care about portability,
    // it's not a good idea to use ids out of this range (and negative ids are
    // reserved for wxWidgets own usage)
    wxASSERT_MSG( id == wxID_ANY || (id >= 0 && id < 32767),
                  _T("invalid id value") );

    // generate a new id if the user doesn't care about it
    m_windowId = id == wxID_ANY ? NewControlId() : id;

    SetName(name);
    SetWindowStyleFlag(style);
    SetParent(parent);

#if wxUSE_VALIDATORS
    SetValidator(validator);
#endif // wxUSE_VALIDATORS

    // if the parent window has wxWS_EX_VALIDATE_RECURSIVELY set, we want to
    // have it too - like this it's possible to set it only in the top level
    // dialog/frame and all children will inherit it by defult
    if ( parent && (parent->GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) )
    {
        SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
    }

    return true;
}

// ----------------------------------------------------------------------------
// destruction
// ----------------------------------------------------------------------------

// common clean up
wxWindowBase::~wxWindowBase()
{
    wxASSERT_MSG( GetCapture() != this, wxT("attempt to destroy window with mouse capture") );

    // FIXME if these 2 cases result from programming errors in the user code
    //       we should probably assert here instead of silently fixing them

    // Just in case the window has been Closed, but we're then deleting
    // immediately: don't leave dangling pointers.
    wxPendingDelete.DeleteObject(this);

    // Just in case we've loaded a top-level window via LoadNativeDialog but
    // we weren't a dialog class
    wxTopLevelWindows.DeleteObject((wxWindow*)this);

    wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );

    // reset the dangling pointer our parent window may keep to us
    if ( m_parent )
    {
        if ( m_parent->GetDefaultItem() == this )
        {
            m_parent->SetDefaultItem(NULL);
        }

        m_parent->RemoveChild(this);
    }

#if wxUSE_CARET
    delete m_caret;
#endif // wxUSE_CARET

#if wxUSE_VALIDATORS
    delete m_windowValidator;
#endif // wxUSE_VALIDATORS

#if wxUSE_CONSTRAINTS
    // Have to delete constraints/sizer FIRST otherwise sizers may try to look
    // at deleted windows as they delete themselves.
    DeleteRelatedConstraints();

    if ( m_constraints )
    {
        // This removes any dangling pointers to this window in other windows'
        // constraintsInvolvedIn lists.
        UnsetConstraints(m_constraints);
        delete m_constraints;
        m_constraints = NULL;
    }
#endif // wxUSE_CONSTRAINTS

    if ( m_containingSizer )
        m_containingSizer->Detach( (wxWindow*)this );

    delete m_windowSizer;

#if wxUSE_DRAG_AND_DROP
    delete m_dropTarget;
#endif // wxUSE_DRAG_AND_DROP

#if wxUSE_TOOLTIPS
    delete m_tooltip;
#endif // wxUSE_TOOLTIPS

#if wxUSE_ACCESSIBILITY
    delete m_accessible;
#endif
}

bool wxWindowBase::Destroy()
{
    delete this;

    return true;
}

bool wxWindowBase::Close(bool force)
{
    wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
    event.SetEventObject(this);
    event.SetCanVeto(!force);

    // return false if window wasn't closed because the application vetoed the
    // close event
    return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
}

bool wxWindowBase::DestroyChildren()
{
    wxWindowList::compatibility_iterator node;
    for ( ;; )
    {
        // we iterate until the list becomes empty
        node = GetChildren().GetFirst();
        if ( !node )
            break;

        wxWindow *child = node->GetData();

        // note that we really want to call delete and not ->Destroy() here
        // because we want to delete the child immediately, before we are
        // deleted, and delayed deletion would result in problems as our (top
        // level) child could outlive its parent
        delete child;

        wxASSERT_MSG( !GetChildren().Find(child),
                      wxT("child didn't remove itself using RemoveChild()") );
    }

    return true;
}

// ----------------------------------------------------------------------------
// size/position related methods
// ----------------------------------------------------------------------------

// centre the window with respect to its parent in either (or both) directions
void wxWindowBase::Centre(int direction)
{
    // the position/size of the parent window or of the entire screen
    wxPoint posParent;
    int widthParent, heightParent;

    wxWindow *parent = NULL;
    wxTopLevelWindow *winTop = NULL;

    if ( !(direction & wxCENTRE_ON_SCREEN) )
    {
        // find the parent to centre this window on: it should be the
        // immediate parent for the controls but the top level parent for the
        // top level windows (like dialogs)
        parent = GetParent();
        if ( IsTopLevel() )
        {
            while ( parent && !parent->IsTopLevel() )
            {
                parent = parent->GetParent();
            }
        }

        // there is no wxTopLevelWindow under wxMotif yet
#ifndef __WXMOTIF__
        // we shouldn't center the dialog on the iconized window: under
        // Windows, for example, this places it completely off the screen
        if ( parent )
        {
            winTop = wxDynamicCast(parent, wxTopLevelWindow);
            if ( winTop && winTop->IsIconized() )
            {
                winTop = NULL;
                parent = NULL;
            }
        }
#endif // __WXMOTIF__

        // did we find the parent?
        if ( !parent )
        {
            // no other choice
            direction |= wxCENTRE_ON_SCREEN;
        }
    }

    if ( direction & wxCENTRE_ON_SCREEN )
    {
        //RN:  If we are using wxDisplay we get
        //the dimensions of the monitor the window is on,

⌨️ 快捷键说明

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