首页 > 编程语言 >广州大学面向对象程序设计实验五

广州大学面向对象程序设计实验五

时间:2024-11-18 18:42:58浏览次数:3  
标签:广州大学 void dc 面向对象 PointBegin PointEnd 程序设计 CMyPaintView DrawType

广州大学学生实验报告

开课实验室:计算机科学与工程实验(电子楼418A)   2023年5月25

学院

计算机科学与网络工程学院

年级、专业、班

姓名

学号

实验课程

面向对象程序设计

成绩

实验项目

实验五  综合应用程序

指导老师

一、实验目的:

本实验是对前面所学知识的总结,通过一个比较完整的应用程序的设计,将学过的知识连贯起来,掌握开发一个实际应用程序的步骤,同时学会使用开发工具实现界面友好的应用程序。并通过本实验,掌握如何运用面向对象技术对具体的应用系统进行分析和设计。

1、类和对象的定义、对象的初始化和使用

2、面向对象的特征的应用:封装、继承和多态

3、可视化程序设计中资源的运用

4、Windows的消息传递机制

5、MFC类库的使用

6、算法的使用

二、使用仪器、器材

微机一台

操作系统:WinXP

编程软件:C++

三、实验内容及原理

利用文档/视图结构创建一个绘图板,实现用鼠标画线等功能,该画板至少要实现以下3个功能:

  1. 可以用不同的线宽和颜色画图

2)可以修改所绘制图形的线宽和颜色,效果如下图。

3)可以存储所绘制的图形。

// MyPaintView.h: CMyPaintView 类的接口

//

#pragma once

class CMyPaintView : public CView

{

protected: // 仅从序列化创建

    CMyPaintView() noexcept;

    DECLARE_DYNCREATE(CMyPaintView)

// 特性

public:

    CMyPaintDoc* GetDocument() const;

// 操作

public:

    int m_PenSize;

    COLORREF m_PenColor, m_BrushColor;

    CPoint m_PointBegin, m_PointEnd;

    enum class DrawType {

        LineSetgment, Circle, Rectangle, Ellips, Pencil, Eraser

    }m_DrawType;

// 重写

public:

    virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图

    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

protected:

    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);

    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);

    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现

public:

    virtual ~CMyPaintView();

#ifdef _DEBUG

    virtual void AssertValid() const;

    virtual void Dump(CDumpContext& dc) const;

#endif

protected:

// 生成的消息映射函数

protected:

    DECLARE_MESSAGE_MAP()

public:

    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

    afx_msg void onm ouseMove(UINT nFlags, CPoint point);

    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

    afx_msg void OnDrawLineSegment();

    afx_msg void OnDrawRectangle();

    afx_msg void OnDrawCircle();

    afx_msg void OnDrawEllips();

    afx_msg void OnSetPencil();

    afx_msg void OnSetEraser();

    afx_msg void OnSetColor();

    afx_msg void OnSetPenSize();

    afx_msg void OnFileSave();

};

#ifndef _DEBUG  // MyPaintView.cpp 中的调试版本

inline CMyPaintDoc* CMyPaintView::GetDocument() const

   { return reinterpret_cast<CMyPaintDoc*>(m_pDocument); }

#endif

// MyPaintView.cpp: CMyPaintView 类的实现

//

#include "pch.h"

#include "framework.h"

// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的

// ATL 项目中进行定义,并允许与该项目共享文档代码。

#ifndef SHARED_HANDLERS

#include "MyPaint.h"

#endif

#include "MyPaintDoc.h"

#include "MyPaintView.h"

#include "resource.h"

#include "CSetPenSizeDialog.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// CMyPaintView

IMPLEMENT_DYNCREATE(CMyPaintView, CView)

BEGIN_MESSAGE_MAP(CMyPaintView, CView)

    // 标准打印命令

    ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)

    ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)

    ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)

    ON_WM_LBUTTONDOWN()

    ON_WM_MOUSEMOVE()

    ON_WM_LBUTTONUP()

    ON_COMMAND(1, &CMyPaintView::OnDrawLineSegment)

    ON_COMMAND(2, &CMyPaintView::OnDrawRectangle)

    ON_COMMAND(3, &CMyPaintView::OnDrawCircle)

    ON_COMMAND(4, &CMyPaintView::OnDrawEllips)

    ON_COMMAND(5, &CMyPaintView::OnSetPencil)

    ON_COMMAND(6, &CMyPaintView::OnSetEraser)

    ON_COMMAND(7, &CMyPaintView::OnSetPenSize)

    ON_COMMAND(8, &CMyPaintView::OnSetColor)

    ON_COMMAND(9, &CMyPaintView::OnFileSave)

   

END_MESSAGE_MAP()

// CMyPaintView 构造/析构

CMyPaintView::CMyPaintView() noexcept

{

    // TODO: 在此处添加构造代码

    m_PenSize = 1;

    m_PenColor = RGB(0, 0, 0),

        m_BrushColor = RGB(0, 0, 0);

    m_PointBegin = CPoint(0, 0);

    m_PointEnd = CPoint(0, 0);

    m_DrawType = DrawType::LineSetgment;

}

CMyPaintView::~CMyPaintView()

{

}

BOOL CMyPaintView::PreCreateWindow(CREATESTRUCT& cs)

{

    // TODO: 在此处通过修改

    //  CREATESTRUCT cs 来修改窗口类或样式

    return CView::PreCreateWindow(cs);

}

// CMyPaintView 绘图

void CMyPaintView::OnDraw(CDC* /*pDC*/)

{

    CMyPaintDoc* pDoc = GetDocument();

    ASSERT_VALID(pDoc);

    if (!pDoc)

        return;

    // TODO: 在此处为本机数据添加绘制代码

}

// CMyPaintView 打印

BOOL CMyPaintView::OnPreparePrinting(CPrintInfo* pInfo)

{

    // 默认准备

    return DoPreparePrinting(pInfo);

}

void CMyPaintView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

    // TODO: 添加额外的打印前进行的初始化过程

}

void CMyPaintView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

    // TODO: 添加打印后进行的清理过程

}

// CMyPaintView 诊断

#ifdef _DEBUG

void CMyPaintView::AssertValid() const

{

    CView::AssertValid();

}

void CMyPaintView::Dump(CDumpContext& dc) const

{

    CView::Dump(dc);

}

CMyPaintDoc* CMyPaintView::GetDocument() const // 非调试版本是内联的

{

    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyPaintDoc)));

    return (CMyPaintDoc*)m_pDocument;

}

#endif //_DEBUG

// CMyPaintView 消息处理程序

void CMyPaintView::OnLButtonDown(UINT nFlags, CPoint point)

{

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    m_PointBegin = m_PointEnd = point;

    /*CClientDC dc(this);

    dc.MoveTo(m_PointBegin);

    dc.LineTo(m_PointEnd);

*/

    CView::OnLButtonDown(nFlags, point);

    CView::OnLButtonDown(nFlags, point);

}

void CMyPaintView::OnMouseMove(UINT nFlags, CPoint point)

{

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    if (nFlags & MK_LBUTTON)

    {

        //定义新笔和旧笔的指针

        CClientDC dc(this);

        CPen newPen, * oldPen;

        newPen.CreatePen(PS_SOLID, m_PenSize, m_PenColor);

        oldPen = dc.SelectObject(&newPen);

        switch (m_DrawType)

        {

        case DrawType::LineSetgment:

        {

             dc.SetROP2(R2_NOTXORPEN);

             dc.MoveTo(m_PointBegin);

             dc.LineTo(m_PointEnd);

             dc.MoveTo(m_PointBegin);

             dc.LineTo(point);

             m_PointEnd = point;

             break;

        }

        case DrawType::Rectangle:

        {dc.SetROP2(R2_NOTXORPEN);

        dc.SelectStockObject(5);

        CRect rectP1(m_PointBegin, m_PointEnd);

        dc.Rectangle(rectP1);

        CRect rectP2(m_PointBegin, point);

        dc.Rectangle(rectP2);

        m_PointEnd = point;

        break;

        }

        case DrawType::Pencil:

        {

             m_PointBegin = m_PointEnd;

             m_PointEnd = point;

             dc.MoveTo(m_PointBegin);

             dc.LineTo(m_PointEnd);

             break;

        }

        case DrawType::Eraser:

        {

             COLORREF pColor = dc.GetBkColor();

             CPen newPen(PS_SOLID, m_PenSize, pColor);

             dc.SelectObject(&newPen);

             m_PointBegin = m_PointEnd;

             m_PointEnd = point;

             dc.MoveTo(m_PointBegin);

             dc.LineTo(m_PointEnd);

             break;

        }

        case DrawType::Ellips:

        {dc.SetROP2(R2_NOTXORPEN);

        dc.SelectStockObject(5);

        CRect rectP1(m_PointBegin, m_PointEnd);

        dc.Ellipse(rectP1);

        CRect rectP2(m_PointBegin, point);

        dc.Ellipse(rectP2);

        m_PointEnd = point;

        break;

        }

        case DrawType::Circle:

        {

             dc.SetROP2(R2_NOTXORPEN);

             dc.SelectStockObject(5);

             int length_1 = m_PointEnd.y - m_PointBegin.y;

             if (m_PointEnd.x < m_PointBegin.x)

             {

                 m_PointEnd.x = m_PointBegin.x - abs(length_1);

             }

             else

             {

                 m_PointEnd.x = m_PointBegin.x + abs(length_1);

             }

             CRect rectP1(m_PointBegin, m_PointEnd);

             dc.Ellipse(rectP1);

             int length_2 = point.y - m_PointBegin.y;

             if (point.x < m_PointBegin.x)

             {

                 m_PointEnd.x = m_PointBegin.x - abs(length_2);

             }

             else

             {

                 m_PointEnd.x = m_PointBegin.x + abs(length_2);

             }

             m_PointEnd.y = point.y;

             CRect rectP2(m_PointBegin, m_PointEnd);

             dc.Ellipse(rectP2);

             m_PointEnd = point;

             break;

        }

        default:

             break;

        }

        dc.SelectObject(oldPen);

    }

    CView::OnMouseMove(nFlags, point);

}

void CMyPaintView::OnLButtonUp(UINT nFlags, CPoint point)

{

    // TODO: 在此添加消息处理程序代码和/或调用默认值

    CClientDC dc(this);

    CPen newPen, * oldPen;

    newPen.CreatePen(PS_SOLID, m_PenSize, m_PenColor);

    oldPen = dc.SelectObject(&newPen);

    switch (m_DrawType)

    {

    case DrawType::LineSetgment:

    {

        dc.MoveTo(m_PointBegin);

        dc.LineTo(point);

        break;

    }

    case DrawType::Rectangle:

    {

        dc.SelectStockObject(PS_NULL);

        CRect rectP2(m_PointBegin, point);

        dc.Rectangle(rectP2);

        break;

    }

    case DrawType::Pencil:

    {

        m_PointBegin = m_PointEnd;

        m_PointEnd = point;

        dc.MoveTo(m_PointBegin);

        dc.LineTo(m_PointEnd);

        break;

    }

    case DrawType::Ellips:

    {

        dc.SelectStockObject(PS_NULL);

        CRect rectP2(m_PointBegin, point);

        dc.Ellipse(rectP2);

        break;

    }

    default:

        break;

    }

    dc.SelectObject(oldPen);

    CView::OnLButtonUp(nFlags, point);

}

void CMyPaintView::OnDrawLineSegment()

{

    m_DrawType = DrawType::LineSetgment;

    // TODO: 在此添加命令处理程序代码

}

void CMyPaintView::OnDrawRectangle()

{

    // TODO: 在此添加命令处理程序代码

    m_DrawType = DrawType::Rectangle;

}

void CMyPaintView::OnDrawCircle()

{

    // TODO: 在此添加命令处理程序代码

    m_DrawType = DrawType::Circle;

}

void CMyPaintView::OnDrawEllips()

{

    // TODO: 在此添加命令处理程序代码

    m_DrawType = DrawType::Ellips;

}

void CMyPaintView::OnSetColor()

{

    // TODO: 在此添加命令处理程序代码

    CColorDialog dlg;

    if (IDOK == dlg.DoModal()) {

        m_PenColor = dlg.GetColor();

    }

}

void CMyPaintView::OnSetPenSize()

{

    // TODO: 在此添加命令处理程序代码

    CSetPenSizeDialog dlg;

    if (IDOK == dlg.DoModal())

    {

        this->m_PenSize = dlg.m_PenSize2;

    }

}

void CMyPaintView::OnSetPencil()

{

    // TODO: 在此添加命令处理程序代码

    m_DrawType = DrawType::Pencil;

}

void CMyPaintView::OnSetEraser()

{

    // TODO: 在此添加命令处理程序代码

    m_DrawType = DrawType::Eraser;

}

//添加事件处理程序,生成函数OnFileSave() :

    void CMyPaintView::OnFileSave()

{

    CClientDC dc(this);

    CRect rect;

    BOOL  showMsgTag;   //是否要弹出”图像保存成功对话框"

    BOOL saveTag;

    CString saveFilePath;

    GetClientRect(&rect);                  //获取画布大小

    HBITMAP hbitmap = CreateCompatibleBitmap(dc, rect.right - rect.left, rect.bottom - rect.top);

    //创建兼容位图

    HDC hdc = CreateCompatibleDC(dc);      //创建兼容DC,以便将图像保存为不同的格式

    HBITMAP hOldMap = (HBITMAP)SelectObject(hdc, hbitmap);

    //将位图选入DC,并保存返回值

    BitBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, dc, 0, 0, SRCCOPY);

    //将屏幕DC的图像复制到内存DC中

    CImage image;

    image.Attach(hbitmap);                //将位图转化为一般图像

    saveTag = FALSE;

    if (!saveTag)                      //如果图像是第一次被写入,则打开对话框

    {

        showMsgTag = TRUE;

        CString  strFilter = _T("位图文件|*.bmp|JPEG 图像文件|*.jpg|GIF图像文件 | *.gif | PNG图像文件 | *.png |其他格式| *.* |");

        CFileDialog dlg(FALSE, _T("bmp"), _T("iPaint1.bmp"), NULL, strFilter);

        if (dlg.DoModal() != IDOK)

             return;

        CString strFileName;          //如果用户没有指定文件扩展名,则为其添加一个

        CString strExtension;

        strFileName = dlg.m_ofn.lpstrFile;

        if (dlg.m_ofn.nFileExtension = 0)               //扩展名项目为0

        {

             switch (dlg.m_ofn.nFilterIndex)

             {

             case 1:

                 strExtension = "bmp"; break;

             case 2:

                 strExtension = "jpg"; break;

             case 3:

                 strExtension = "gif"; break;

             case 4:

                 strExtension = "png"; break;

             default:

                 break;

             }

             strFileName = strFileName + "." + strExtension;

        }

        saveFilePath = strFileName;     //saveFilePath为视类中的全局变量,类型为CString

    }

    else

    {

        showMsgTag = FALSE;

    }

    //AfxMessageBox(saveFilePath);               //显示图像保存的全路径(包含文件名)

    HRESULT hResult = image.Save(saveFilePath);     //保存图像

    if (FAILED(hResult))

    {

        MessageBox(_T("保存图像文件失败!"));

    }

    else

    {

        if (showMsgTag)

             MessageBox(_T("文件保存成功!"));

    }

    image.Detach();

    SelectObject(hdc, hOldMap);

}

  • 实验过程原始数据记录

实现功能如下:

(1)可以选择绘制多种图

(2)可以擦除所绘内容

(3)能够用选择不同颜色绘制图案

(4)能够调整画笔的粗细

(6)可以存储所绘制的图形

   

五、实验结果及分析

个人小结:

这个项目是一个基于MFC多文档的桌面应用程序,完成这个项目除了增加了对C++面向对象编程的理解,同时也加深了对MFC的理解,在整个过程中我侧重于把握前者。我的C++知识不怎么完善,写完整个项目的感觉像搭积木,而且对类中一些限定词(如const、override、virtual、protected),指针引用和STL中的容器对象不怎么理解,所以这一次重在把握程序设计的整体架构,加深理解面向对象继承和成员函数重载等概念,同时加深了对MFC的了解。

标签:广州大学,void,dc,面向对象,PointBegin,PointEnd,程序设计,CMyPaintView,DrawType
From: https://blog.csdn.net/m0_74013441/article/details/143672407

相关文章

  • 【JAVA】Java基础—面向对象编程:类的其他特性—静态成员与方法
    在Java中,静态成员和静态方法是类的一部分,而不是类的实例的一部分。这意味着静态成员和方法可以在没有创建类的实例的情况下访问。理解静态成员和方法的概念对于Java开发至关重要,因为它们在内存管理、性能优化和设计模式中扮演着重要角色。理论知识1.静态成员静态变量:也称......
  • 【JAVA】Java基础—面向对象编程:类的其他特性—static 关键字的使用
    在Java编程中,static关键字是一个非常重要的概念,它用于定义类级别的成员,而不是实例级别的成员。理解static的使用对于编写高效、清晰和可维护的代码至关重要。在实际开发中,static关键字通常用于创建工具类、常量、单例模式以及共享数据等场景。理论知识1.static变量静态变......
  • 用函数实现模块化程序设计习题
    写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入//写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入#include<stdio.h>intgetGCD(inta,intb){ intiM......
  • 学期2024-2025-1 学号20241424 《计算机基础与程序设计》第8周学习总结
    学期2024-2025-1学号20241424《计算机基础与程序设计》第8周学习总结作业信息|这个作业属于2024-2025-1-计算机基础与程序设计||-- |-- ||这个作业要求在[2024-2025-1计算机基础与程序设计第8周作业](https://www.cnblogs.com/rocedu/p/9577842.html#WEEK08||这个作业的目......
  • 《计算机基础与程序设计》第八周学习总结
    学期(如2024-2025-8)学号(如:20241404)《计算机基础与程序设计》第八周学习总结作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP这个作业要求在哪里(如2024-2025-1计算机基础与程序设计第八周作业)这个作业的目标<功能设计与面......
  • 2024-2025-1 20241406 刘书含《计算机基础与程序设计》第8周学习总结
    2024-2025-120241406《计算机基础与程序设计》第8周学习总结这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 如2024-2025-1计算机基础与程序设计第八周作业这个作业的目标 功能设计与面向对象设计>面向对象设计过程面向对象语言三要素汇编、编......
  • 2024-2025-1 20241328 《计算机基础与程序设计》第八周学习总结
    2024-2025-120241328《计算机基础与程序设计》第八周学习总结作业信息课程2024-2025-1-计算机基础与程序设计作业要求2024-2025-1计算机基础与程序设计第八周作业作业目标功能设计与面向对象设计,面向对象设计过程,面向对象语言三要素,汇编、编译、解释、执行作......
  • 2024-2025-1 20241304 《计算机基础与程序设计》第8周学习总结
    2024-2025-120241304《计算机基础与程序设计》第8周学习总结作业信息|这个作业属于哪个课程|<2024-2025-1-计算机基础与程序设计)|>|-- |-- ||这个作业要求在哪里|<作业要求的链接>(如2024-2025-1计算机基础与程序设计第八周作业)||这个作业的目标|<学习目标功能设计与面......
  • 程序设计2596基于ASP.NET的滑雪网站的设计与实现【源码+讲解视频】滑雪产品租赁网站/
    项目包含:源码、讲解视频、说明文档,部署录像开发环境开发工具:VisualStudio2010或以上版本数据库:SQLServer2005或以上版本开发语言:c#操作系统:windows7或以上浏览器:GoogleChrome(推荐)、Edge、360浏览器系统用户分为:管理员、普通用户界面设计......
  • 【JAVA】Java基础—面向对象编程:多态—多态的概念
    在Java编程中,多态是面向对象编程(OOP)的核心特性之一。它允许对象以多种形式存在,使得程序能够在运行时根据对象的实际类型调用相应的方法。这种特性不仅提高了代码的灵活性和可扩展性,还能减少代码重复,提高代码的可维护性。1.什么是多态?多态(Polymorphism)是指同一个操作作用于不......