CSplitterWnd窗口分割之——动态静态嵌套分割(二)

       鉴于CSplitterWnd资料很少(MSDN上也说的很简单,Sample我也就不想吐槽了),同时网上博客又几乎是千篇一律的转载。现将个人的一点经验拿出来和大家分享,希望对他人有所帮助。不足之处还望批评指正。

       最终效果如下:

      分割窗体就是把一个窗体分割成多个面板,面板就是放各种控件或视图的容器。分割窗体有两种形式,静态和动态。两种形式的区别在于动态的可以收拢和展开,静态的则不能。动态分割只能创建2*2的分割窗口,而静态分割可以创建16*16的分割窗口。


       好了,进入正题。在VS或VC++6.0中建立一个多文档或者单文档,按照向导一直下一步即可。本文创建的是多文档,单文档相对简单一些。

       创建好之后,在ChildFrm.h中添加两个窗口分割变量:

// Attributes
protected:
	CSplitterWnd m_wndSplitter1;
	CSplitterWnd m_wndSplitter;

然后选择工程的类视图,右键ChildFrm属性,添加Overrides中的OnCreateClient方法。如果是单文档的话在MainFrm中添加!

修改OnCreateClient方法如下:

BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext)
{
	// Create 2*2 nested dynamic splitter
	 	// TODO: Add your specialized code here and/or call the base class
	 	return m_wndSplitter.Create(this,
	 		2, 2,			// TODO: adjust the number of rows, columns
	 		CSize(10, 10),	// TODO: adjust the minimum pane size
	 		pContext);
	 	//return CMDIChildWnd::OnCreateClient(lpcs, pContext);

	 Create a  static splitter with 1 rows, 3 columns
	//m_wndSplitter.CreateStatic(this, 1, 3);	// create a splitter with 1 rows, 3 columns
	//m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0), pContext);	// create view with 0 rows, 0 columns
	//m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CViewMiddle), CSize(0, 0), pContext);	// create view with 0 rows, 1 columns
	//m_wndSplitter.CreateView(0, 2, RUNTIME_CLASS(CViewRight), CSize(0, 0), pContext);	// create view with 0 rows, 2 columns

	//m_wndSplitter.SetColumnInfo(0, 400, 10);	// set the width of column, 0 column, ideal width is 200dip,min width is 10dip
	//m_wndSplitter.SetColumnInfo(1, 400, 10);	// set the width of column, 0 column, ideal width is 200dip,min width is 10dip
	//m_wndSplitter.SetColumnInfo(2, 400, 10);	// set the width of column, 0 column, ideal width is 200dip,min width is 10dip
	 m_wndSplitter.SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

	//Create a static splitter with 2 rows,1 columns
	if (!m_wndSplitter.CreateStatic(this, 2, 1, WS_CHILD|WS_VISIBLE))
	{
		TRACE("Failed to Create StaticSplitter\n");
		return NULL;
	}
	//set view
	pContext->m_pNewViewClass = RUNTIME_CLASS(CViewRight);
	
	CRect rect;     
	this->GetClientRect(&rect);
	SIZE size;
	size.cx = rect.Width();
	size.cy = rect.Height()/3;

	m_wndSplitter.CreateView(0, 0, pContext->m_pNewViewClass, size, pContext);
	//m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CViewLeft), CSize(0, 0), pContext);	// create view with 0 rows, 0 columns
	//m_wndSplitter.SetRowInfo(0, 200, 10);	// set the width of column, 0 column, ideal width is 250dip,min width is 10dip


	pContext->m_pNewViewClass = RUNTIME_CLASS(CViewMiddle);
	if (!m_wndSplitter1.Create(
		&m_wndSplitter,     // our parent window is the first splitter
		2, 2,          // TODO: adjust the number of rows, columns
		CSize(10, 10), // TODO: adjust the minimum pane size
		pContext,
		WS_CHILD|WS_VISIBLE|SPLS_DYNAMIC_SPLIT|WS_HSCROLL|WS_VSCROLL,
		m_wndSplitter.IdFromRowCol(1, 0)))
	{
		TRACE("Failed to create the nested dynamic splitter\n");
	}

	return TRUE;
}

RUNTIME_CLASS是MFC中的一个宏,用来动态创建一个类。
这里是我做了三种分割方式的测试,第一种是直接创建了一个2*2的动态分割窗口,没有修改视图;第二种是创建的一个一行三列的静态分割窗口,并且分别为之创建了三个视图,然后设置的了每一列的宽度;最后一种是静态分割和动态分割嵌套使用,先使用静态分割,将整个窗口分割成为两行一列,分割完成后为第一行创建视图,设置视图高度为整个窗口的1/3,然后更改视图,使得随后动态分割的窗口绑定不同的视图,再对第二行使用动态分割,将第二行分割成2*2的动态分割窗口。

       CViewLeft、CViewRight、CViewMiddle这三个类均继承自CView,只需重写下每个类的OnDraw方法即可

void CViewLeft::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
	CPaintDC* dc = (CPaintDC*)pDC;
	CRect rect,fillrect;
	CBrush brush;
	brush.CreateSolidBrush(RGB(255, 0, 0));
	this->GetClientRect(&rect);
	dc->FillRect(&rect,&brush);
	brush.DeleteObject();
}

void CViewMiddle::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
	CPaintDC* dc = (CPaintDC*)pDC;
	CRect rect,fillrect;
	CBrush brush;
	brush.CreateSolidBrush(RGB(0, 255, 0));
	this->GetClientRect(&rect);
	dc->FillRect(&rect,&brush);
	brush.DeleteObject();
}


void CViewRight::OnDraw(CDC* pDC)
{
 CDocument* pDoc = GetDocument();
 // TODO: add draw code here
 CPaintDC* dc = (CPaintDC*)pDC;
 CRect rect,fillrect;
 CBrush brush;
 brush.CreateSolidBrush(RGB(0, 0, 255));
 this->GetClientRect(&rect);
 dc->FillRect(&rect,&brush);
 brush.DeleteObject();
}


       一个CSplitterWnd对象通常被嵌入CFrameWnd或CMDIChildWnd父对象。一般使用Create或者CreateStatic分割窗口完毕,可使用SetColumnInfo和SetRowInfo来调整这些最小值,为使用其设置过的行或列则会自动分配大小。


定制属于自己的SplitterWnd:拖动滚动条时只显示一行或者一列

/*****************************************************************

Filename:			Splitter.h
Contents:			Implemetation of CSplitter class

Authors:	
Created date: 	  	
Last Modified date:	
Revision History: 

Used by:			
Uses:				
Build Notes:		

See Also:			

Copyright: 		(c) 2015 by All rights reserved.                           

*********************
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MFC(Microsoft Foundation Class)是微软提供的一种C++类库,用于快速开发Windows界面应用程序。其中的拆分窗口可以有效地将窗口分割成多个子窗口,方便用户在一个窗口中同时显示多个视图或控件。 动态拆分示例是指在程序运行时根据用户的操作或其他条件来动态地改变拆分窗口的布局。以一个简单的文本编辑器为例,用户可能希望在编辑文本的同时查看另一部分文档内容。在这种情况下,可以使用动态拆分窗口来实现在编辑区域和预览区域的同时显示。 在MFC中,可以使用拆分窗口类(CSplitterWnd)来实现动态拆分窗口。通过在代码中响应用户的操作或其他条件的变化,可以动态地改变拆分窗口的布局。比如,可以通过捕获用户的鼠标事件来改变拆分窗口的大小和位置,或者根据用户的选择来动态地增加或减少子窗口的数量。 动态拆分窗口的实现需要一定的编程经验和理解MFC的相关知识。在使用MFC的拆分窗口进行动态拆分时,需要根据具体的需求和UI设计来选择合适的拆分方式和布局。同时,为了提高用户体验,还需要注意在动态改变拆分窗口布局时保持界面的流畅和稳定。 总之,MFC的拆分窗口提供了丰富的功能和灵活的布局方式,可以通过动态拆分实现更加灵活和复杂的界面布局。通过合理的设计和实现,动态拆分窗口可以为用户提供更加便捷和高效的操作体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值