visual studio 2017 MFC SDI项目 添加CFormView类

visual studio 2017 MFC SDI项目 添加CFormView类

1

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

2

在这里插入图片描述
接下来就可以像操作对话框应用程序一样直接操作单文档应用程序了.需要注意的是CFormView派生类没有"OnInitDialog"函数.对话框的初始化(或者说习惯开始函数)可以放在"OnInitialUpdate"中完成.

VS2017单文档程序窗口分割没有CFormView基类的解决方法

https://www.cctry.com/thread-298468-1-1.html

起因:
最近在学习VC++高级版之窗口篇,在学习最后一节课《单文档程序之窗口分割》的时候,出现了一点问题。
其实也不是什么大问题,Syc大大视频中的编程环境时xp + VS2008,我的环境的win7 + VS2017,有些不同时正常的,我首先在网上搜了一下,没有找到什么好的解决方法,于是我自己查了msdn,加上自己的一些尝试,解决了这个问题,现在分享一下。

目标是将下图底部的日志窗口替换为对话框样式的窗口
改之前:

在这里插入图片描述
在这里插入图片描述
经过:
先来回顾一下低版本VS单文档程序窗口分割的几个步骤,这个在视频中都有讲解哦,在课件里也有:
1)新建一个单文档工程:SpliterTest,会默认生成CMainFrame、CSpliterTestApp、CSpliterTestDoc、CSpliterTestView这几个类
其中向导默认将CSpliterTestView的基类选择为CView,这是问题所在

2)各个分割窗口类的添加:类向导、添加MFC类:分组信息类、客户端信息类、日志信息类
CGroupTreeView,基类选择:CTreeView
CClientListView,基类选择CListView
CLogListView,基类选择CListView

3)重载CMainFrame::OnCreateClient函数,进行分割窗口的创建:

// 对参1窗口进行分割,分成2行1列
// 以后再对第0行窗口进行分割,成为两列
if (!m_wndSplitter.CreateStatic(this, 2, 1))
        return FALSE;

// 给第0行0列窗口关联一个类,因为0行0列的窗口以后还要被分割,所以目前关联项目自身的CSpliterTestView类
// 给第1行0列的窗口关联CLogListView类
if (!m_wndSplitter.CreateView( 0, 0, RUNTIME_CLASS(CSpliterTestView), CSize(0, 260), pContext) ||
    !m_wndSplitter.CreateView( 1, 0, RUNTIME_CLASS(CLogListView), CSize(0, 0), pContext) )
{
        m_wndSplitter.DestroyWindow();
        return FALSE;
}

return TRUE;

4)响应CMainFrame类的WM_SIZE消息,在OnSize中进行窗口位置的调整,具体代码略

5)响应CSpliterTestView类的WM_CREATE消息,在OnCreate中继续分割窗口:

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

CCreateContext *pContext = (CCreateContext *)lpCreateStruct->lpCreateParams;

//给0行0列窗口关联CGroupTreeView类
//给0行1列窗口关联CClientListView类
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CGroupTreeView), CSize(100, 100), pContext) ||
    !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CClientListView), CSize(0, 0), pContext))
{
        m_wndSplitter.DestroyWindow();
        return FALSE;
}

return TRUE;

6)响应CSPliterTestView的WM_SIZE消息,在其OnSize中进行窗口位置调整,具体代码略

7)在各个分割视图窗口上添加内容:在各个关联视图类OnInitialUpdate中初始化,具体代码略

8)可放置控件的视图类:CFormView
类向导添加MFC类CFilterFormView,基类选择:CFormView。
此时资源里,就有对话框模版了,就可以拖控件了。将第3)步的1行0列窗口,替换为本类CFilterFormView。运行就可以看到效果了。

好,以上步骤的第8)步,我在VS2012里,是可以进行的,但是在VS2017里,类向导里没有CFormView这个基类~~~噢,这。。。
我在网上没看到什么好的方法,在msdn中有一句话,如下:
在这里插入图片描述
这下我就明白了,在项目创建的时候,也就是上面的第1),View的基类不要选择CView,而是要选择CFormView,改动如下:
1)在项目创建向导的最后一步,View类的基类选择CFormView,这样一运行起来,整个客户区就是对话框模版!!!

2)按照前面的第2)步,添加3个类:
CBaseView,基类选择CView
CGroupTreeView,基类选择:CTreeView
CClientListView,基类选择CListView
为啥要加CBaseView类?因为此时我们不需要日志类CLogListView来关联底部的窗口,我们就把本身客户区的对话框当作底部。
CBaseView类当作CGroupTreeView、CClientListView类的载体,实践证明如果CBaseView的基类选择得太具体了,比如CListView、CTreeView等,会报错。

3)在前面第3)步,CMainFrame类的OnCreateClient里:
0行0列窗口关联CBaseView类,1行0列窗口关联项目自身的CSpliterTestView类

4)参考前面第5)步,响应CBaseView类的WM_CREATE消息,在OnCreate里,继续分割,1行2列:
0行0列关联CGroupTreeView,0行1列关联CClientListView,即可

结果:
改动几个地方之后,就能在底部窗口显示对话框模版了,可以拖控件了,这不是啥高深的技术,就是遇到一点小问题,自己连蒙带猜,查询msdn,得出来的一点经验。
如果大家有其他方法,希望告知哦

其实最下面一个分割窗体,也可以从CDialog继承,只不过需要自己对有些地方代码改一下就能使用了!

我的做法

先在 visual studio 2015里面,创建一个 CFormView类,他会关联一个ID 对话框
然后再 viusal studio 2017里面,创建一个 资源 对话框,选择 Dialog (Form Dialog)
然后 添加类。
会生成 对应的 类文件,
然后将 visual studio 2015里面生成的文件,复制到visual studio 2017里面,然后替换
就可以了

visual 2017中

新建一个dialog 对话框 资源
在这里插入图片描述
选择 新建 一个 IDD_FORMVIEW 模式的 对话框资源,
IDD_FORMVIEW 模式 指的是 style = child,border=none

这个新建的资源的 ID 默认为 IDD_FORMVIEW
在这里插入图片描述
添加各种控件
在这里插入图片描述
在对话框 资源上 点击 鼠标右键,添加类
在这里插入图片描述
基类暂时 选择 CDialog
在这里插入图片描述
这样会生成 MessageView.cpp MessageView.h文件,这两个文件 需要 被替换。

visual 2015中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
生成新的 MessageView.cpp 和 MessageView.h

将这个新的 MessageView.cpp 和 MessageView.h 替换原来 visual stduio 2017 里面的 对应文件
在这里插入图片描述
接下来 就可以 添加 变量关联 和 事件 和 OnInitialUpdate 函数了

MessageView.h 文件内容
#pragma once



// CMessageView 窗体视图

class CMessageView : public CFormView
{
	DECLARE_DYNCREATE(CMessageView)

protected:
	CMessageView();           // 动态创建所使用的受保护的构造函数
	virtual ~CMessageView();

public:
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_FORMVIEW };
#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()
};



MessageView.cpp 文件内容
// MessageView.cpp : 实现文件
//

#include "stdafx.h"
#include "resource.h"
#include "MessageView.h"


// CMessageView

IMPLEMENT_DYNCREATE(CMessageView, CFormView)

CMessageView::CMessageView()
	: CFormView(IDD_FORMVIEW)
{

}

CMessageView::~CMessageView()
{
}

void CMessageView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMessageView, CFormView)
END_MESSAGE_MAP()


// CMessageView 诊断

#ifdef _DEBUG
void CMessageView::AssertValid() const
{
	CFormView::AssertValid();
}

#ifndef _WIN32_WCE
void CMessageView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif
#endif //_DEBUG


// CMessageView 消息处理程序

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值