MFC基于CSplitterWnd类的多窗口分割

使用平台:win7 64bit

使用环境:VS2012

1、CSplitterWnd介绍


上图是从MSDN中截取的类的继承图表,CSplitterWnd类继承自CWnd类。这个类主要就是提供窗口分割的功能。


2、使用CSplitterWnd类作窗口分割

建立单文档程序,选择不支持文档-视图框架。目的是为了使得程序结构更加的灵活,适合自己DIY。建立好的程序结构中就回存在有三个基础的类。

CXXXApp类        tips: (XXX)是建立工程的时候自己取得名字,代表的是这个工程的实例

CChildView类

CMainFrame类

窗口的分割要在CMainFrame类中进行完成。目前例子里面我们分割出如图所示的效果:


从上图中可以看到窗口分割成了5个部分,左边的白色部分和右边的四个黑色窗口部分。

在CMainFrame类中添加两个成员:

CSplitterWnd m_spliter1;               //原版的CSplitterWnd
CMySplitterWndEx m_spliter2;     //在CSplitterWnd上做修改之后

然后重载CMainFrame类的OnCreateClient()函数,在该函数中添加如下代码:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	CRect rct;
	GetClientRect(&rct);								//获取窗口大小
	int nRcWidth = rct.Width();
	int nRcHeight = rct.Height();

	//用第一个分隔条分割成1行2列
	if(m_spliter1.CreateStatic(this, 1, 2)==NULL) return FALSE;
	//分割的第一行第一列指定动态创建对象CLeftView
	//指定窗口宽度是1/4界面宽度,高度为整个界面高度
	m_spliter1.CreateView(0,0,RUNTIME_CLASS(CLeftView),CSize(nRcWidth / 4, nRcHeight), pContext);
	
	//对m_spliter1分割的第二个区域再使用m_spliter2进行分割,分割成2*2个区域
	if (m_spliter2.CreateStatic(&m_spliter1, 2, 2, WS_CHILD|WS_VISIBLE, m_spliter1.IdFromRowCol(0, 1)) == NULL) return FALSE;
	//和上述差不多,指定动态创建的对象为CLTView
	m_spliter2.CreateView(0, 0, RUNTIME_CLASS(CLTView), CSize(nRcWidth / 8 * 3, nRcHeight/2), pContext);
	m_spliter2.CreateView(0, 1, RUNTIME_CLASS(CLTView), CSize(nRcWidth / 8 * 3, nRcHeight/2), pContext);
	m_spliter2.CreateView(1, 0, RUNTIME_CLASS(CLTView), CSize(nRcWidth / 8 * 3, nRcHeight/2), pContext);
	m_spliter2.CreateView(1, 1, RUNTIME_CLASS(CLTView), CSize(nRcWidth / 8 * 3, nRcHeight/2), pContext);

	return CFrameWnd::OnCreateClient(lpcs, pContext);
}
上述代码中的CLeftView和CLTView都是自己向工程中添加的类。详细的可以看分享的代码(博文结尾处)。当然,在MFC中默认生成的CChildView类和相关的程序我都已经把它们删掉或者注释掉了,为了是更清晰的程序结构。

3、分割条的风格DIY

       在上面的代码中两个风格条中有一个分割条是自己在原有的分割条上DIY后的,所有才有了黑底蓝色线条的分割,然而默认的分割风格是比较丑陋的。下面来DIY这个类。

向工程中添加一个MFC,记住是MFC类,很关键!!!

选择其父类为CWnd,因为选择框里面并不能选择CSplitterWnd类,生成之后我们手动把他的继承类改成CSplitterWnd。添加鼠标左键按下的消息响应,并重载OnDrawSplittter函数。

类的定义就成了这个样子(名字可以随便取),为什么前面说的是要添加MFC类?因为MFC类里面才会给我们自动的添加上DECLARE_DYNAMIC(),DELARE_MESSAGE_MAP()这样的宏。也就才能有消息响应的发生。不然这里重载的OnDrawSplittter是无法生效的。

class CMySplitterWndEx : public CSplitterWnd
{
	DECLARE_DYNAMIC(CMySplitterWndEx)

public:
	CMySplitterWndEx();
	virtual ~CMySplitterWndEx();

protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	virtual void OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rect);
};

在类的构造函数里面就可以对分割条的Size进行调整了。

CMySplitterWndEx::CMySplitterWndEx()
{
	m_cxSplitterGap = 2;
	m_cxSplitter = 5;
	m_cySplitterGap = 2;
	m_cySplitter = 5;
}
这个是调整分割条横向和竖向的宽度,默认的宽度是10,太宽了不好看!宽度修改了之后再修改颜色。在OnDrawSplittter函数中。

void CMySplitterWndEx::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rect)
{
	CSplitterWnd::OnDrawSplitter(pDC, nType, rect);
	if (pDC != NULL)
	{
		CBrush  brush;
		brush.CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
		pDC->FillRect(&rect,&brush);
	}
}
很好理解,这个函数就和视图宽口中的OnDraw的功能差不多。

鼠标左键的消息响应纯粹是为了不想让鼠标左键拖动风格窗条的。也就是在消息传递中截获该消息,不让它传向基类。

4、管理分割窗口

         分割后窗口之间怎么通信?怎么进行相互数据交互?如果不能管理好分割的窗口,很容易使得程序的框架变得混乱。给维护和升级带来很大的麻烦。这个有过相关痛苦经历的人肯定有切身的体会。首先试图窗口都在CMainFrame类中进行创建的,CMainFrame类的对象指针也是很容易获取的。那么我们就可以再CMainFrame类中记录所有视图窗口的对象指针,然后通过访问CMainFrame类的成员来对我们想要交互的窗口进行操作。这样就很好的解决了这个问题,也使得在修改窗口分割后不用大量的去修改原来的视图窗口的代码。具体做法:
在CMainFrame类中添加成员。


然后在分割窗口后就用创建好的成员指向关联的窗口。



这样在视图窗口中就可以直接一句代码就可以访问到想访问的类了:
((CMainFrame*)AfxGetMainWnd())

((CMainFrame*)AfxGetMainWnd())->你想访问的视图


下载链接


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空空的司马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值