VC++的MFC单文档画图程序

一、前言

  1. 参考教程

  2. 开发环境:Microsoft Visual Studio Community 2022 (64 位) - Preview

  3. 安装MFC模板:参考

  4. 要求:能处理线、矩形和椭圆的加载和保存工作,要能有颜色和线宽信息。

  5. 最终项目结构
    在这里插入图片描述

二、创建项目

  1. 选择MFC应用在这里插入图片描述

  2. 设置项目名称:Test3
    在这里插入图片描述

  3. 设置应用程序类型和项目样式

在这里插入图片描述

三、编写代码

1.创建自己的形状类

  • 头文件:Test3Shape.h

在这里插入图片描述
在这里插入图片描述

得到

在这里插入图片描述

输入代码:

#pragma once
class Test3Shape : public CObject
{
	DECLARE_SERIAL(Test3Shape)
private:
	double up;
	double down;
	double left;
	double right;
	int body;
	COLORREF col_area;
	COLORREF col_line;
	int line_width;
	bool isOk;
public:
	Test3Shape(); // 无参构造
	Test3Shape(double up, double down, double left, double right, int body, COLORREF col_area, COLORREF col_line, int line_width);	// 构造函数
	virtual void Serialize(CArchive& ar);
	void Draw(CDC* pDC); // 绘图函数
	void IsSelect(double x, double y); // 判断选择函数
	bool CD(); // 返回选择状态函数
	void NoSelect(); // 取消选择状态函数
	
	void MoveUP(); // 向上移动
	void MoveDOWN(); // 向下移动
	void MoveLEFT(); // 向左移动
	void MoveRight(); // 向右移动
	double GetUP(); // 返回up值
	double GetDPWN(); // 返回down值
	double GetLEFT(); // 返回left值
	double GetRIGHT(); // 返回right值
	int GetBODY(); // 返回body值
	COLORREF GetCOL_AREA(); // 返回填充颜色
	COLORREF GetCOL_LINE(); // 返回描边颜色
	int GetLINE_WIDTH(); // 返回线宽
	void ad(); // 个数+
	void da(); // 个数-
};
  • 源文件:Test3Shape.cpp

在这里插入图片描述
在这里插入图片描述

得到

在这里插入图片描述

输入代码:

#include "pch.h"
#include "windef.h"
#include "Test3Shape.h"

IMPLEMENT_SERIAL(Test3Shape, CObject, 1)
Test3Shape::Test3Shape() {}
Test3Shape::Test3Shape(double x, double y, double m, double n, int z, COLORREF c, COLORREF c0, int w) // 构造
{
	up = x;
	down = y;
	left = m;
	right = n;
	body = z;
	col_area = c;
	col_line = c0;
	line_width = w;
	isOk = false;
}

void Test3Shape::Serialize(CArchive& ar)

{
	if (ar.IsStoring()) { //序列化,保存信息
		ar << up << down << left << right << body << col_area << col_line << line_width << isOk;
	}
	else //反序列化,读取信息
	{
		ar >> up >> down >> left >> right >> body >> col_area >> col_line >> line_width >> isOk;
	}

}


void Test3Shape::Draw(CDC* pDC) // 绘画
{
	CBrush NBrush(col_area);
	CPen NPen(PS_SOLID, line_width, col_line);
	pDC->SelectObject(NBrush);
	pDC->SelectObject(NPen);
	switch (body)
	{
	case 1:
	{
		pDC->MoveTo(left, up);
		pDC->LineTo(right, down);
		break;
	}
	case 2:
	{
		pDC->Ellipse(left, down, right, up);
		break;
	}
	case 3:
	{
		pDC->Rectangle(left, down, right, up);
		break;
	}
	}
}
void Test3Shape::IsSelect(double x, double y) // 选择
{
	switch (body)
	{
	case 1: // 直线
	{
		TRACE("直线n: %p\n");
		TRACE("直线n: %p\n");
		double k = (up - down) / (left - right);
		double b = up - k * left;
		if (y == k * x + b)
			isOk = true;
		break;
	}
	case 2: // 椭圆
	{
		double a = (right - left) / 2, b = (up - down) / 2;
		a = a > 0 ? a : a * -1;
		b = b > 0 ? b : b * -1;
		double c, Clx, Cly, Crx, Cry, o_l;
		if (a > b)
		{
			c = sqrt(pow(a, 2) - pow(b, 2));
			Clx = (left + right) / 2 - c, Crx = (left + right) / 2 + c, Cly = Cry = (up + down) / 2;
			o_l = sqrt(pow(x - Clx, 2) + pow(y - Cly, 2)) + sqrt(pow(x - Crx, 2) + pow(y - Cry, 2));
			if (o_l <= 2 * a)
				isOk = true;
		}
		else
		{
			c = sqrt(pow(b, 2) - pow(a, 2));
			Cly = (up + down) / 2 - c, Cry = (up + down) / 2 + c, Clx = Crx = (left + right) / 2;
			o_l = sqrt(pow(x - Clx, 2) + pow(y - Cly, 2)) + sqrt(pow(x - Crx, 2) + pow(y - Cry, 2));
			if (o_l <= 2 * b)
				isOk = true;
		}
		break;
	}
	case 3: // 矩形
	{
		if (y >= up && y <= down && x >= left && x <= right)
			isOk = true;
		break;
	}
	}

}

bool Test3Shape::CD() // 返回选中状态
{
	return isOk;
}

void Test3Shape::NoSelect() // 取消选中状态
{
	isOk = false;
}

void Test3Shape::MoveUP()
{
	up -= 10;
	down -= 10;
}

void Test3Shape::MoveDOWN()
{
	up += 10;
	down += 10;
}

void Test3Shape::MoveLEFT()
{
	left -= 10;
	right -= 10;
}

void Test3Shape::MoveRight()
{
	left += 10;
	right += 10;
}

double Test3Shape::GetUP() { return up; }
double Test3Shape::GetDPWN() { return down; }
double Test3Shape::GetLEFT() { return left; }
double Test3Shape::GetRIGHT() { return right; }
int Test3Shape::GetBODY() { return body; }
COLORREF Test3Shape::GetCOL_AREA() { return col_area; }
COLORREF Test3Shape::GetCOL_LINE() { return col_line; }
int Test3Shape::GetLINE_WIDTH() { return line_width; }
void Test3Shape::ad() { up++; }
void Test3Shape::da() { up--; }

2.Doc类

  • 头文件:Test3Doc.h

输入代码:

// Test3Doc.h: CTest3Doc 类的接口
//


#pragma once

#include "Test3Shape.h"
class CTest3Doc : public CDocument
{
protected: // 仅从序列化创建
	CTest3Doc() noexcept;
	DECLARE_DYNCREATE(CTest3Doc)

// 特性
public:
	CArray<Test3Shape*, Test3Shape*> ShapeArray;

// 操作
public:

// 重写
public:
	virtual BOOL OnNewDocument();
	virtual void Serialize(CArchive& ar);
#ifdef SHARED_HANDLERS
	virtual void InitializeSearchContent();
	virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds);
#endif // SHARED_HANDLERS

// 实现
public:
	virtual ~CTest3Doc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	DECLARE_MESSAGE_MAP()

#ifdef SHARED_HANDLERS
	// 用于为搜索处理程序设置搜索内容的 Helper 函数
	void SetSearchContent(const CString& value);
#endif // SHARED_HANDLERS
};
  • 源文件:Test3Doc.cpp

输入代码:

// Test3Doc.cpp: CTest3Doc 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "Test3.h"
#endif

#include "Test3Doc.h"

#include <propkey.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CTest3Doc

IMPLEMENT_DYNCREATE(CTest3Doc, CDocument)

BEGIN_MESSAGE_MAP(CTest3Doc, CDocument)
END_MESSAGE_MAP()


// CTest3Doc 构造/析构

CTest3Doc::CTest3Doc() noexcept
{
	// TODO: 在此添加一次性构造代码
}

CTest3Doc::~CTest3Doc()
{
	for (int i = 0; i < ShapeArray.GetSize(); ++i)
	{
		Test3Shape* pShape = ShapeArray.GetAt(i);
		delete pShape;
	}
}


BOOL CTest3Doc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: 在此添加重新初始化代码
	// (SDI 文档将重用该文档)

	return TRUE;
}




// CTest3Doc 序列化

void CTest3Doc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: 在此添加存储代码

		for (int i = 0; i < ShapeArray.GetSize(); i++)
		{
			Test3Shape* CS = ShapeArray[i];
			CS->Serialize(ar);

		}

	}
	else
	{
		// TODO: 在此添加加载代码
		ShapeArray.RemoveAll(); // 清空数组
		Test3Shape* CS = new Test3Shape();
		CS->Serialize(ar);
		ShapeArray.Add(CS); // 添加元素到数组
		int num = ShapeArray[0]->GetUP();
		for (int i = 0; i < num; i++)
		{
			Test3Shape* CS2 = new Test3Shape();
			CS2->Serialize(ar);
			ShapeArray.Add(CS2); // 添加元素到数组
		}
	}
}


#ifdef SHARED_HANDLERS

// 缩略图的支持
void CTest3Doc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
{
	// 修改此代码以绘制文档数据
	dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));

	CString strText = _T("TODO: implement thumbnail drawing here");
	LOGFONT lf;

	CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
	pDefaultGUIFont->GetLogFont(&lf);
	lf.lfHeight = 36;

	CFont fontDraw;
	fontDraw.CreateFontIndirect(&lf);

	CFont* pOldFont = dc.SelectObject(&fontDraw);
	dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
	dc.SelectObject(pOldFont);
}

// 搜索处理程序的支持
void CTest3Doc::InitializeSearchContent()
{
	CString strSearchContent;
	// 从文档数据设置搜索内容。
	// 内容部分应由“;”分隔

	// 例如:     strSearchContent = _T("point;rectangle;circle;ole object;");
	SetSearchContent(strSearchContent);
}

void CTest3Doc::SetSearchContent(const CString& value)
{
	if (value.IsEmpty())
	{
		RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
	}
	else
	{
		CMFCFilterChunkValueImpl *pChunk = nullptr;
		ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
		if (pChunk != nullptr)
		{
			pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
			SetChunkValue(pChunk);
		}
	}
}

#endif // SHARED_HANDLERS

// CTest3Doc 诊断

#ifdef _DEBUG
void CTest3Doc::AssertValid() const
{
	CDocument::AssertValid();
}

void CTest3Doc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// CTest3Doc 命令

3.View类

头文件:Test3View.h
  • 添加按钮

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 输入代码

    // Test3View.h: CTest3View 类的接口
    //
    
    #pragma once
    
    
    class CTest3View : public CView
    {
    protected: // 仅从序列化创建
    	CTest3View() noexcept;
    	DECLARE_DYNCREATE(CTest3View)
    
    // 特性
    public:
    	CTest3Doc* GetDocument() const;
    
    // 操作
    public:
    	int num = 0;
    	int numColour = 0;
    	int numLineWidth = 0;
    	bool ff = false;
    	double m_u;
    	double m_d;
    	double m_l;
    	double m_r;
    	double m_x;
    	double m_y;
    	COLORREF col_in = RGB(0, 0, 0);
    	COLORREF col_out = RGB(0, 0, 0);
    	int lineWidth = 0;
    
    	Test3Shape* CS;
    	void DeleteSelect(double x, double y); // 删除选择函数
    	Test3Shape* Choose(double x, double y); // 选择函数
    // 重写
    public:
    	virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
    	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    
    // 实现
    public:
    	virtual ~CTest3View();
    #ifdef _DEBUG
    	virtual void AssertValid() const;
    	virtual void Dump(CDumpContext& dc) const;
    #endif
    
    protected:
    
    // 生成的消息映射函数
    protected:
    	DECLARE_MESSAGE_MAP()
    public:
    	afx_msg void CreateLine();
    	afx_msg void CreateRCircle();
    	afx_msg void CreateRectangle();
    	afx_msg void ChooseBlack();
    	afx_msg void ChooseRed();
    	afx_msg void ChooseBlue();
    	afx_msg void lineWidth1pc();
    	afx_msg void lineWidth5pc();
    	afx_msg void lineWidth10pc();
    	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
    	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    };
    
    #ifndef _DEBUG  // Test3View.cpp 中的调试版本
    inline CTest3Doc* CTest3View::GetDocument() const
       { return reinterpret_cast<CTest3Doc*>(m_pDocument); }
    #endif
    
源文件:Test3View.cpp
  • 类导向

在这里插入图片描述
在这里插入图片描述

找到上述的 ID_32771 ~ ID_32779 ,对每个进行添加,输入函数名,一一对应。

函数名命令ID
ChooseBlackID_32774
ChooseBluelD_32776
ChooseRedlD_32775
CreateLineID_32771
CreateRCircleID_32772
CreateRectangleID_32773
lineWidth10pcID_32779
lineWidth1pcID_32777
lineWidth5pcID_32778

在这里插入图片描述

  • 输入代码:
// Test3View.cpp: CTest3View 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "Test3.h"
#endif

#include "Test3Doc.h"
#include "Test3View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CTest3View

IMPLEMENT_DYNCREATE(CTest3View, CView)

BEGIN_MESSAGE_MAP(CTest3View, CView)
	ON_COMMAND(ID_32771, &CTest3View::CreateLine)
	ON_COMMAND(ID_32772, &CTest3View::CreateRCircle)
	ON_COMMAND(ID_32773, &CTest3View::CreateRectangle)
	ON_COMMAND(ID_32774, &CTest3View::ChooseBlack)
	ON_COMMAND(ID_32775, &CTest3View::ChooseRed)
	ON_COMMAND(ID_32776, &CTest3View::ChooseBlue)
	ON_COMMAND(ID_32777, &CTest3View::lineWidth1pc)
	ON_COMMAND(ID_32778, &CTest3View::lineWidth5pc)
	ON_COMMAND(ID_32779, &CTest3View::lineWidth10pc)
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
END_MESSAGE_MAP()

// CTest3View 构造/析构

CTest3View::CTest3View() noexcept
{
	// TODO: 在此处添加构造代码

}

CTest3View::~CTest3View()
{
}

BOOL CTest3View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CTest3View 绘图

void CTest3View::DeleteSelect(double x, double y)
{
	CTest3Doc* pDoc = GetDocument();
	for (int i = 0; i < pDoc->ShapeArray.GetSize(); ++i)
	{
		Test3Shape* pShape = pDoc->ShapeArray.GetAt(i);
		pShape->IsSelect(x, y);
		if (pShape->CD())
		{
			pDoc->ShapeArray.RemoveAt(i);
			pDoc->ShapeArray[0]->da();
		}
	}
}
Test3Shape* CTest3View::Choose(double x, double y)
{
	CTest3Doc* pDoc = GetDocument();
	Test3Shape* pShape = NULL;
	for (int i = 0; i < pDoc->ShapeArray.GetSize(); ++i)
	{
		pShape = pDoc->ShapeArray.GetAt(i);
		pShape->IsSelect(x, y);
	}
	return pShape;
}
void CTest3View::OnDraw(CDC* pDC)
{
	CTest3Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	for (int i = 0; i < pDoc->ShapeArray.GetSize(); ++i)
	{
		Test3Shape* pShape = (pDoc->ShapeArray).GetAt(i);
		pShape->Draw(pDC);
	}
}


// CTest3View 诊断

#ifdef _DEBUG
void CTest3View::AssertValid() const
{
	CView::AssertValid();
}

void CTest3View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTest3Doc* CTest3View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTest3Doc)));
	return (CTest3Doc*)m_pDocument;
}
#endif //_DEBUG


// CTest3View 消息处理程序


void CTest3View::CreateLine()
{
	// TODO: 在此添加命令处理程序代码
	num = 1;
}


void CTest3View::CreateRCircle()
{
	// TODO: 在此添加命令处理程序代码
	num = 2;
}


void CTest3View::CreateRectangle()
{
	// TODO: 在此添加命令处理程序代码
	num = 3;
}


void CTest3View::ChooseBlack()
{
	// TODO: 在此添加命令处理程序代码
	numColour = 1;
}


void CTest3View::ChooseRed()
{
	// TODO: 在此添加命令处理程序代码
	numColour = 2;
}


void CTest3View::ChooseBlue()
{
	// TODO: 在此添加命令处理程序代码
	numColour = 3;
}


void CTest3View::lineWidth1pc()
{
	// TODO: 在此添加命令处理程序代码
	numLineWidth = 1;
}


void CTest3View::lineWidth5pc()
{
	// TODO: 在此添加命令处理程序代码
	numLineWidth = 2;
}


void CTest3View::lineWidth10pc()
{
	// TODO: 在此添加命令处理程序代码
	numLineWidth = 3;
}


void CTest3View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nChar)
	{
	case VK_DELETE:
	{
		DeleteSelect(m_x, m_y);
		InvalidateRect(NULL);
		break;
	}
	case VK_CONTROL:
	{
		CS = Choose(m_x, m_y);
		ff = true;
		break;
	}
	case VK_UP:
	{
		if (ff)
		{
			CS->MoveUP();
			CS->NoSelect();
			InvalidateRect(NULL);

		}
		break;
	}
	case VK_DOWN:
	{
		if (ff)
		{
			CS->MoveDOWN();
			CS->NoSelect();
			InvalidateRect(NULL);
		}
		break;
	}
	case VK_LEFT:
	{
		if (ff)
		{
			CS->MoveLEFT();
			CS->NoSelect();
			InvalidateRect(NULL);
		}
		break;
	}
	case VK_RIGHT:
	{
		if (ff)
		{
			CS->MoveRight();
			CS->NoSelect();
			InvalidateRect(NULL);
		}
		break;
	}
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CTest3View::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nChar)
	{
	case VK_CONTROL:
	{
		ff = false;
		break;
	}

	}
	CView::OnKeyUp(nChar, nRepCnt, nFlags);
}


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


void CTest3View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_d = point.y;
	m_r = point.x;
	if (num != 0)
	{
		CTest3Doc* pDoc = GetDocument();
		Test3Shape* pShape;
		if (numColour == 1) // 设置填充颜色为黑色
			col_in = RGB(0, 0, 0);
		if (numColour == 2) // 设置填充颜色为红色
			col_in = RGB(255, 0, 0);
		if (numColour == 3) // 设置填充颜色为蓝色
			col_in = RGB(0, 0, 255);

		if (numLineWidth == 1)
			lineWidth = 1; // 设置线宽为1像素
		if (numLineWidth == 2)
			lineWidth = 5; // 设置线宽为5像素
		if (numLineWidth == 3)
			lineWidth = 10; // 设置线宽为10像素

		if (num == 1)
			pShape = new Test3Shape(m_u, m_d, m_l, m_r, num, col_in, col_out, lineWidth);
		else
			pShape = new Test3Shape(min(m_u, m_d), max(m_u, m_d), min(m_l, m_r), max(m_l, m_r), num, col_in, col_out, lineWidth);

		pDoc->ShapeArray.Add(pShape);
		pDoc->ShapeArray[0]->ad();
		InvalidateRect(NULL);
	}
	CView::OnLButtonUp(nFlags, point);
}


void CTest3View::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_x = point.x;
	m_y = point.y;
	CView::OnMouseMove(nFlags, point);
}


int CTest3View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	Test3Shape* pShape = new Test3Shape(0, 0, 0, 0, 99999, col_in, col_out, lineWidth);
	CTest3Doc* pDoc = GetDocument();
	pDoc->ShapeArray.Add(pShape);
	return 0;
}

4.保存文件带后缀名

比如保存的文件带后缀名line,假设项目名为XXX:

在资源视图中,XXX工程下的文件夹XXX.rc里面的String Table文件夹下的String Table,双击打开。找到IDR MAINFRAMETM,其值:

  • 默认:Test3\n\nTest3\n\n\nTest3.Document\nTest3.Document

  • 改为:Test3\n\nTest3\n.line\n.line\nTest3.Document\nTest3.Document

在这里插入图片描述

四、运行结果

动态演示
或者
选择不同选项,绘制出图形如下所示:

在这里插入图片描述

对绘制文档进行保存,文件扩展名为.line,如下所示:

在这里插入图片描述

成功打开保存的.line绘图文档如下所示:

在这里插入图片描述

在这里插入图片描述

五、MFC项目文件的介绍

在Microsoft Foundation Class (MFC)库中,Doc.hView.hDoc.cppView.cpp是常见的文件名,通常与应用程序的文档(Document)和视图(View)部分相关。下面简要解释一下它们各自的作用:

  1. Doc.h:
    • 这是文档类的头文件。通常,这个类定义了一个应用程序所处理的数据的结构。它也可能包含与数据持久性(例如,保存和加载到文件)相关的代码。
    • 文档类通常与一个视图类关联,这样视图可以显示文档的内容并与之交互。
  2. View.h:
    • 这是视图类的头文件。视图类定义了用户界面(UI),用户可以通过这个界面与文档交互。例如,如果文档是一个文本编辑器,视图可能就是一个文本编辑控件。
    • 视图类通常包含用于处理用户输入(如按键和鼠标移动)的代码,以及用于更新显示内容的代码。
  3. Doc.cpp:
    • 这是文档类的实现文件。它包含了在Doc.h中声明的类的实现代码。这包括数据结构的定义、数据持久性方法(如保存和加载到文件),以及其他与文档管理相关的逻辑。
  4. View.cpp:
    • 这是视图类的实现文件。它包含了在View.h中声明的类的实现代码,包括UI元素的更新、用户输入的处理等。

在MFC应用程序中,通常会有多个视图类与一个文档类相关联,以支持多个UI线程或同时从多个窗口查看文档的不同部分。此外,MFC还提供了框架代码来处理文档和视图的生命周期,以及它们之间的通信,从而简化了Windows应用程序的开发。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HYYFKL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值