QDUc++课程设计(简易绘图程序)
更新时间:2023-04-09 13:23:01 阅读量: 实用文档 文档下载
- 简易电子琴课程设计推荐度:
- 相关推荐
目录
1、需求与功能分析 (1)
2、系统总体框架 (2)
3、模块设计与分析 (3)
3.1画图模块 (3)
3.2贴图模块 (3)
3.3窗口模块 (4)
3.4菜单模块 (4)
3.5工具栏与状态栏模块 (4)
4、类的设计与分析 (4)
4.1、CAboutDlg类 (4)
4.2、CChildFrame类 (4)
4.3、CDib类 (4)
4.4、CDrawingDoc类 (5)
4.5、CDrawingView类 (6)
4.6、CMainFrame类 (7)
4.7、CSettingDlg类 (7)
5、特色算法分析 (8)
5.1 CDib类中的显示bmp位图 (8)
5.2 CDrawingView类中的画图部分 (10)
6、功能测试 (13)
7、存在的不足与对策 (16)
8、程序源代码 (17)
9、使用手册 (17)
10、参考文献 (20)
1、QDU需求与功能分析
为了检验一个学期以来自己学习c++这门课程能够学到多少知识,加上原来就对图像处理就比较感兴趣,曾经更有想过要做一个可以合成红蓝3D图片的一款软件,就是那种需要带上红蓝眼镜才可以看到3D效果的那种图片,自己也有用photoshop做过这样的图片,但是photoshop需要调很多东西才能合成这样的图片,而且还要用相机送两个不同的角度拍两张照片作为源图片去合成红蓝3D图片,虽然我知道原理并不难,但是当我选择了”简易绘图程序”这个课程设计的题目之后,才发现每实现一个功能都需要花很多的精力,而且实现那些功能之后还会发现各种各校的bug,需要细心去寻找解决的办法。如今课程设计也要上交,一样还有很多我想实现的功能都还没实现,最终也没有实现我想要实现的功能---合成红蓝3D图片。只做了一些简单的绘图功能。
功能分析,目前这个软件的主要功能有如下:
1、画直线:通过OnLine()函数实现。
2、画矩形:通过OnRectangle()函数实现。
3、画椭圆:通过OnEllipse()函数实现。
4、铅笔工具:可以画任意线条。通过OnPencil()函数实现。
5、橡皮擦:可以擦除所画的线条。该功能还没实现。
6、右键弹出菜单:可以在客户中点击鼠标右键,快速选择常用菜单。通过
OnContextMenu函数实现。
7、状态栏显示鼠标移动的坐标:在程序的右下角显示,通过OnUpdateX(CCmdUI
*pCmdUI)和OnUpdateY(CCmdUI *pCmdUI)这两个函数实现。
8、画图颜色选择:可以画任何颜色的线条,通过OnEditColor()函数实现。
9、读取bmp位图:可以在电脑中选择一个bmp位图,在程序中显示出来,通过
新建一个Cdib类来读取bmp文件信息再view类和Doc类调用来显示该位图。
10、保存为bmp位图:可以将在程序所画的图形保存为一幅bmp图片,通过view
中的SaveAsBmp(CString filename)实现。
1、线条类型及线宽的设置:可以将画出的线条设置成实线、虚线、点线,还可
1
以设置线条的粗细,通过示例这一功能可以立刻显示所选择线条的粗细及线型。通过新建CSettingDlg类,再在view类中调用OnSetting()函数实现画笔的对话框,CSettingDlg类中的OnPaint()函数是实现示例功能的。
11、窗口的重绘时不擦除原来的内容:可以在窗口发生变化时,窗口的内容不消
失,程序在窗口尺寸发生变化时,将会发送WM_PAINT消息,这时首先会擦除窗口背景,然后进行重绘操作,这样就把窗口中先前绘制的内容擦除了。
我是使用双缓冲来解决这个问题的,双缓冲设计思路:如果只是为了让窗口闪烁不那么厉害,避免背景色的填充是最直接的办法。但是那样的话,窗体上会变的一团糟。因为每次绘制图象的时候都没有将原来的图象清除,造成了图象的残留,于是窗体重绘时,画面往往会变的乱七八糟。所以单纯的禁止背景重绘是不够的。我们还要进行重新绘图,但要求速度很快,于是想到了使用 BitBlt函数。它可以支持图形块的复制,速度很快。我们可以先在内存中作图,然后用此函数将做好的图复制到前台,同时禁止背景刷新,这样就消除了闪烁。以上就是双缓冲绘图的基本的思路。一部分代码写在了OnLButtonUp(UINT nFlags, CPoint point)函数里面,也有一部分打码写在了OnDraw(CDC* pDC)函数里面。
2、系统总体框架
图1 总体框架
2
3、模块设计与分析
3.1画图模块:该模块的大部份功能都写在了view类里面,这样造成了后期的修改造成了一定的影响,对于排错,修复bug增加了难度,对于初次使用mfc 做一个相对大一点的程序,在函数分配,类的建立都有很多不足的地方。该模块也是此次程序的重点模块之一,主要负责画一些简单图形,例如:直线、矩形、椭圆、任意曲线(铅笔)等等;有线型、线宽的设置;还有画笔颜色的选择,可以画各种各样颜色的线条。该模块的设计思路是:简易画图工具——线型、线宽设置——颜色选择。
3.2贴图模块:该模块是为了读取bmp位图设计的,主要代码写在CDib类里面,再通过view类和Doc类去调用显示位图,这个模块同样是此次程序的重点模块之一,也是花费时间最多的一个模块,开始的时候,我使用了读取程序里面的位图资源,但是这样的办法虽然能够成功显示出位图,但是却十分麻烦,就是要先把想要显示的位图放到程序的位图资源里面,然后再通过LoadBitmap函数把位图资源加载到程序再显示出来。这样对使用都来说是非常不合理的,但是我却从这里懂得了一个显示位图的思路,要显示一幅位图需要有以下几点:
(1)读取bmp位图信息,bmp位图的信息包括:位图文件头BITMAPFILEHEADER 和位图信息头BITMAPINFOHEADER,还有就是颜色表RGBOUAD。最后一部分是实际的位图数据IMAGEDATA。
(2)创建兼容DC,这和相对比较容易,通过CreateCompatibleDC函数创建。(3)将位图选入兼容DC中,也就是先把位图存到内存之中,通过SelectObject 函数实现。
(4)将兼容DC中的位图贴到当前DC中,也就是显示在屏幕上,通过BitBlt 或者StretchBlt这两个函数都可以实现,区别在于,前者不可以自动压缩图片在一个窗口显示全部的图片内容,而后者可以。
后来我在另一本书上看到了其它的方法,也了解了DDB(设备相关图)和DIB(设备无关图),DDB位图的格式相当依赖于设备,所以它不适用于图像的交换,所以,大部分的BMP位图都会包含DIB。为了完成位图的显示,需要完成:装载位图、获取位图文件头信息、获取位图信息、获取颜色表信息、获取做准备数据信
3
息、获取位图尺寸、获取颜色总数、获取颜色位数、创建位图调色板、绘制位图等等。但是windows并没有提供DIB操作的类,需要自己动手写一个CDib的类,虽然这个类网上有可以直接复制,但是我还是按照书本那里,自己跟着课本的思路,手动把代码写上去,所以花费的时间比较多,即使是这样,有一些还是没有完全理解。封装好CDib类之后,再在View类和Doc类中写上相应的调用函数。便可以在程序中通过“打开”从磁盘中读取bmp位图了。设计思路基本上和上面的步骤一样。此时还需要面临另外一个问题,就是窗口的重绘。此功能已在功能分析上有说明,就是利用双缓冲解决这个问题。
3.3窗口模块:这部分大多数都是编译器自动生成,只做了一些修改,例如:使程序一开始运行便最大话,还是自定义程序的标题。刚开始做的时候,创建成单文档的了,后来需要用到多文档的,然后又不想再重新做过,所以只能手动修改,把单文档改成了多文档的。新建一个多文档的程序,然后用旧的那个单文档对照着多文档的源代码,一个个类的修改。
3.4菜单模块:该部分同样大部分都是编译器自动生成的,自己增添了一部分菜单例如:绘图工具、颜色设置、线条设置等等。还有右键弹出菜单,有新建窗口、颜色及线条设置、退出程序等等,让使用者可以进行快速的操作。
3.5工具栏与状态栏模块:除了编译器自动生成的之外,还加入了画直线、矩形、椭圆、铅笔等工具的快速选择,状态栏可以显示鼠标移动的坐标。该部分让我觉得有点难度的就是那些工具栏那些图标,我画了很久才画出那个铅笔的图标,听说可以从磁盘里加载这些图标的,但是我不知道怎么要怎么做。
4、类的设计与分析
4.1、CAboutDlg类
由编译器生成,只做了两处的修改:
m_pMainWnd->SetWindowText(_T("简单绘图工具")); //设定主框架窗口标题pMainFrame->ShowWindow(SW_MAXIMIZE); //显示主框架窗口默认最大化
4.2、CChildFrame类
由编译器生成,只做了一处的修改:
cs.style |= WS_VISIBLE|WS_MAXIMIZE; //使子窗口一打开就是最大化
4.3、CDib类
4
按照书本上的代码进行封装,以下是各成员函数和数据成员
4.4、CDrawingDoc类
由编译器生成,添加不少内容:因为显示bmp位图时,有一部分操作需要在这里进行,首先在头文件中添加了以下:
public:
HGLOBAL GetHObject() const { return m_hDIB; } //获取DIB对象的句柄
CPalette *GetDocPal() const { return m_palDIB; } //获取调色板指针
5
CSize GetDocDimension() const { return m_sizeDoc; } //获取调色板大小
void UpdateObject(HGLOBAL hDIB); //更新DIB对象
void SetDib(); //初始化DIB对象
protected:
HGLOBAL m_hDIB; //定义指向DIB的句柄变量
CPalette *m_palDIB; //定义指向逻辑调色板的指针
CSize m_sizeDoc; //文档大小的变量
4.5、CDrawingView类
编译器自动生成的类,全部的画图操作都在此类中完成,包括bmp位图的显示也是在该类中通过调CDib类中的函数来完成的。
6
4.6、CMainFrame类
主要同编译器生成,修改小部分:
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
ID_X,
ID_Y
};
ID_X,ID_Y是状态栏中的x和y坐标.
cs.style&=~FWS_ADDTOTITLE; //使主窗口的标题不发生变化
4.7、CSettingDlg类
由自己创建,主要是响应菜单中的各个设置选项,该类实现的功能比较少。
7
5、特色算法分析
在函数或成员方法里找出你认为比较有特色的1~2个算法。
5.1 CDib类中的显示bmp位图
流程图:
流程图1:设备无关位图的读取流程图2:设备无关图的显示流程
功能:在磁盘中读取一幅bmp位图,然后显示到屏幕上。
算法思路:首先理解bmp位图里面所包含的信息然后再以下步骤实现:
8
<1>读取bmp位图信息,bmp位图的信息包括:位图文件头BITMAPFILEHEADER
和位图信息头BITMAPINFOHEADER,还有就是颜色表RGBOUAD。最后一部分是实际的位图数据IMAGEDATA。
<2>创建兼容DC,这和相对比较容易,通过CreateCompatibleDC函数创建。
<3>将位图选入兼容DC中,也就是先把位图存到内存之中,通过SelectObject
函数实现。
<4>将兼容DC中的位图贴到当前DC中,也就是显示在屏幕上,通过BitBlt或
者StretchBlt这两个函数都可以实现,区别在于,前者不可以自动压缩图片在一个窗口显示全部的图片内容,而后者可以自动压缩和拉伸图片让它布满整个客户区。
加载位图信息代码:
显示位图部分函数代码:
5.2 CDrawingView类中的画图部分
功能:在客户区中实现画直线、矩形、椭圆、任意曲线。画完之后可以保存为bmp格式的文件。
算法思路:在View类中创建画笔,然后通过调用各个函数去画不同的形状在画图方面,我写了4个函数, OnLine()、OnRectangle()、OnEllipse()、OnPencil()。
OnLine()函数:
SetClassLong(this->GetSafeHwnd(),GCL_HCURSOR,(LONG)LoadCursor(NULL,IDC_CROSS)); DC.LineTo(m_LineEnd);
DC.MoveTo(m_LineOrg);
m_LineEnd=point;
10
DC.LineTo(m_LineEnd);
OnRectangle()函数:
DC.SelectStockObject(HOLLOW_BRUSH);
DC.Rectangle(m_LineOrg.x,m_LineOrg.y,m_LineEnd.x,m_LineEnd.y);
DC.MoveTo(m_LineOrg);
m_LineEnd=point;
DC.Rectangle(m_LineOrg.x,m_LineOrg.y,m_LineEnd.x,m_LineEnd.y);
OnEllipse()函数:
DC.SelectStockObject(HOLLOW_BRUSH);
DC.Ellipse(m_LineOrg.x,m_LineOrg.y,m_LineEnd.x,m_LineEnd.y);
DC.MoveTo(m_LineOrg);
m_LineEnd=point;
DC.Ellipse(m_LineOrg.x,m_LineOrg.y,m_LineEnd.x,m_LineEnd.y);
OnPencil()函数:
DC.SetROP2(R2_COPYPEN); //保证重叠的线不会变化,使画出来的线条始终为黑色
DC.MoveTo(m_LineOrg);
DC.LineTo(point);
m_LineOrg=point;
(注:这些代码不是写在OnLine()、OnRectangle()、OnEllipse()、OnPencil()这4个函数中,而是写在OnLButtonUp()和OnMouseMove()中)
分别把以上的四个功能的代码同时写在OnLButtonUp()和OnMouseMove()中,因为如果只写在OnLButtonUp()里面的话,画线条时在鼠标移动中线条不会立刻显示,要等鼠标左键弹起之后才显示画出来,同时在OnMouseMove()便可以解决这个问题,但是如果只在OnMouseMove()写这些函数的话,当两次把线条画在同一个地方时,原来的线条会消失,所以必须把这四个功能同时写在这两个函数之中,才可以顺利实现我想要的效果。
11
流程图:
12
6、功能测试
图6-1 多窗口测试图
图6-2 画直线测试图
13
图6-3 画矩形测试图
图6-4 画椭圆测试图
14
15
图6-5 铅笔工具测试图
图6-6 颜色设置测试图
图6-7 读取位图测试图
7、存在的不足与对策
本次课程设计,是第一次使用面向对象语言做的程序,以前一直都是在win32下的编程,在这种界面化的编程环境中,感觉到了面向对象语言的实用性,和win32下的那种感觉是完全不同的。由于是第一次使用mfc做相对大一点的程序,之前课本只有介绍过几个很简单的mfc程序,所以当时学得并不多,不过通过这次的课程设计,对mfc的使用熟悉了很多,同时也发现了自己c++语言基础很不牢固,在类与类之间的函数调用非常不熟悉,还有指针的使用也不熟悉,而且在做程序之前并没有好好的规划,造成很多的函数和成员变量都写在了View 类之中,对于排错和修得bug造成了极大的不便,有时候一个小错误都需要找很久才能找到,直到现在也依然有一些bug还没有修复的。不过程序整体上已经没有太大的问题了。
这次课程设计里面花时间最多的还是对CDib类的封装,虽然可以有书本对照着,但是依然有很多地方没理解的,为了让程序可以从磁盘中读取bmp文件和显示到屏幕上,我先后看了两篇CDib类的源代码,才开始动手封装的,在此之前还要去理解bmp文件所包含的信息,bmp位图的信息包括:位图文件头BITMAPFILEHEADER和位图信息头BITMAPINFOHEADER,还有就是颜色表RGBOUAD。最后一部分是实际的位图数据IMAGEDATA。中有理解了这些之后才有可能会理解CDib类的封装。封装完之后,还要将它导入到我的工程文件夹之中然后还要在View类和Doc类之中添加相应的代码,才能实现从有磁盘中读取bmp位图。到后来我才发现该CDib类中的,保存位图是不起作用的,每次保存都会出现错误,造成无法将所画的图,变成bmp格式的文件。我查找了一下源代码中出现的问题,虽然找到的问题所在,却不知道如何在原来的类上面更改,所以我只能在网上查其它解决方法。因为我不怎么懂得哪些函数应该写在哪里,所以我又把这些保存bmp位图的函数写到了View类里面,最后我新添了SaveAsBmp()和OnFileSaveAs()这两个函数实现保存bmp位图功能。
16
17
其中还遇到了一个比较有趣的问题,在我想要实现右键弹出菜单的时候,需要使用vc6.0添加Pop-up menu 这个控件,它居然弹出左图这样一个窗口,后来
我查了一下,原来是因为我装了win7系统
的原因,可能是vc6.0并不兼容吧!我找
网上找了好一会都没找到好的解决办法,
但我又不想重装电脑的系统,更不想用回
那古老的xp 系统。直到昨天下午,我才突
然想到了,我直接把整个工程拷到用xp 系
统的机子上,加载了Pop-up menu 这个控
件之后,再把它拷回到我的电脑上继续编写不就行了吗?我拿到宿舍同学的电脑上试了一下,没想这种方法真的可行。
最后还有一个绘图工具,必须有的功能,但是没有实现,就是橡皮擦功能,因为之前写那个CDib 的类花费了太多的时间,所以这个功能就不够时间写了。以后我会慢慢完善这个程序的。
以后再遇到要做这种软件时,一定要在前期规划再开始做,如果不这样的话会造成编程后期工作相当麻烦,各个模块写得乱七八糟,等到发现这样的问题时,就已经来不急去修改了,除非重新再写过。为了让自己在写程序的过程之中,保持着那种严紧的思维,所以前期的计划是非常重要的,先把每个模块都分开来,然后再一个个的去实现它。
8、程序源代码
由于源代码量过大,所以不粘贴,已经将源代码存在同一文件夹之中。
9、使用手册
由于本程序使用比较简单,现在只作一些的使用介绍.
下面是程序打开的初始界面
:
18
图6-8 程序主体图
菜单与工具栏,工具栏可以快捷选择要使用的画笔
图6-9 菜单栏及工具栏
此功能与工具栏的一样,只是工具栏那里会比较方便选择
图6-11 设置
图6-10 绘图工具栏
线条类型对话框,颜色设置请参考图6-6 颜色设置测试图
图6-12 线宽、线型设置
图6-13 打开位图选择
图6-14 右键弹出菜单
19
10、参考文献
【1】孙鑫余安萍编著VC++深入详解电子工业出版社
【2】高守传姚领田等编著Visual c++ 实践与提高-数字图像处理与工程应用篇中国铁道出版社
【3】陈天华编面向对象程序设计与Visual c++教程清华大学出版社
【4】明日科技宋坤刘锐宁李伟明编著Visual C++开发技术大全人民邮电出版社
【5】周长发编著精通Visual C++ 图像处理编程电子工业出版社
20
正在阅读:
QDUc++课程设计(简易绘图程序)04-09
第九知识块 统计、概率(第1课时-第3课时)(2)04-09
硝酸市场报告12-09
百家讲坛2001-2009总目录07-26
含括号的四则混合运算汇总--精选.doc04-10
06混凝土结构试题A卷答案10-24
6S现场管理制度09-13
普通话考试朗读作品60篇(内含拼音与文字及音频地址)04-06
廖金精雷霆八架与律吕择日法106-21
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- 绘图
- 简易
- 课程
- 程序
- 设计
- QDUc
- 2016年新北师大版小学四年级数学下册全册导学案(81页)
- 2022年成都理工大学物理化学复试仿真模拟三套题(1)
- 公司战略管理翻译第九章讲解
- 第四章 液压控制元件
- IATF16949内部审核员考核试题答案.docx
- 空气调节用制冷技术复习资料(整理)
- 标准化基础知识讲座
- 2022-2022学年山东省潍坊市寒亭区九年级(上)期中物理试卷(解析版
- (新版)高中数学 3.1.2 用二分法求方程的近似解教案 新人教A版必
- 钻模体工艺规程及钻2-Φ16H7孔夹具设计
- 中国专利技术交易信息服务平台建设项目可行性研究报告
- 二期工程40万吨聚氯乙烯配套70万吨电石项目安装工程施工组织设计
- 新思路MS Office高年级应用二级第二套试题答案
- 人教地理八下《“鱼米之乡”—长江三角洲地区》同课异构教案 (3)
- pep小学四级英语下册课文及翻译教程文件
- 2015年山东省卫生计生系统人员“针对性普法”考试(医护人员)题库
- 初一作文:那一刻遇见你作文600字
- 2022-2024年中国专用肥行业运营态势研究报告(目录)
- 小学百科知识竞赛试题及答案
- 年产1000吨天然食品添加剂建设项目可行性研究报告