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

📄 mainfrm.cpp

📁 此代码主要实现视图窗口的动态切分
💻 CPP
字号:
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "SingleSplit.h"

#include "MainFrm.h"

#include "SingleSplitView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND_RANGE(ID_SPLITTER_2, ID_SPLITTER_9, OnSplitter)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	// TODO: add member initialization code here
	m_wndSplitter = new CSplitterWnd;
	
}

CMainFrame::~CMainFrame()
{
	if(m_wndSplitter != NULL)
	{
		delete m_wndSplitter;
		m_wndSplitter = NULL;
	}
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers


BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
	// create a splitter with 1 row, 2 columns
	CRect cr; 
	GetClientRect(&cr);//取得客户区的显示区域 
	CSize paneSize1(cr.Width()/2, cr.Height());//设定新view大小
	if (!m_wndSplitter->CreateStatic(this, 1, 2))
	{
		TRACE0("Failed to CreateStaticSplitter\n");
		return FALSE;
 	}

	// add the first splitter pane - the default view in column 0
	if (!m_wndSplitter->CreateView(0, 0,
		pContext->m_pNewViewClass, paneSize1, pContext))
	{
		TRACE0("Failed to create first pane\n");
		return FALSE;
	}

	// add the second splitter pane - an input view in column 1
	if (!m_wndSplitter->CreateView(0, 1,
		RUNTIME_CLASS(CSingleSplitView), paneSize1, pContext))
	{
		TRACE0("Failed to create second pane\n");
		return FALSE;
	}

	// activate the input view
	SetActiveView((CView*)m_wndSplitter->GetPane(0,0));

	return TRUE;
}

// 用户定义的回调函数
BOOL CALLBACK MyWndEnumProc(HWND hWnd, LPARAM ppWndLPARAM)
{
	CWnd * pWndChild = CWnd::FromHandlePermanent(hWnd);
	CWnd ** ppWndTemp = (CWnd**)ppWndLPARAM;
	if(pWndChild && pWndChild->IsKindOf(RUNTIME_CLASS(CView)))
	{
		*ppWndTemp = pWndChild;
		return FALSE;
	}
	else
	{
		*ppWndTemp = NULL;
		return TRUE;
	}
}

void CMainFrame::OnSplitter(UINT nCmdID)
{
	CWnd * pWnd;
	CWnd * pWndToDelete;
	CDocument * pDoc = GetActiveDocument();
	//使用EnumChildWindows查找从CView继承的子窗口
	::EnumChildWindows(m_hWnd, MyWndEnumProc, (LPARAM)&(pWnd));
	if(pWnd == NULL)
	{
		return;
	}
	//发现子窗口,找到级别最高的子窗口,即父窗口为CMainFrame的窗口
	while(lstrcmp(pWnd->GetRuntimeClass()->m_lpszClassName, "CMainFrame"))
	{
		pWndToDelete = pWnd;
		pWnd = pWnd->GetParent();	
	}
	// 确保视图被删除时文档不被删除
	pDoc->m_bAutoDelete = FALSE;
	// 删除视图
	pWndToDelete->DestroyWindow();
	pDoc->m_bAutoDelete = TRUE;
	
	CDocument * pCurrentDoc = GetActiveDocument();
	// 初始化创建上下文相关指针
	CCreateContext Context;
	Context.m_pNewViewClass = RUNTIME_CLASS(CSingleSplitView);
	Context.m_pCurrentDoc = pDoc;
	Context.m_pNewDocTemplate = NULL;
	Context.m_pLastView = NULL;
	Context.m_pCurrentFrame = NULL;
	CView* pNewView = STATIC_DOWNCAST(CView, CreateView(&Context));
	if( pNewView == NULL )
	{
		return;
	}
	//使用CreateView创建的视图 不能自动调用OnInitialUpdate函数,
	//需要人工调用OnInitialUpdate函数或者发送 WM_INITIALUPDATE消息
	pNewView->OnInitialUpdate();
	pNewView->ShowWindow(SW_SHOW); 
	// 使用CreateView创建的视图不会自动显示并且激活,需要人工操作
	SetActiveView(pNewView);
	RecalcLayout();

	//初始化上下文相关指针
	CCreateContext newContext;
	newContext.m_pNewViewClass = RUNTIME_CLASS(CSingleSplitView);
	newContext.m_pCurrentDoc = GetActiveDocument();
	newContext.m_pNewDocTemplate = NULL;
	newContext.m_pLastView = NULL;
	newContext.m_pCurrentFrame = NULL;

	//判断分离器对象是否为空
	if(m_wndSplitter != NULL)
	{
		delete m_wndSplitter;
		m_wndSplitter = NULL;
	}
	m_wndSplitter = new CSplitterWnd;
	
	//重新进行切割
	CRect cr; 
	GetClientRect(&cr);//取得客户区的显示区域 
	int i, j;//控制视图个数
	 
	switch (nCmdID)
	{
		case ID_SPLITTER_2:
			{
				m_wndSplitter->CreateStatic(this, 1,2 );
				for(i = 0; i < 1; i++)
					for(j = 0; j < 2; j++)
					if (!m_wndSplitter->CreateView(i, j,RUNTIME_CLASS(CSingleSplitView), 
						CSize(cr.Width()/2, cr.Height()), &newContext))
					{
						TRACE0("Failed to create second pane\n");
						return ;
					}
			}
			break;
		case ID_SPLITTER_4:
			m_wndSplitter->CreateStatic(this, 2,2 );
			for(i = 0; i < 2; i++)
				for(j = 0; j < 2; j++)
					if (!m_wndSplitter->CreateView(i, j,RUNTIME_CLASS(CSingleSplitView), 
						CSize(cr.Width()/2, cr.Height()/2), &newContext))
					{
						TRACE0("Failed to create second pane\n");
						return ;
					}
					break;
		case ID_SPLITTER_9:
			m_wndSplitter->CreateStatic(this, 3,3 );
			for(i = 0; i < 3; i++)
				for(j = 0; j < 3; j++)
					if (!m_wndSplitter->CreateView(i, j,RUNTIME_CLASS(CSingleSplitView),
						CSize(cr.Width()/3, cr.Height()/3), &newContext))
					{
						TRACE0("Failed to create second pane\n");
						return ;
					}
					
					break;
		default:
			ASSERT(0);
			return;
	}
	
	SetActiveView((CView*)m_wndSplitter->GetPane(0,0));
	RecalcLayout();
	
}

⌨️ 快捷键说明

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