正在学习MFC的小白,错误的地方请大家多多指正。
前言
VS2015和VS2019现在都能很方便地分割窗口了,然而只有2017没有办法用类向导创建一个继承自CFormView类与对话框关联,但又不想重新下一个VS了实在太占空间了。没有办法,只有全网找解决方案,很多大佬都写得很好,但奈何方法太复杂,小白实在弄不好。试了N个方法,不是根本窗口不分割,就是各种奇葩报错(创建空白文档失败之类的)。在长时间的尝试无果之后,我想出了老师告诉我了一个绝妙的方法——用VS2015的文件替换CCgEditControl文件替换。(源码附在博客最后)
具体步骤
新建项目
- 打开VS2017,点击菜单栏里的文件->新建->项目选项,在新建窗口里面选择MFC应用程序,定义工程名称和位置。
- 点击完成进入程序参数配置。应用程序类型改为单文档,项目类型改为MFC标准,其后步骤选择默认参数配置即可
- 新创建项目包括头文件、资源文件、源文件和外部依赖项4部分。
类结构关系如下图:
cg2019HkrFillPolyApp: 应用程序框架类,程序注册、资源申请和运行启动等。
CMainFrame: 应用程序主窗体类,程序交互界面窗口控制。
cg2019HkrFillPolyView:应用程序视类,绘制文档类存储数据的图形。
cg2019HkrFillPolyDoc: 应用程序文档类,存储数据格式描述。
资源配置
- 打开资源视图(视图->其他窗口->资源视图,有的可能在视图下就可以找到资源视图)
-
选择资源视图中Dialog选项,按右键弹出Popup菜单;选择插入Dialog选项。
-
在属性窗口中,编辑修改Dialog的相关属性。(选中Dialog单击右键打开属性窗口)
IDD_DIALOG1改为: IDD_SELECTCONTROL(自定义命名,但要保留前面的IDD_)
Style 选择Child.
Border 选择 None.
将确定和取消键删除。
- 为新资源映射一个类。选中Dialog双击左键,命名类名,选择基类(由于VS2017中没有CFormView类,就随便选一个)。
系统自动生成CCgEditControl.cpp和CCgEditControl.h两个文档模板。
8.用之前拷好的VS2015生成的CCgEditControl.cpp和CCgEditControl.h两个文档进行替换。将刚刚生成的两个文件从工程中移除,在将VS2015的两个文档移到工程目录下,添加到工程中。
注意不要忘记修改CCgEditControl.cpp引用的头文件名。
分割窗口
- 重写CMainFrame类的虚函数OnCreateClient()。
选择弹出类向导对话窗口(项目->类向导),添加OnCreateClient函数。
- 在OnCreateClient函数中添加如下代码。
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
if (!m_wndSplit.CreateStatic(this, 1, 2))
return 0;
if (!m_wndSplit.CreateView(0, 0,pContext->m_pNewViewClass,CSize(650, 100),pContext))
return 0;
if (!m_wndSplit.CreateView(0, 1,RUNTIME_CLASS(CCgEditControl),CSize(100,50),pContext))
return 0;
ShowWindow(SW_SHOWMAXIMIZED);
return TRUE;
}
-
CMainFrame类添加窗体分割条变量
CSplitterWnd m_wndSplit;
CMainFrame类添加CCgEditControl.h
- 运行结果如下图
最后附上VS2015的CCgEditControl.cpp和CCgEditControl.h两个文档源码
//CCgEditControl.h
#pragma once
// CCgEditControl 窗体视图
class CCgEditControl : public CFormView
{
DECLARE_DYNCREATE(CCgEditControl)
protected:
CCgEditControl(); // 动态创建所使用的受保护的构造函数
virtual ~CCgEditControl();
public:
#ifdef AFX_DESIGN_TIME
enum { IDD =
IDD_EDITCONTROL };
#endif
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
};
// CgEditControl.cpp : 实现文件
#include "stdafx.h"
#include "cg2019HkrFillPoly.h"//注意修改!!!!!
#include "CCgEditControl.h"//注意修改!!!!
// CCgEditControl
IMPLEMENT_DYNCREATE(CCgEditControl, CFormView)
CCgEditControl::CCgEditControl(): CFormView(IDD_EDITCONTROL)
{
}
CCgEditControl::~CCgEditControl()
{
}
void CCgEditControl::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CCgEditControl, CFormView)
END_MESSAGE_MAP()
// CCgEditControl 诊断
#ifdef _DEBUG
void CCgEditControl::AssertValid() const
{
CFormView::AssertValid();
}
#ifndef _WIN32_WCE
void CCgEditControl::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif
#endif //_DEBUG
// CCgEditControl 消息处理程序