0
点赞
收藏
分享

微信扫一扫

文档/视图结构以及简单操作

做个橙梦 2022-04-29 阅读 61
windows

文档/视图结构

一、前言

兄弟们,我又来了!最近有点忙,事情有点多,不过事再多,也要把博客写了,好习惯是要一步一步养成的,不能中途放弃,不然就功亏一篑了!我们MFC原理与方法的课程结束了,接下来我们要学习文档/视图结构。好了,废话不多说,咱们开始吧!
在这里插入图片描述


二、什么是文档/视图结构

文档/视图的核心是四个关键类

  1. CDocument 类支持用于存储或控制程序数据的对象,并为程序员定义的文档类提供基本功能。 文档表示用户通常使用“文件”菜单上的“打开”命令打开的数据单位,并使用“文件”菜单上的“保存”命令进行保存。

  2. CView (或其许多派生类之一) 为程序员定义的视图类提供了基本功能。 视图附加到文档,充当文档与用户之间的中介:视图在屏幕上呈现文档的图像,并将用户输入解释为对文档的操作。 该视图还呈现打印和打印预览的图像。若要使用 CView,请从该类派生类,并实现 OnDraw 成员函数来执行屏幕显示。还可使用 执行 OnDraw 打印和打印预览。框架处理打印循环,用于打印和预览文档。视图使用和成员函数处理滚动 CWnd::OnHScroll条CWnd::OnVScroll 消息。可以在这些函数中实现CViewCScrollView滚动条消息处理,或者可以使用派生类来处理滚动。
    除此之外,Microsoft 基础类库还提供九个派生自的其他类CView:
    在这里插入图片描述

  3. CFrameWnd (或其变体之一) 支持围绕文档的一个或多个视图提供框架的对象。MFC 把文档/视图/框架视为一体,只要创建文档/视图框架结构的程序,必定会创建这三个类。在程序运行时,CWinApp将创建一个 CFrame Wnd 框架窗口实例,而框架窗口将创建文档模板,然后由文档模板创建文档实例和视图实例,并将两者关联

  4. CDocTemplate (或 CSingleDocTemplate 或 CMultiDocTemplate) 支持一个或多个给定类型的现有文档,并管理为该类型创建正确的文档、视图和框架窗口对象。

下图显示了文档与其视图之间的关系:
在这里插入图片描述
类库中的文档/视图实现将数据本身与数据的显示和用户操作分开。 对数据的所有更改都通过文档类进行管理。 视图调用此接口来访问和更新数据。

文档、其关联视图和框架窗口框架窗口由文档模板创建。 文档模板负责创建和管理一个文档类型的所有文档。


三、文档/视图结构的操作

接下来我们尝试使用MFC来画线,首先创建一个MFC程序,选择单文档类型,然后利用类向导View类添加移动鼠标WM_MOUSEMOVE响应事件函数,代码如下:

void CMFCView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CClientDC dc(this);
	if((nFlags&MK_LBUTTON)) //nFlags用来记录鼠标消息产生时瞬间状态,前缀MK_表示掩码,如MK_LBUTTON表示需要按下左键才能执行if语句的代码
	{
		dc.SetPixel(point,RGB(255,0,0));//point为鼠标当前的位置,SetPixel()函数将指定坐标处的像素设为指定的颜色。
	}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
	CView::OnMouseMove(nFlags, point);
}

我们来看看效果:
在这里插入图片描述
我们可以通过上面的结果看到,如果你鼠标的移动速度比较慢的时候,还能看起来像一条线,但当速度一快就会成离散的像素点,这是因为用SetPixel()函数画线只能一个一个点的来画,所以我们想要改进是不是要想办法换一个合适的函数,我们可以想到画线嘛,为什么我们不用LineTo函数呢?好,接下来我们来试试看怎么用LineTo()函数画线:

void CMFCView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CClientDC dc(this);
	if((nFlags&MK_LBUTTON))
	{
		dc.LineTo(point);
	}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
	CView::OnMouseMove(nFlags, point);
}

看看效果如何:
在这里插入图片描述
我们可以看到,我们画的线并不是我们想怎么画就怎么画的线,这是因为在dc.LineTo(point);中画线的起点始终在(0,0)即左上角,所以我们要编写代码使画线的起点设置在鼠标的位置才行,我们可以通过MoveTo()函数来完成。要注意的是,我们需要利用类向导在View类下设置一个私用点变量CPoint p0

void CMFCView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值	CClientDC dc(this);
	if((nFlags&MK_LBUTTON))
	{
		dc.MoveTo(p0);
		dc.LineTo(point);
		p0=point;
	}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
	CView::OnMouseMove(nFlags, point);
}

在这里插入图片描述
我们发现效果好多了,但是还是存在两个问题第一,起点还是从左上角开始。第二,每次按下鼠标左键时都会与上一次画线的最后一点进行连线。这是因为p0的值还是上次画线时的值,所以我们可以通过类向导在View类下的WM_RBUTTONDOWN添加一个函数,使得每次按下鼠标左键的时候重新设置起点p0的值。

void CMFCView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	p0=point;
	CView::OnLButtonDown(nFlags, point);
}

在这里插入图片描述
我们可以看到两个问题都解决了,已经可以随意的画线了。


四、结语

终于写完了!终于在ACM、深度学习和智能感知和日常学习中完成了这篇博客。。。哎,太难了,有点累,不过还是得坚持下去。好了,话不多说,我们下次再见吧!《遇见》谢谢大家!
在这里插入图片描述


举报

相关推荐

0 条评论