VS2017MFC单文档视图分割

本文详述了在Visual Studio 2017中使用MFC框架进行复杂视图分割的方法,包括创建单文档项目、添加对话框资源、创建CFormView类、分割视图以及在对话框中添加和配置控件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:VS2017、Win10
语言:C++
说明:用VS2015可以很方便的进行单文档的视图分割,将界面分成多个右对话框组成的界面。但在VS2017中,无法用类向导创建一个继承自CFormView类与对话框关联,所以分割视图不是很方便,我在看过多篇文章后总结出一种用VS2017分割视图的方法,以此记录。
结果:如下图,左半边是一个带有TeeChart控件的对话框,右半边又分为两行,第一行是继承自CView类的空白行,和新建的单文档界面一样,第二行是一个带有列表控件的对话框。图一
第一步:创建单文档MFC项目
用VS2017正常创建一个单文档项目,并运行,结果如下图所示:
在这里插入图片描述
第二步:添加对话框资源
在资源视图中创建两个对话框,默认ID分别为IDD_DIALOG1、IDD_DIALOG1,可根据自己的喜好修改。然后修改两个对话框的属性:‘Border属性改为None’、‘Style改为Child’。如下图:
在这里插入图片描述
第三步:为两个对话框创建继承自CFormView的类
首先点击VS菜单栏的‘视图->类向导’,打开类向导后,然后点击‘添加类->MFC类’,类名设为‘CDlg1’,可更改,基类选择‘CView’。如下图所示:
在这里插入图片描述
按照上述方法再生成一个类名为‘CDlg2’继承自CView的类。
打开CDlg1.h头文件,可看到刚刚生成的类的定义,将‘class CDlg1 : public CView’修改为‘class CDlg1 : public CFormView’,,让它继承自CFormView类。在类中添加如下代码:

#ifdef AFX_DESIGN_TIME
 enum { IDD = IDD_DIALOG1};
#endif

修改结果如下图:
在这里插入图片描述
IDD应等于对话框1的ID,然后打开CDlg1.cpp文件,可看到如下代码

在这里插入图片描述
修改为:

在这里插入图片描述按照如上步骤修改生成的第二个类CDlg2。修改完成后运行程序,看有无错误发生,若有,按照提示修改错误。运行结果和刚创建完项目的运行结果一样,因为我们才为两个对话框生成了继承自CFormView的类,还未进行视图分割。
第四步:分割视图
打开MainFrm.cpp文件,添加如下头文件:

#include "CSDNDoc.h"
#include "CSDNView.h"
#include "CDlg1.h"
#include "CDlg2.h"

注意第一个头文件和第二个头文件名称应和自己工程中的名称一致,因为我的工程名为‘CSDN’,所以是CSDN+Doc.h和CSDN+View.h,并且这两个头文件顺序不能互换,CSDN+Doc.h必须在CSDN+View.h的前面,否则编译时会报错。报错形式如下图:
在这里插入图片描述
然后打开类向导,类名选择CMainFrame,在‘虚函数’中搜索‘create’,选择OnCreateClient,点击‘添加函数’,再点击‘编辑代码’,就可以看到已成功向MainFrm.cpp添加虚函数,过程如下图所示:
在这里插入图片描述
在这里插入图片描述
接下来就要在这个虚函数中添加分割视图的代码
1.在CMainFrame类中添加两个CSplitterWnd类型的变量m_wndSplitter,m_wndSplitter1;

public:
 CSplitterWnd m_wndSplitter, m_wndSplitter1;

2.先将视图分成一行两列

if (!m_wndSplitter.CreateStatic(this, 1, 2))
  return FALSE;

3.再将左边的视图(即0行0列)与第一个对话框关联,并设定其宽度为整个视图的一般,高度和整个视图一样高。RUNTIME_CLASS()的参数为与第一个对话框关联的类CDlg1

CRect rc;
GetClientRect(&rc);//获取整个视图大小
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CDlg1), CSize(rc.Width() / 2, rc.Height()), pContext))
  return FALSE;

4.将右边视图再分成两行一列

if (!m_wndSplitter1.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD | WS_VISIBLE, m_wndSplitter.IdFromRowCol(0, 1)))
  return FALSE;

5.将第一行与原视图关联,RUNTIME_CLASS()中的参数为原视图类CCSDNView;将第二行与第二个对话框关联,RUNTIME_CLASS()中的参数为第二个对话框关联的类CDlg2

if (!m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CCSDNView), CSize(rc.Width() / 2, rc.Height() / 4), pContext))
  return FALSE;
if (!m_wndSplitter1.CreateView(1, 0, RUNTIME_CLASS(CDlg2), CSize(rc.Width() / 2, rc.Height() - rc.Height() / 4), pContext))
  return FALSE;

6.整合全部代码如下:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
  CRect rc;
  // 获取框架窗口客户区的CRect对象   
   GetClientRect(&rc);
   // 创建静态分割窗口,一行二列   
   if (!m_wndSplitter.CreateStatic(this, 1, 2))
    return FALSE;
    // 将第0行0列与对话框一关联
   if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CDlg1), CSize(rc.Width() / 2, rc.Height()), pContext))
    return FALSE;
    //在第0行1列上创建一个两行一列的分割窗口
   if (!m_wndSplitter1.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD | WS_VISIBLE,   m_wndSplitter.IdFromRowCol(0, 1)))
    return FALSE;
   //分别关联视图
   if (!m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CCSDNView), CSize(rc.Width() / 2, rc.Height() / 4), pContext))
    return FALSE;
   if (!m_wndSplitter1.CreateView(1, 0, RUNTIME_CLASS(CDlg2), CSize(rc.Width() / 2, rc.Height() - rc.Height() / 4), pContext))
    return FALSE;
   return TRUE;
}

第五步:在对话框中添加控件并为控件关联变量
1.在资源视图中打开对话框一和二,分别拖入TeeChart控件和列表控件,在本文中只讲列表控件,如何在VS2017单文档MFC程序中加入TeeChart控件可自行在网上找其他的教程,这个在以后的博客中我也会介绍。添加列表控件后,在属性中将‘View’属性设置为‘Report’。
2.此时点击列表视图后右键,选择‘添加变量’,填写变量名称后点击‘完成‘会发现出现错误提示“为将对象引用设置到对象的实例”
在这里插入图片描述
看来此项目中不能直接添加变量,接下来打开类向导,向CDlg2类中添加虚函数DoDataExchange,步骤如下图所示:
在这里插入图片描述然后在在资源视图中打开对话框2,点击列表控件,右键添加变量,变量名称设为m_List1,然后点击完成,此时发现在刚刚添加的DoDataExchange虚函数中多了行代码“DDX_Control(pDX, IDC_LIST1, m_List1);”转到CDlg2类的定义中也发现有“CListCtrl m_List1;”。但是会发现报错“未定义标识符IDC_LIST1”,很明显这个标识符是列表控件的ID,它被定义在Resource.h,打开这个头文件查看有无此定义,打开后发现是有的,可以无视此错误提示,关闭Resource.h。编译运行程序,发现并未出现错误提示,此时就已成功为列表控件添加了变量。
简而言之,在添加变量前要先添加DoDataExChange虚函数,再添加变量。
7.为列表控件中添加内容
首先为对话框2添加初始化的虚函数,名为OnInitialUpdate,步骤如下图:
在这里插入图片描述
再向此函数中添加如下代码:

m_List1.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);//设置列表控件格式(有栅格线,整行选中)
m_List1.SetBkColor(RGB(255, 255, 255));//设置列表控件背景为白色
m_List1.InsertColumn(0, _T("姓名"), LVCFMT_CENTER, 160);//添加列,并设置列的宽度为160
m_List1.InsertColumn(1, _T("性别"), LVCFMT_CENTER, 160);
m_List1.InsertColumn(2, _T("年龄"), LVCFMT_CENTER, 160);
m_List1.InsertItem(0, _T("张三")); m_List1.SetItemText(0, 1, _T("男")); m_List1.SetItemText(0, 2, _T("21"));//添加数据

然后运行,最终结果如下:
在这里插入图片描述
本文工程百度云链接:https://pan.baidu.com/s/1dXvvg2iEykT0ZPc1tLp4Dg 提取码:mr9h
本文工程CSDN下载链:https://download.csdn.net/download/weixin_41303441/11743253
本文开头显示结果的工程百度云链接(含TeeChart控件及控件大小随窗口大小而变):https://pan.baidu.com/s/1jJOvKNsnHvrfgZO77GEiCg 提取码:kg5e
本文开头显示结果的工程CSDN下载链(含TeeChart控件及控件大小随窗口大小而变):https://download.csdn.net/download/weixin_41303441/11743278

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值