关闭

MFC基于CSplitterWnd类的多窗口分割

标签: mfcvs2012结构
7325人阅读 评论(0) 收藏 举报
分类:

使用平台: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())->你想访问的视图


下载链接


2
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

CSplitterWnd的使用

一、关于CSplitterWnd类 我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割。 那么我们自己如...
  • netanimals
  • netanimals
  • 2012-04-25 09:26
  • 13738

CSplitterWnd

MFC支持两种类型的拆分窗口:静态的和动态的。 静态拆分窗口的行列数在拆分窗口被创建时就设置好了,用户不能更改。但是用户可以缩放各行各列。一个静态拆分窗口最多可以包含16行16列。 要找一...
  • zang141588761
  • zang141588761
  • 2015-10-19 11:33
  • 1044

使用CSplitterWnd类创建分割窗口,并实现数据交互

使用CsplitterWnd类创建分割窗口,并实现数据交互
  • u013947807
  • u013947807
  • 2016-12-08 22:06
  • 802

扩展CSplitterWnd——实现隐藏分割条的功能

Create动态拆分:     动态拆分是对同一个视图进行分隔,各个分隔窗口内容相同,但各自独立控制视野范围,可以显示同一文档的不同部分,允许分隔的窗口内有一个分隔条,可用鼠标拖拽分隔条调整各窗口大...
  • hsp494980719
  • hsp494980719
  • 2012-10-24 17:53
  • 1703

使用CSplitterWnd实现拆分窗口(多视图显示)

MFC支持两种类型的拆分窗口:静态的和动态的。 静态拆分窗口的行列数在拆分窗口被创建时就设置好了,用户不能更改。但是用户可以缩放各行各列。一个静态拆分窗口最多可以包含16行16列。 要找一个使用了...
  • xshown
  • xshown
  • 2011-08-30 10:53
  • 9166

CSplitterWnd类分割MFC单文档应用程序窗口

前言 网上其他大牛已经对MFC窗口分割进行了详细介绍,这里主要用意是分享我在做窗口分割的经验,若是对大家能够有所帮助的话,我倍感荣幸,由于本人水平有限,如若本文中出现错误,望大家见谅与指正! 工具...
  • m_buddy
  • m_buddy
  • 2016-03-04 15:32
  • 1849

关于mfc CSplitterWnd的几点理解

1.首先是CsplitterWnd的关键的几个参数 // implementation attributes which control layout of the splitter int ...
  • abcdef8c
  • abcdef8c
  • 2012-08-20 15:41
  • 3041

MFC下分割CSplitterWnd窗口等比例缩放

http://blog.csdn.net/ruihaha/article/details/38018231 在MFC中添加CSplitterWnd分割窗口后,屏幕分为2*2区域,    当用鼠标...
  • ruihaha
  • ruihaha
  • 2015-01-29 10:35
  • 1660

MFC窗口分割/拆分

参考资料 [1]基于MFC的窗口拆分 [2]VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口) [3]MFC分割窗口的实现
  • Q1302182594
  • Q1302182594
  • 2015-04-19 20:54
  • 6832

MFC 任意分割窗口的小结(CSplitterWndEx)

在头文件MainFrm.h,中定义三个分割类对象:CSplitterWndEx m_wndSplitter; CSplitterWndEx m_wndSplitter2; CSplitterWnd...
  • bao_bei
  • bao_bei
  • 2017-03-03 11:33
  • 689
    个人资料
    • 访问:217826次
    • 积分:3444
    • 等级:
    • 排名:第11254名
    • 原创:108篇
    • 转载:10篇
    • 译文:0篇
    • 评论:103条
    博客专栏
    最新评论