mdig.cpp

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

CPP
820
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        src/generic/mdig.cpp
// Purpose:     Generic MDI (Multiple Document Interface) classes
// Author:      Hans Van Leemputten
// Modified by:
// Created:     29/07/2002
// RCS-ID:      $Id: mdig.cpp,v 1.21 2005/08/16 20:22:54 ABX Exp $
// Copyright:   (c) Hans Van Leemputten
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

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

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

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

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

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/panel.h"
    #include "wx/menu.h"
    #include "wx/intl.h"
#endif //WX_PRECOMP

#include "wx/generic/mdig.h"
#include "wx/stockitem.h"

enum MDI_MENU_ID
{
    wxWINDOWCLOSE = 4001,
    wxWINDOWCLOSEALL,
    wxWINDOWNEXT,
    wxWINDOWPREV
};

//-----------------------------------------------------------------------------
// wxGenericMDIParentFrame
//-----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIParentFrame, wxFrame)

BEGIN_EVENT_TABLE(wxGenericMDIParentFrame, wxFrame)
#if wxUSE_MENUS
    EVT_MENU (wxID_ANY, wxGenericMDIParentFrame::DoHandleMenu)
#endif
END_EVENT_TABLE()

wxGenericMDIParentFrame::wxGenericMDIParentFrame()
{
    Init();
}

wxGenericMDIParentFrame::wxGenericMDIParentFrame(wxWindow *parent,
                                   wxWindowID id,
                                   const wxString& title,
                                   const wxPoint& pos,
                                   const wxSize& size,
                                   long style,
                                   const wxString& name)
{
    Init();

    (void)Create(parent, id, title, pos, size, style, name);
}

wxGenericMDIParentFrame::~wxGenericMDIParentFrame()
{
    // Make sure the client window is destructed before the menu bars are!
    wxDELETE(m_pClientWindow);

#if wxUSE_MENUS
    if (m_pMyMenuBar)
    {
        delete m_pMyMenuBar;
        m_pMyMenuBar = (wxMenuBar *) NULL;
    }

    RemoveWindowMenu(GetMenuBar());

    if (m_pWindowMenu)
    {
        delete m_pWindowMenu;
        m_pWindowMenu = (wxMenu*) NULL;
    }
#endif // wxUSE_MENUS
}

bool wxGenericMDIParentFrame::Create(wxWindow *parent,
                              wxWindowID id,
                              const wxString& title,
                              const wxPoint& pos,
                              const wxSize& size,
                              long style,
                              const wxString& name)
{
  // this style can be used to prevent a window from having the standard MDI
  // "Window" menu
  if ( !(style & wxFRAME_NO_WINDOW_MENU) )
  {
#if wxUSE_MENUS
      m_pWindowMenu = new wxMenu;

      m_pWindowMenu->Append(wxWINDOWCLOSE,    _("Cl&ose"));
      m_pWindowMenu->Append(wxWINDOWCLOSEALL, _("Close All"));
      m_pWindowMenu->AppendSeparator();
      m_pWindowMenu->Append(wxWINDOWNEXT,     _("&Next"));
      m_pWindowMenu->Append(wxWINDOWPREV,     _("&Previous"));
#endif // wxUSE_MENUS
  }

  wxFrame::Create( parent, id, title, pos, size, style, name );

  OnCreateClient();

  return true;
}

#if wxUSE_MENUS
void wxGenericMDIParentFrame::SetWindowMenu(wxMenu* pMenu)
{
    // Replace the window menu from the currently loaded menu bar.
    wxMenuBar *pMenuBar = GetMenuBar();

    if (m_pWindowMenu)
    {
        RemoveWindowMenu(pMenuBar);

        wxDELETE(m_pWindowMenu);
    }

    if (pMenu)
    {
        m_pWindowMenu = pMenu;

        AddWindowMenu(pMenuBar);
    }
}

void wxGenericMDIParentFrame::SetMenuBar(wxMenuBar *pMenuBar)
{
    // Remove the Window menu from the old menu bar
    RemoveWindowMenu(GetMenuBar());
    // Add the Window menu to the new menu bar.
    AddWindowMenu(pMenuBar);

    wxFrame::SetMenuBar(pMenuBar);
}
#endif // wxUSE_MENUS

void wxGenericMDIParentFrame::SetChildMenuBar(wxGenericMDIChildFrame *pChild)
{
#if wxUSE_MENUS
    if (pChild  == (wxGenericMDIChildFrame *) NULL)
    {
        // No Child, set Our menu bar back.
        SetMenuBar(m_pMyMenuBar);

        // Make sure we know our menu bar is in use
        m_pMyMenuBar = (wxMenuBar*) NULL;
    }
    else
    {
        if (pChild->GetMenuBar() == (wxMenuBar*) NULL)
            return;

        // Do we need to save the current bar?
        if (m_pMyMenuBar == NULL)
            m_pMyMenuBar = GetMenuBar();

        SetMenuBar(pChild->GetMenuBar());
    }
#endif // wxUSE_MENUS
}

bool wxGenericMDIParentFrame::ProcessEvent(wxEvent& event)
{
    /*
     * Redirect events to active child first.
     */

    // Stops the same event being processed repeatedly
    static wxEventType inEvent = wxEVT_NULL;
    if (inEvent == event.GetEventType())
        return false;

    inEvent = event.GetEventType();

    // Let the active child (if any) process the event first.
    bool res = false;
    if (m_pActiveChild && event.IsKindOf(CLASSINFO(wxCommandEvent))
#if 0
        /* This is sure to not give problems... */
        && (event.GetEventType() == wxEVT_COMMAND_MENU_SELECTED ||
            event.GetEventType() == wxEVT_UPDATE_UI )
#else
        /* This was tested on wxMSW and worked... */
        && event.GetEventObject() != m_pClientWindow
        && !(event.GetEventType() == wxEVT_ACTIVATE ||
             event.GetEventType() == wxEVT_SET_FOCUS ||
             event.GetEventType() == wxEVT_KILL_FOCUS ||
             event.GetEventType() == wxEVT_CHILD_FOCUS ||
             event.GetEventType() == wxEVT_COMMAND_SET_FOCUS ||
             event.GetEventType() == wxEVT_COMMAND_KILL_FOCUS )
#endif
       )
    {
        res = m_pActiveChild->GetEventHandler()->ProcessEvent(event);
    }

    // If the event was not handled this frame will handle it!
    if (!res)
    {
        res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
    }

    inEvent = wxEVT_NULL;

    return res;
}

wxGenericMDIChildFrame *wxGenericMDIParentFrame::GetActiveChild() const
{
    return m_pActiveChild;
}

void wxGenericMDIParentFrame::SetActiveChild(wxGenericMDIChildFrame* pChildFrame)
{
    m_pActiveChild = pChildFrame;
}

wxGenericMDIClientWindow *wxGenericMDIParentFrame::GetClientWindow() const
{
    return m_pClientWindow;
}

wxGenericMDIClientWindow *wxGenericMDIParentFrame::OnCreateClient()
{
#if wxUSE_GENERIC_MDI_AS_NATIVE
    m_pClientWindow = new wxMDIClientWindow( this );
#else
    m_pClientWindow = new wxGenericMDIClientWindow( this );
#endif
    return m_pClientWindow;
}

void wxGenericMDIParentFrame::ActivateNext()
{
    if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
    {
        size_t active = m_pClientWindow->GetSelection() + 1;
        if (active >= m_pClientWindow->GetPageCount())
            active = 0;

        m_pClientWindow->SetSelection(active);
    }
}

void wxGenericMDIParentFrame::ActivatePrevious()
{
    if (m_pClientWindow && m_pClientWindow->GetSelection() != -1)
    {
        int active = m_pClientWindow->GetSelection() - 1;
        if (active < 0)
            active = m_pClientWindow->GetPageCount() - 1;

        m_pClientWindow->SetSelection(active);
    }
}

void wxGenericMDIParentFrame::Init()
{
    m_pClientWindow = (wxGenericMDIClientWindow *) NULL;
    m_pActiveChild = (wxGenericMDIChildFrame *) NULL;
#if wxUSE_MENUS
    m_pWindowMenu = (wxMenu *) NULL;
    m_pMyMenuBar = (wxMenuBar*) NULL;
#endif // wxUSE_MENUS
}

#if wxUSE_MENUS
void wxGenericMDIParentFrame::RemoveWindowMenu(wxMenuBar *pMenuBar)
{
    if (pMenuBar && m_pWindowMenu)
    {
        // Remove old window menu
        int pos = pMenuBar->FindMenu(_("&Window"));
        if (pos != wxNOT_FOUND)
        {
            wxASSERT(m_pWindowMenu == pMenuBar->GetMenu(pos)); // DBG:: We're going to delete the wrong menu!!!
            pMenuBar->Remove(pos);
        }
    }
}

void wxGenericMDIParentFrame::AddWindowMenu(wxMenuBar *pMenuBar)
{
    if (pMenuBar && m_pWindowMenu)
    {
        int pos = pMenuBar->FindMenu(wxGetStockLabel(wxID_HELP,false));
        if (pos == wxNOT_FOUND)
        {
            pMenuBar->Append(m_pWindowMenu, _("&Window"));
        }
        else
        {
            pMenuBar->Insert(pos, m_pWindowMenu, _("&Window"));
        }
    }
}

void wxGenericMDIParentFrame::DoHandleMenu(wxCommandEvent &event)
{
    switch (event.GetId())
    {
    case wxWINDOWCLOSE:
        if (m_pActiveChild)
        {
            m_pActiveChild->Close();
        }
        break;
    case wxWINDOWCLOSEALL:
        {
#if 0   // code is only needed if next #if is set to 0!
            wxGenericMDIChildFrame *pFirstActiveChild = m_pActiveChild;
#endif
            while (m_pActiveChild)
            {
                if (!m_pActiveChild->Close())
                {
                    return; // We failed...
                }
                else
                {
#if 1   // What's best? Delayed deleting or immediate deleting?
                    delete m_pActiveChild;
                    m_pActiveChild = NULL;
#else
                    ActivateNext();

                    if (pFirstActiveChild == m_pActiveChild)
                        return; // We've called Close on all items, no need to continue.
#endif
                }
            }
        }
        break;
    case wxWINDOWNEXT:
        ActivateNext();
        break;
    case wxWINDOWPREV:
        ActivatePrevious();
        break;
    default :
        event.Skip();
    }
}
#endif // wxUSE_MENUS

void wxGenericMDIParentFrame::DoGetClientSize(int *width, int *height) const
{
    wxFrame::DoGetClientSize( width, height );
}


//-----------------------------------------------------------------------------
// wxGenericMDIChildFrame
//-----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS(wxGenericMDIChildFrame, wxPanel)

BEGIN_EVENT_TABLE(wxGenericMDIChildFrame, wxPanel)
    EVT_MENU_HIGHLIGHT_ALL(wxGenericMDIChildFrame::OnMenuHighlight)
    EVT_ACTIVATE(wxGenericMDIChildFrame::OnActivate)

    EVT_CLOSE(wxGenericMDIChildFrame::OnCloseWindow)
    EVT_SIZE(wxGenericMDIChildFrame::OnSize)
END_EVENT_TABLE()

wxGenericMDIChildFrame::wxGenericMDIChildFrame()
{
    Init();
}

wxGenericMDIChildFrame::wxGenericMDIChildFrame( wxGenericMDIParentFrame *parent,
      wxWindowID id, const wxString& title,
      const wxPoint& WXUNUSED(pos), const wxSize& size,
      long style, const wxString& name )
{
    Init();

    Create( parent, id, title, wxDefaultPosition, size, style, name );
}

#include "wx/log.h"
wxGenericMDIChildFrame::~wxGenericMDIChildFrame()
{
    wxGenericMDIParentFrame *pParentFrame = GetMDIParentFrame();

⌨️ 快捷键说明

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