⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splitframe.cpp

📁 这是MFC经典问答书的光盘内容
💻 CPP
字号:
// SplitFrame.cpp : implementation file
//

#include "stdafx.h"
#include "SwitchViewSplitter.h"
#include "SplitFrame.h"

#include "DrawDoc.h"
#include "DrawView.h"
#include "DrawFormView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSplitFrame

IMPLEMENT_DYNCREATE(CSplitFrame, CMDIChildWnd)

CSplitFrame::CSplitFrame()
{
}

CSplitFrame::~CSplitFrame()
{
}

BOOL CSplitFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
	CRect rect;
	GetClientRect( &rect );
	CSize size = rect.Size();
	size.cx /= 2;		// Initial column size
	size.cy /= 2;		// Initial row size

	// 1 - Create first static splitter
	if( !m_wndSplitter1.CreateStatic( this, 1, 2 ) )	// 1 row, 2 cols
	{
		TRACE0( "Failed to create first static splitter\n" );
		return FALSE;
	}

	// 2 - Create left column view
	if( !m_wndSplitter1.CreateView( 0, 0,				// row 0, col 0
							RUNTIME_CLASS( CDrawFormView ), 
							size, pContext ) )
	{
		TRACE0( "Failed to create left view\n" );
		return FALSE;
	}

	// 3 - Create nested static splitter 
	if( !m_wndSplitter2.CreateStatic( &m_wndSplitter1, 2, 1,	// 2 rows, 1 col
							 WS_CHILD | WS_VISIBLE,
							 m_wndSplitter1.IdFromRowCol( 0, 1 ) ) )
	{
		TRACE0( "Failed to create nested static splitter\n" );
		return FALSE;
	}

	// 4 - Create top-right view
	if( !m_wndSplitter2.CreateView( 0, 0,			// row 0, col 0
							RUNTIME_CLASS( CDrawView ), 
							size, pContext ) )
	{
		TRACE0( "Failed to create top-right view\n" );
		return FALSE;
	}

	// 5 - Create bottom-right view
	if( !m_wndSplitter2.CreateView( 1, 0,			// row 1, col 0
							RUNTIME_CLASS( CDrawView ), 
							size, pContext ) )
	{
		TRACE0( "Failed to create bottom-right view\n" );
		return FALSE;
	}

	return TRUE;
}


BEGIN_MESSAGE_MAP(CSplitFrame, CMDIChildWnd)
	//{{AFX_MSG_MAP(CSplitFrame)
	ON_COMMAND(ID_SWITCH_DRAWVIEW, OnSwitchDrawView)
	ON_COMMAND(ID_SWITCH_FORMVIEW, OnSwitchFormView)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

///////////////////////////////////////////////////////////
// Replace the current view in the splitter pSplitter
// at pane (row, col) by a new view of class pViewClass

void EkSwitchViewInSplitter(	CSplitterWnd* pSplitter,
								int row, int col,
								CRuntimeClass* pViewClass )
{
	ASSERT_VALID( pSplitter );
	ASSERT( pViewClass != NULL );

	ASSERT( pViewClass->
				IsDerivedFrom( RUNTIME_CLASS( CView ) ) );

	// 1 - Find the view to be replaced
	CWnd* pPaneWnd = pSplitter->GetPane( row, col );
	if( !pPaneWnd->IsKindOf( RUNTIME_CLASS( CView ) ) )
	{
		TRACE2(	"Unable to switch: pane (%d,%d) is not a view\n",
				row, col );
		return;
	}

	CView* pCurrentView = static_cast<CView*>( pPaneWnd );
	ASSERT_VALID( pCurrentView );
	ASSERT_KINDOF( CView, pCurrentView );

	if( pCurrentView->IsKindOf( pViewClass ) )
	{
		// No need to switch for same view class
		return;
	}

	// 2 - Store current view position and activation state
	CRect rcView;
	pCurrentView->GetWindowRect( &rcView );

	CView* pActiveView = pSplitter->
						GetParentFrame()->GetActiveView();
	BOOL bSaveActive = ( pActiveView == NULL ) 
						|| ( pActiveView == pCurrentView );

	// 3 - Find the associated document
	CDocument* pDoc = pCurrentView->GetDocument();
	ASSERT_VALID( pDoc );

	// 4 - Make sure the document won't self-destruct
	// when current view is destroyed
	BOOL bSaveAutoDelete = pDoc->m_bAutoDelete;
	pDoc->m_bAutoDelete = FALSE;

	// 5 - Destroy the current view
	pCurrentView->DestroyWindow();

	// 6 - Restore document to initial state
	pDoc->m_bAutoDelete = bSaveAutoDelete;

	// 7 - Initialize creation context used by CreateView()
	CCreateContext context;
	context.m_pNewDocTemplate = NULL;
	context.m_pLastView = NULL;
	context.m_pCurrentFrame = NULL;

	context.m_pNewViewClass = pViewClass;
	context.m_pCurrentDoc = pDoc;

	// 8 - Create the new view
	pSplitter->CreateView(	row, col, pViewClass,
							rcView.Size(), &context );

	CView* pNewView = static_cast<CView*>
						( pSplitter->GetPane( row, col ) );
	ASSERT_VALID( pNewView );
	ASSERT_KINDOF( CView, pNewView );

	// 9 - Position the new view like the old one and
	// activate it if needed
	pSplitter->ScreenToClient( &rcView );
	pNewView->MoveWindow( &rcView, TRUE );
	if( bSaveActive )
	{
		pSplitter->GetParentFrame()->SetActiveView( pNewView );
	}
	
	// 10 - Send WM_INITIALUPDATE to the view
	pNewView->GetParentFrame()->InitialUpdateFrame( pDoc, TRUE );
}

/////////////////////////////////////////////////////////////////////////////
// CSplitFrame message handlers

void CSplitFrame::OnSwitchDrawView() 
{
	if( GetActiveView() == m_wndSplitter1.GetPane( 0, 0 ) )
	{
		// Active pane is leftmost in Splitter1
		EkSwitchViewInSplitter(	&m_wndSplitter1, 0, 0,
								RUNTIME_CLASS( CDrawView ) );
	}
	else
	{
		// Active pane is in Splitter2
		int row, col;
		m_wndSplitter2.GetActivePane( &row, &col );
		EkSwitchViewInSplitter(	&m_wndSplitter2, row, col,
								RUNTIME_CLASS( CDrawView ) );
	}
}

void CSplitFrame::OnSwitchFormView() 
{
	if( GetActiveView() == m_wndSplitter1.GetPane( 0, 0 ) )
	{
		// Active pane is leftmost in Splitter1
		EkSwitchViewInSplitter(	&m_wndSplitter1, 0, 0,
								RUNTIME_CLASS( CDrawFormView ) );
	}
	else
	{
		// Active pane is in Splitter2
		int row, col;
		m_wndSplitter2.GetActivePane( &row, &col );
		EkSwitchViewInSplitter(	&m_wndSplitter2, row, col,
								RUNTIME_CLASS( CDrawFormView ) );
	}
}

⌨️ 快捷键说明

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