暴力解决VS2017MFC窗口分割问题

Posted by HK on November 19, 2019

正在学习MFC的小白,错误的地方请大家多多指正。

前言

VS2015和VS2019现在都能很方便地分割窗口了,然而只有2017没有办法用类向导创建一个继承自CFormView类与对话框关联,但又不想重新下一个VS了实在太占空间了。没有办法,只有全网找解决方案,很多大佬都写得很好,但奈何方法太复杂,小白实在弄不好。试了N个方法,不是根本窗口不分割,就是各种奇葩报错(创建空白文档失败之类的)。在长时间的尝试无果之后,我想出了老师告诉我了一个绝妙的方法——用VS2015的文件替换CCgEditControl文件替换。(源码附在博客最后)

具体步骤

新建项目

  1. 打开VS2017,点击菜单栏里的文件->新建->项目选项,在新建窗口里面选择MFC应用程序,定义工程名称和位置。

新建项目

  1. 点击完成进入程序参数配置。应用程序类型改为单文档,项目类型改为MFC标准,其后步骤选择默认参数配置即可

程序参数配置

  1. 新创建项目包括头文件、资源文件、源文件和外部依赖项4部分。

在这里插入图片描述

类结构关系如下图:

在这里插入图片描述

cg2019HkrFillPolyApp: 应用程序框架类,程序注册、资源申请和运行启动等。

CMainFrame: 应用程序主窗体类,程序交互界面窗口控制。

cg2019HkrFillPolyView:应用程序视类,绘制文档类存储数据的图形。

cg2019HkrFillPolyDoc: 应用程序文档类,存储数据格式描述。

资源配置

  1. 打开资源视图(视图->其他窗口->资源视图,有的可能在视图下就可以找到资源视图)

在这里插入图片描述

  1. 选择资源视图中Dialog选项,按右键弹出Popup菜单;选择插入Dialog选项。 在这里插入图片描述

  2. 在属性窗口中,编辑修改Dialog的相关属性。(选中Dialog单击右键打开属性窗口)

IDD_DIALOG1改为: IDD_SELECTCONTROL(自定义命名,但要保留前面的IDD_)

Style 选择Child.

Border 选择 None.

将确定和取消键删除。

在这里插入图片描述

  1. 为新资源映射一个类。选中Dialog双击左键,命名类名,选择基类(由于VS2017中没有CFormView类,就随便选一个)。

在这里插入图片描述

系统自动生成CCgEditControl.cpp和CCgEditControl.h两个文档模板。

8.用之前拷好的VS2015生成的CCgEditControl.cpp和CCgEditControl.h两个文档进行替换。将刚刚生成的两个文件从工程中移除,在将VS2015的两个文档移到工程目录下,添加到工程中。

在这里插入图片描述

注意不要忘记修改CCgEditControl.cpp引用的头文件名。

分割窗口

  1. 重写CMainFrame类的虚函数OnCreateClient()。

选择弹出类向导对话窗口(项目->类向导),添加OnCreateClient函数。

在这里插入图片描述

  1. 在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; 
  }
  1. CMainFrame类添加窗体分割条变量

    CSplitterWnd m_wndSplit;
    

在这里插入图片描述

CMainFrame类添加CCgEditControl.h

在这里插入图片描述

  1. 运行结果如下图

在这里插入图片描述

最后附上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 消息处理程序