CSplitterWnd类分割MFC单文档应用程序窗口
2023-09-11 14:22:29 时间
前言
网上其他大牛已经对MFC窗口分割进行了详细介绍,这里主要用意是分享我在做窗口分割的经验,若是对大家能够有所帮助的话,我倍感荣幸,由于本人水平有限,如若本文中出现错误,望大家见谅与指正!
工具函数
MFC窗口分割的作案工具主要是CSplitterWnd类成员函数CreateStatic()与CreateView(),CreateStatic()函数用于分割窗口,可以利用返回值判断分割是否成功;CreateView()函数用于关联相关的视图类。两个函数的原型为:
virtual BOOL CreateStatic(
CWnd* pParentWnd,
int nRows,
int nCols,
DWORD dwStyle = WS_CHILD | WS_VISIBLE,
UINT nID = AFX_IDW_PANE_FIRST
);
pParentWnd:父窗口指针,第一次分割指定为this;nRows:分割出来窗口的行数;nCols:分割出来窗口的列数;dwStyle:分割窗口的属性;nID:对于需要再次分割窗口的ID;
virtual BOOL CreateView(
int row,
int col,
CRuntimeClass* pViewClass,
SIZE sizeInit,
CCreateContext* pContext
);
row:需要关联视图类的行索引(
以0开始);col:需要关联视图类的列索引(
以0开始);pViewClass:一般通过宏定义的“函数”RUNTIME_CLASS()得到需要关联的视图运行之间类;sizeInit:子窗口的尺寸;pContext:填写OnCreateClient()函数传递进来的环境参数。
实现
定义分割窗口类对象,在CMainFrame头文件类定义中定义:
CSplitterWnd m_splitwnd;
CSplitterWnd m_subsplitwnd;
对于需要关联的View类可以在CMainFrame头文件类定义中添加相关的声明,添加的同时要添加相关类的头文件,方便进行管理。
CsplitwindView* m_psplitwnd;
CDialogView* m_pdialogview;
CDialogSub* m_pdialogsub;
注明:在调试的时候可能会出现如下的错误,需要在相关View类头文件中添加XXXdoc.h,View类xxxdoc.h要在xxxView.h前面。
1>error C2143: 语法错误 : 缺少“;”(在“*”的前面)
1>error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>warning C4183: “GetDocument”: 缺少返回类型;假定为返回“int”的成员函数
1>error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>warning C4183: “GetDocument”: 缺少返回类型;假定为返回“int”的成员函数
重写 CMainFrame::OnCreateClient()函数进行窗口分割
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类
CRect rect;
GetClientRect(&rect);
int nwidth(rect.right);
int nheight(rect.bottom); //获取客户区窗口大小
if (!m_splitwnd.CreateStatic(this, 1, 2)) //窗口分割
{
MessageBox(_T("分割窗口错误"), _T("Error"), MB_OK|MB_ICONERROR);
return false;
}
//关联相关的View类
m_splitwnd.CreateView(0, 0, RUNTIME_CLASS(CsplitwindView), CSize(nwidth/6*3, nheight), pContext);
m_psplitwnd = (CsplitwindView*)m_splitwnd.GetPane(0, 0);
//对子窗口进行在分割
if (!m_subsplitwnd.CreateStatic(&m_splitwnd, 2, 1, WS_VISIBLE|WS_CHILD, m_splitwnd.IdFromRowCol(0,1)))
{
MessageBox(_T("子窗口分割窗口错误"), _T("Error"), MB_OK | MB_ICONERROR);
return false;
}
//关联相关的View类
m_subsplitwnd.CreateView(0, 0, RUNTIME_CLASS(CDialogView), CSize(nwidth/6*3, nheight/2), pContext);
m_pdialogview = (CDialogView*)m_subsplitwnd.GetPane(0, 0);
m_subsplitwnd.CreateView(1, 0, RUNTIME_CLASS(CDialogSub), CSize(nwidth/6*3, nheight/2), pContext);
m_pdialogsub = (CDialogSub*)m_subsplitwnd.GetPane(1, 0);
m_splitwnd.SetActivePane(0, 0);
return true;
//return CFrameWnd::OnCreateClient(lpcs, pContext);
}
上面第二次调用CreateStaic()函数是对子窗口的第二次分割,上面关联的CsplitwindView为工程向导创建的,CDialogView与CdialogSub是相关的对话框类,他们的创建步骤为:1.创建相关的对话框资源;2.对话框的属性Style选择为child,border属性选择为none,否则会报错;3.添加对话框类将其派生自CFormView类。
注意:在单文档窗口分割的OnCreateClient()函数中返回值直接返回true,不要返回上面注释类的代码,否则窗口分割不成功。
运行效果如图:
对于分割出来的窗口样式问题,可以继承CSplitterWnd类,但是不能直接继承,因为没这个选项,可以继承他的父类CWnd类,再将CWnd改为CSplitterWnd。在修改继承的类中的函数就可以DIY相应的分割窗口风格,至于怎么固定分割窗口的大小,可以使相应的鼠标消息不执行相应的动作即可,也就是没有处理代码。可以参考他的博客
http://blog.csdn.net/robin__chou/article/details/49963575
MFC文档视图框架
在某些情况下可能会在View类中调用Frame类中的函数或变量、Frame类中调用View类中的函数或变量、Frame类中调用Doc类中函数或变量
如:Frame类中调用View类中函数可以使用GetActiveView()
函数来获取视图类指针,接着便可以调用相应部分的View类函数和变量。对于Frame中调用Doc类也是一样的道理
CMxxxxView *pView = (CxxxxView*)GetActiveView();
View类中调用Frame类中函数可以使用GetParentFrame()
函数来获取窗口类指针,接着便可以调用相应部分的Frame类函数和变量。对于View中调用Doc类也是一样的道理
CMainFrame* pFrame = (CMainFrame*)GetParentFrame();
因而只要知道View,Frame,Doc,App之间相互访问的关系,就可以利用他们之间的关系,方便地调用相应的类成员变量和函数。
相关文章
- [Hadoop]Sqoop 1.4.2中文文档(三)之SqoopJob与其外的操作
- 模板文件不存在,无法解析文档”的几种解决办法
- MFC单文档应用程序显示图像
- 三步去掉 Word 2010 文档页眉上的横线
- rest api方式实现对文档库的管理
- 使用Java客户端操作elasticsearch--设置mappings、添加文档、查询数据
- Atitit ppt转换文本txt 目录 1.1. Atitit word ppt excel convert txt bp 等文档转换纯文本问题最佳实践.docx1 1.2. 跨语言转换Open
- Atitit 微信小程序的部署流程文档 目录 1.1. 设置https 参照 Atitit tomcat linux 常用命令1 1.2. 增加证书 腾讯云和阿里云都可申请免费证书,但要一天
- Atitit.cateService分类管理新特性与设计文档说明v1
- scConverter 文档转换 DLL / SDK
- [Docker 官方文档] 理解 Docker
- C++MFC编程笔记day05 文档类-单文档和多文档应用程序
- 使用Zuul聚合多个微服务的Swagger文档
- 〖Python自动化办公篇⑧〗- word文件自动化 - 创建并生成 word 文档