VC单文档中画图
- 格式:wps
- 大小:79.00 KB
- 文档页数:8
VC++图像应用——绘制图形一、利用线条绘制多边形/利用线条绘制多边形和弧线1.创建一个单文档/视图结构的应用程序2.1在视图类的OnDraw编写如下代码1.点击文件→选择新建→选择MFC APP ;填写工程名;点击确认→2.选择单文档→点击完成void CMy854View::OnDraw(CDC* pDC){CMy854Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);CPen pen(PS_SOLID,2,RGB(255,0,0));CPen*pOldPen=pDC->SelectObject(&pen);//矩形pDC->MoveTo(50,30);pDC->LineTo(240,30);pDC->LineTo(240,120);pDC->LineTo(50,120);pDC->LineTo(50,30);//多边形pDC->MoveTo(300,50);pDC->LineTo(400,50);pDC->LineTo(450,100);pDC->LineTo(400,150);pDC->LineTo(300,150);pDC->LineTo(250,100);pDC->LineTo(300,50);//椭圆CRect rc(500,50,600,100);pDC->Arc(500,50,600,100,520,70,560,30);CBrush brush(RGB(255,0,0));pDC->FrameRect(rc,&brush);pDC->SelectObject(pOldPen);}2.2程序3.成功运行程序二、利用制表位控制文本输出/将字符中的制表符按照指定的宽度转换为空格输出1.创建一个单文档/视图结构的应用程序2.1在视图类的OnDraw编写如下代码1.点击文件→选择新建→选择MFC APP ;填写工程名;2.点击确认→选择单文档→点击完成void CMy854View::OnDraw(CDC* pDC){CMy854Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rc(20,100,80,160);pDC->Rectangle(rc);CRect RndRC(20,100,80,160);pDC->RoundRect(RndRC,CPoint(10,10));CPointpts[6]={CPoint(300,50),CPoint(400,50),CPoint(4 50,100),CPoint(400,150),CPoint(300,150),CPoin t(250,100)};pDC->Polygon(pts,6);}2.2程序3.成功运行程序三、绘制空件外观/在窗口中绘制空件1.创建一个单文档/视图结构的应用程序2.1在视图类的OnDraw编写如下代码3.点击文件→选择新建→选择MFC APP ;填写工程名;点击确认→4.选择单文档→点击完成void CMy854View::OnDraw(CDC* pDC){CMy854Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rc(50,50,120,80);pDC->DrawFrameControl(rc,DFC_BUTTON ,DFCS_BUTTONPUSH);CRect CapRC(130,50,160,80);pDC->DrawFrameControl(CapRC,DFC_CAP TION,DFCS_CAPTIONHELP);CRect ScrollRC(170,50,200,80);pDC->DrawFrameControl(ScrollRC,DFC_SC ROLL,DFCS_SCROLLCOMBOBOX);}2.2程序3.成功运行程序四、填充图形区域/填充区域的方法1.创建一个单文档/视图结构的应用程序2.1在视图类的OnDraw编写如下代码1.点击文件→选择新建→选择MFC APP ;填写工程名;点击确认→2.选择单文档→点击完成void CMy854View::OnDraw(CDC* pDC){CMy854Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);CRect rc(30,40,100,120);CBrush brush(RGB(128,128,128));pDC->FillRect(rc,&brush);brush.DeleteObject();CBitmap bmp;bmp.LoadBitmap(IDB_BK);brush.CreatePatternBrush(&bmp);CRect bmpRC(110,40,200,120);pDC->FillRect(bmpRC,&brush);bmp.DeleteObject();brush.DeleteObject();CRect rectrc(170,50,200,80);CRect hrc(280,60,350,140);pDC->Rectangle(rectrc);pDC->Rectangle(hrc);HRGNhRect=CreateRectRgn(210,40,300,120);HRGNhrgn=CreateRectRgn(280,60,350,140);HRGN hret=CreateRectRgn(0,0,0,0);CombineRgn(hret,hRect,hrgn,RGN_AND);brush.CreateSolidBrush(RGB(255,0,0));CRgn rgn;rgn.Attach(hret);pDC->FillRgn(&rgn,&brush);brush.DeleteObject();rgn.Detach();DeleteObject(hRect);DeleteObject(hrc);DeleteObject(hret);}2.2程序3.添加位图IDB_BK4.成功运行程序。
第五讲绘图程序-1本例知识要点单文档界面应用程序的基本概念应用程序对象主框架窗口对象文档模板在视图上绘图画笔SDI界面应用程序的基本概念SDI在同一时刻只能打开一个文档(写字板),新建或打开另一文档会自动关闭当前的活动文档;AppWizard产生五个类:见VC开发环境。
应用程序对象应用程序对象(theApp)表示一个程序,它由程序类CSDIApp创建的对象;类CSDIApp从CWinApp类派生而来,内部定义了三个成员函数;函数InitInstance用于对象的初始化,其核心是创建主窗口、文档模板、文档和视对象、显示程序窗口和更新窗口内容;菜单、工具栏按钮、加速键等的WM_COMMAND命令消息,由消息处理函数或虚函数处理消息;应用程序的入口处--SDIApp.cpp文件,其中theApp是一个全局变量,执行程序时立即为其分配内存,然后调用对象的构造函数和InitInstance函数初始化应用程序,接着调用其Run成员启动消息循环,并将消息分配给主框架窗口对象、视图对象、文档对象和应用程序对象。
消息循环获得WM_QUIT消息后结束循环,Run函数调用应用程序的成员函数ExitInstance来关闭程序窗口。
主框架窗口对象主框架窗口对象表示应用程序界面,由类CMainFrame创建的对象,继承了CFrameWnd的许多功能。
其他成员函数:1.OnCreate响应WM_CREATE消息,在Windows创建一个窗口之后和显示一个窗口之前发出;2.PreCreateWindow函数用来修改窗口的外观;3.诊断函数AssertValid和Dump;主框架窗口对象能接收标准的Windows消息(如鼠标、键盘、WM_PAINT、WM_TIMER消息等等)和命令消息。
SDI应用程序中,文档窗口即是主框架窗口。
文档模板文档模板负责创建文档、视图和框架窗口。
SDI应用程序对象只能拥有一个文档模板;MDI为其支持的每种文档类型生成不同的文档模板(如MS OFFICE WORD程序)。
VC++程序设计实验报告一、实验目的掌握MFC编程二、实验内容用MFC向导创建单文档应用程序,实现一个简单的画图程序。
●使用C++语言实现●使用VS2010集成开发环境开发●使用MFC应用程序开发框架三、实验步骤●基本功能描述1. 打开exe文件,在绘图下拉菜单中可分别设置绘制的图形形状,如直线、曲线、矩形及椭圆,线宽选项,有1-5可供选择,线型选项有实线、虚线、点线和点段线供设置,还可以设置线色以及填充色,通过弹出的颜色对话框选择需要的颜色,如果不选择线宽、线色以及填充色,则按默认的画笔,画刷来绘制选择的图形。
2. 选择好图形后,通过鼠标可以绘制出相应的直线,矩形或椭圆,鼠标的按下确定图形的起点,鼠标的拖动则确定了图形的终点,即通过鼠标的拖动来决定图形的大小,当鼠标弹起,此图形则绘制完毕。
●设计思路1. 对需要用到的变量进行初始化。
2. 选择相应的图形之后就响应相应的消息处理函数,给shape赋对应的值。
选择不同的线宽,线色与填充色,即可改变画笔或画刷的属性。
3. 鼠标的按下响应函数OnLButtonDown(),捕捉鼠标当前位置得到起点的坐标,鼠标的拖动响函数OnMouseMove()改变终点的坐标,鼠标的弹起响应OnLButtonUp(),确定终点坐标,刷新,得到绘制图形。
4. 选择图形或其它属性,可进行下一次绘制。
●软件设计A 设计步骤1.创建单文档创建一个MFC AppWizard[exe]工程,命名为“Draw”,如图1所示,并创建单文档,如图2所示。
创建成功后,系统自动生成相应的类,如图3所示。
图1 创建工程图2 创建单文档图3 生成类2.编辑菜单打开资源视图中的Menu-IDR_MAINFRAME添加需要的菜单项,如图4所示;并在菜单的属性中设定好所对应的ID,如图5所示,各项菜单对应的ID如表1所示(其中线宽菜单为弹出菜单,只需在菜单项目属性中的弹出选项前打勾即可,分隔线亦只需在菜单项目属性中选中分隔符选项即可)。
实验4 Windows绘图实验目的1、掌握设备描述表2、掌握CDC类和CGDIObject类及其派生类的应用3、掌握CFont类的一个用4、定时器的应用与定时消息的处理实验内容:本节主要掌握Windows的绘图功能,主要内容包括图形设备接口、CDC类和CGDIObject 类、用CDC类进行图形绘制、用CGDIObject类的派生类CPen类和CBrush类进行绘图。
还讲述了用CGDIObject类的派生类CFont类设置字体以及用定时器实现简单的动画效果。
1.设备描述表设备描述表(Device Context)是一个用来确定任何设备的GDI出书的位置和形象属性的集合。
应用程序病不能直接访问设备描述表,但是应用程序可以使用设备描述表的句柄来间接地存取设备描述表及其属性。
创建的设备描述表包含了它所有的属性和默认值。
在Windows环境下,所有图形文字的输出都是基于坐标系统的,图形坐标系统与基于文本的函数所使用的坐标系统是一致的。
默认的坐标系统以用户区域的左上角为原点,向右的每一个像素表示沿正X轴的一个单位,向下的每一个像素表示沿正Y轴的一个单位。
3.绘图工具绘图工具包括画线的画笔、填充图形内部以及书写正文的字体工具。
所有这些工具的使用都要经过3个步骤,即建立工具、选择工具和使用完后删除相应的工具。
4.CDC类和CGDIObject类CDC类封装了Windows的DC(设备描述表),是MFC设备环境类的基类,其他的MFC设备环境类都是CDC类的派生类。
CDC类指针的生成是用GetDC()函数来实现的,CDC类指针的销毁是用ReleaseDC()函数来实现的。
如:CDC *pDC=GetDC();ReleaseDC(pDC);CGDIObject类及其派生类只封装了GDI中的部分实体,所以CGDIObject类和GDI并不具有想CDC类和DC那样的对应关系。
CGDIObject类具有以下几个主要派生类:CBitmap:位图CBrush类:画刷CPen类:画笔CPalette类:调色板CFont类:字体CRgn类:区域构造CGDIObject派生类的对象通用有两种方法:(一)一步构造法。
vc 画图篇(整理资料)Windows中负责图形输出的是GDI(即Graphic Device Interface,图形设备接口)。
这是Windows与硬件无关的图形输出模式的体现。
GDI建立在硬件抽象层(HAL)之上,屏蔽了不同输出设备之间的差异,从而为用户提供了一个统一的“标准输出设备”。
但是,与DOS不同,Windows是多任务、进程独立的,每一个窗口都应该有一个独立的输出通道。
这样,GDI 又使用了一种简单的机制来保证在窗口中画图的不同程序之间能共享“设备”而又互不干扰。
这个机制就是DC(Device Context,设备描述表)。
有人把DC比喻成画家的画室,这里有画布、画刷、画笔等等很多工具。
就画布而言,画布形式可以不同,是的,我可以在桌上(desktop)的纸上(window)画,也可以就画在桌面上,还可以画在墙上(管的着吗!^_^)。
为此,Windows MFC提供了四种不同的DC环境(封装为C++类),以标明不同的绘制权限,即:CPaintDC, 用于在窗口客户区画图(仅限于在OnPaint处理函数中使用);CClientDC, 也用于在窗口客户区画图(限于在OnPaint处理函数之外使用);CWindowDC, 用于在窗口内任意地方画图,包括非客户区;CMetaFileDC, 用于绘制GDI图元文件。
这些类都可以直接实例化,如:CPaintDC dc(this);//this表示此DC所属窗口为当前窗口创建了一个CPaintDC对象dc。
CWindowDC一般不常用,如果想在窗口非客户区画图,可借助OnNcPaint()处理函数捕获WM_NCPAINT消息。
刚才说了,DC中还有画刷、画笔等。
这些都是DC的属性,可通过DC自身(调用其成员函数)获得。
DC属性包括文本颜色、背景颜色、映射模式、绘图模式、当前位置、当前画笔(刷)和当前字体等。
画笔(Pen)、画刷(Brush)都是独立的GDI对象,可通过CDC成员函数SelectObject()选入DC。
第二章VC6.0简单绘图说明许多学编程的都是从C 语言开始入门的,而目前的现状是:有些学校以Turbo C 为环境讲C 语言,只是Turbo C 的环境实在太老了,复制粘贴都很不方便。
有些学校直接拿VC 来讲C 语言,因为VC 的编辑和调试环境都很优秀,并且VC 有适合教学的免费版本。
可惜在VC 下只能做一些文字性的练习题,想画条直线画个圆都很难,还要注册窗口类、建消息循环等等,初学者会受严重打击的。
初学编程想要绘图就得用TC,很是无奈。
还有计算机图形学,这门课程的重点是绘图算法,而不是Windows 编程。
所以,许多老师不得不用TC 教学,因为Windows 绘图太复杂了,会偏离教学的重点。
新的图形学的书有不少是用的OpenGL,可是门槛依然很高。
要给初学者一个简单的学习平台,就要VC的开发平台和TC的简单的绘图功能,于是就有了这个EasyX 库,我们需要在VC下下载安装EasyX库,下载地址:http:///。
下面是VC下简单绘图函数的基本说明。
1.系统支持操作系统版本:Windows 2000 及以上系统。
编译环境版本:Visual C++ 6.0 / 2008(x86 & x64) / 2010(x86 & x64)。
2.安装请先将下载的压缩包解压缩,然后执行Setup.hta,并跟随提示安装。
安装程序会检测已经安装的VC 版本,并根据选择将对应的.h 和.lib 文件安装至VC 的include 和lib 文件夹内。
安装程序不会修改注册表或者本机的任何文件。
如果需要手动安装,请根据下面的文件列表说明将安装包里的相关文件分别复制到VC 对应的include 和lib 文件夹内,或者将include 和lib 文件夹放到任意位置,然后修改VC 中的Lib 和Include 的引用路径。
3.卸载由于安装程序并不改写注册表,因此在“添加删除程序”中不会看到EasyX 的卸载项。
VC基本绘图文档[键入作者姓名]VC基本绘图文档设计一个矢量图形绘制程序一、运行环境:Microsoft Visual C++ 6.0二、目标与任务:1.使设计的程矢量绘制图形序具有画点、画线、画多边形、画矩形的功能;2.其中所绘制的点、线、多边形具有保存的功能,并且能保存入数据库,数据库采用的access,文件名为shp.mdb,在设计的程序中使用ODBC访问数据库,DSN=shp,无同户名与密码;3.设计的绘图程序能读入数据库中的记录,而且可以通过自己建立的菜单[数据库操作]的子菜单[记录集导出]导出,显示在自己事先设计好的对话框设置中4.建立的[设置]菜单功能,其子菜单有[点的大小]、[线的宽度]功能。
三、程序总体结构图:四、各个功能模块详细设计1.画点画点流程图画点主要代码:2.画线画线主要代码:3.画矩形画矩形主要代码:4.画多边形画多边形的主要代码:五、数据库设计说明1.构造数据库,数据库采用access,.建立数据表,文件名为shp.mdb如下图5.2.创建ODBC数据源Windows中的ODBC组件出现系统的“控制面板”管理工具中,如下图所示:双击ODBC图标,进入ODBC数据源管理器。
然后创建用户用户DNS,过程如下下图:单击“添加”按钮,弹出创建数据源对话框,按下图选择用户所需的驱动程序(如下图):单击“完成”按钮进入指定驱动程序的安装对话框,单击“选择”按钮,将前面创建的数据库调入,结果如下图所示:单击“确定”按钮。
3.在自己的绘图MFC中绑定数据源建立新的类CShpSet类,其基类是CRecordset,单击“OK”,进入选择数据源对话框,按下图进行选择:如下图进入选择数据表对话框,选择自己已经建立过的shp.mdb数据表,如下图所示:单击“OK”,完成绑定数据源。
6.在MFC中建立显示此记录集对话框,其设计如下图所示:添加基于上图对话框的相应的类DisplayDataBaseDlg,其基类是CDlg,用于显示记录集,并建立相应的数据库操作菜单,用来显示记录集。
图形设备接口(GDI)与设备描述表(DC)图形设备接口(GDI)许多MS-DOS程序都直接往视频存储区或打印机端口输送数据,这种做法的不利之处在于需要对每种显示卡或打印机类型提供相应的驱动程序。
Windows则提供了一抽象的接口,称之为图形设备接口(GDI)。
Windows 己经提供了各种显示卡及打印机的驱动程序,这样我们的程序就可以不必关心与系统相连的显示卡及打印机的类型。
我们的程序可以通过调用GDI函数和硬件打交道,而各种GDI函数会自动参考被称为设备环境(CDC)的数据结构。
Windows会自动将设备环境结构映射到相应的物理设备,并且会提供正确的输入输出指令。
设备描述表(DC)在Windows环境中,各程序的输出必须限制在自己的窗口中。
GDI使用一种简单的机制保证在窗口中画图的各程序遵循这个规则。
这种机制即为设备描述表(DC);当Windows程序在屏幕、打印机或其它设备上画图时,它并不是将像素直接输出到设备上,而是将图绘制到由设备描述表表示的逻辑意义上的"显示平面"上去。
设备描述表是深寓于Windows中的一种数据结构,它包含GDI需要的所有关于显示平面情况的描述字段,包括相连的物理设备和各种各样的状态信息。
设备描述表对象在使用MFC编制Windows程序时,设备描述表具有更加突出的作用。
除了可作为通往各种设备的桥梁之外,设备描述表对象还封装了程序用来产生输出的GDI函数。
在MFC中,你不用捕获设备描述表句柄和调用GDI输出函数,至少不必直接捕获和调用,而是通过创建一设备描述表对象并调用它的成员函数来画图。
设备描述表句柄在平面上画图之前,Windows程序从GDI获取设备描述表句柄,并在每次调用完GDI输出函数时将句柄返回给GDI。
在MFC应用程序中获取设备描述表的一种方法是调用CWnd::GetDC,它返回指向表示Windows设备描述表的CDC对象的指针。
在画图完毕,要用CWnd::ReleaseDC释放指针(注:在OnPaint处理程序中,不用显示调用这两个函数)CDC派生类为了避免获取和释放设备描述表所带来的麻烦,MFC提供了一些CDC派生类,如CPaintDC,CClientDC,CWindowDC这些类被设计为可直接进行实例化。
一、实验目的(1) 熟悉开发环境;(2) 掌握应用MFC类库编写鼠标绘图程序的方法;(3) 掌握MFC环境中绘图函数的使用方法。
二、实验内容创建一个单文档应用程序,实现鼠标的绘图功能。
要求:(1) 创建一个工具栏,有线段、矩形、椭圆三个按钮;(2) 绘图前,选择工具栏上的按钮,确定图形的形状。
按下鼠标左键,开始绘图,结合鼠标的光标坐标值,来确定图形的形状和大小,并随着鼠标的移动在屏幕上实时绘制图形,放开鼠标左键,确定最后的图形,绘制在屏幕上。
三、实验处理列表实现绘图功能的代码清单:1、代码如下#if !defined(AFX_PIC_H__00F5F2B9_A2A6_4ED6_907E_EC07AA16 8545__INCLUDED_)#defineAFX_PIC_H__00F5F2B9_A2A6_4ED6_907E_EC07AA168545__INCL UDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CPic{public:CPic();virtual ~CPic();void Draw(CDC *PDC);public:UINT m_nDrawType;int m_nX0;int m_nY0;int m_nX1;int m_nY1;};#endif// !defined(AFX_PIC_H__00F5F2B9_A2A6_4ED6_907E_EC07AA1685 45__INCLUDED_)2、代码如下:// Pic.cpp: implementation of the CPic class.////////////////////////////////////////////////////////////////////////#include ""#include "Shiyan8.h"#include ""#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CPic::CPic(){}CPic::~CPic(){}void CPic::Draw(CDC *pDC){CPen PenLN,*pOldPen;(PS_SOLID,3,RGB(255,0,0));pOldPen = pDC->SelectObject(&PenLN);switch(m_nDrawType){case 0:pDC->MoveTo(m_nX0,m_nY0);pDC->LineTo(m_nX1,m_nY1);break;case 1:pDC->Ellipse(m_nX0,m_nY0,m_nX1,m_nY1);break;case 2:pDC->Rectangle(m_nX0,m_nY0,m_nX1,m_nY1);break;}pDC->SelectObject(pOldPen);}3、程序如下:// Shiyan8View.cpp : implementation of the CShiyan8View class//#include ""#include "Shiyan8.h"#include "Shiyan8Doc.h"#include "Shiyan8View.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CShiyan8ViewIMPLEMENT_DYNCREATE(CShiyan8View, CView)BEGIN_MESSAGE_MAP(CShiyan8View, CView)//{{AFX_MSG_MAP(CShiyan8View)ON_COMMAND(ID_DRAW_FILEOPEN, OnDrawFileopen)ON_UPDATE_COMMAND_UI(ID_DRAW_FILEOPEN, OnUpdateDrawFileopen)ON_COMMAND(ID_DRAW_FILESA VE, OnDrawFilesave)ON_UPDATE_COMMAND_UI(ID_DRAW_FILESA VE, OnUpdateDrawFilesave)ON_WM_LBUTTONDOWN()ON_WM_MOUSEMOVE()ON_WM_LBUTTONUP()//}}AFX_MSG_MAPON_COMMAND_RANGE(ID_DRAWTYPE_LINE,ID_DRAWTYPE_RECT,OnDrawType)ON_UPDATE_COMMAND_UI_RANGE(ID_DRAWTYPE_LIN E, ID_DRAWTYPE_RECT,OnUpdateDrawType)// Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CShiyan8View construction/destructionCShiyan8View::CShiyan8View(){// TODO: add construction code herem_nDrawType = 0;m_nX0 = 0;m_nY0 = 0;m_nX1 = 0;m_nY1 = 0;m_nPicNum = 0;}CShiyan8View::~CShiyan8View(){}BOOL CShiyan8View::PreCreateWindow(CREATESTRUCT& cs) {// TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CShiyan8View drawingvoid CShiyan8View::OnDraw(CDC* pDC){CShiyan8Doc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data herefor(int i=0;i<m_nPicNum;i++){m_Pic[i].Draw(pDC);}}/////////////////////////////////////////////////////////////////////////////// CShiyan8View printingBOOL CShiyan8View::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CShiyan8View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CShiyan8View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}/////////////////////////////////////////////////////////////////////////////// CShiyan8View diagnostics#ifdef _DEBUGvoid CShiyan8View::AssertValid() constCView::AssertValid();}void CShiyan8View::Dump(CDumpContext& dc) const{CView::Dump(dc);}CShiyan8Doc* CShiyan8View::GetDocument() // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CShiyan8Doc)));return (CShiyan8Doc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CShiyan8View message handlersvoid CShiyan8View::OnDrawFileopen(){// TODO: Add your command handler code here}void CShiyan8View::OnUpdateDrawFileopen(CCmdUI* pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(FALSE);}void CShiyan8View::OnDrawFilesave(){// TODO: Add your command handler code herevoid CShiyan8View::OnUpdateDrawFilesave(CCmdUI* pCmdUI){// TODO: Add your command update UI handler code herepCmdUI->Enable(FALSE);}void CShiyan8View::OnDrawType(WORD nID){m_nDrawType = nID-ID_DRAWTYPE_LINE;}void CShiyan8View::OnUpdateDrawType(CCmdUI* pCmdUI){pCmdUI->SetRadio(m_nDrawType == pCmdUI->m_nID-ID_DRAWTYPE_LINE);}void CShiyan8View::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultm_nX0 = m_nX1 = ;m_nY0 = m_nY1 = ;CView::OnLButtonDown(nFlags, point);}void CShiyan8View::OnMouseMove(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCClientDC dc(this);CPen PenBK,PenLN,*pOldPen;if(nFlags & MK_LBUTTON)(PS_SOLID,1,RGB(255,255,255)); (PS_DASH, 1,RGB(255,0,0)); pOldPen = (&PenBK);switch(m_nDrawType){case 0:(m_nX0,m_nY0);(m_nX1,m_nY1);break;case 1:(m_nX0,m_nY0,m_nX1,m_nY1);break;case 2:(m_nX0,m_nY0,m_nX1,m_nY1);break;}(&PenLN);m_nX1 = ;m_nY1 = ;switch(m_nDrawType){case 0:(m_nX0,m_nY0);(m_nX1,m_nY1);break;case 1:(m_nX0,m_nY0,m_nX1,m_nY1);break;case 2:(m_nX0,m_nY0,m_nX1,m_nY1);break;}(pOldPen);CView::OnMouseMove(nFlags, point);}void CShiyan8View::OnLButtonUp(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call default CClientDC dc(this);CPen PenBK,PenLN,*pOldPen;(PS_SOLID,1,RGB(255,255,255));(PS_SOLID,3,RGB(255,0,0));pOldPen = (&PenBK);switch(m_nDrawType){case 0:(m_nX0,m_nY0);(m_nX1,m_nY1);break;case 1:(m_nX0,m_nY0,m_nX1,m_nY1);break;case 2:(m_nX0,m_nY0,m_nX1,m_nY1);break;}(&PenLN);m_nX1 = ;m_nY1 = ;switch(m_nDrawType){case 0:(m_nX0,m_nY0);(m_nX1,m_nY1);break;case 1:(m_nX0,m_nY0,m_nX1,m_nY1);break;case 2:(m_nX0,m_nY0,m_nX1,m_nY1);break;}m_Pic[m_nPicNum].m_nDrawType = m_nDrawType;m_Pic[m_nPicNum].m_nX0 = m_nX0;m_Pic[m_nPicNum].m_nY0 = m_nY0;m_Pic[m_nPicNum].m_nX1 = m_nX1;m_Pic[m_nPicNum].m_nY1 = m_nY1;m_nPicNum++;(pOldPen);CView::OnLButtonUp(nFlags, point);}其他的程序略四、实验总结:1.在Resource View中展开menu资源菜单中,设计如下:2、在Resource View中展开Toorlbar资源菜单中,设计如下:3、本实验的一部分代码可以从实验六中复制过来,但应注意变量名称。
VC绘图/游戏简易教程--1:创建新项目 (1)VC绘图/游戏简易教程--2:简单绘图,学习单步执行 (1)VC绘图/游戏简易教程--3:熟悉更多的绘图语句 (2)VC绘图/游戏简易教程--4:结合流程控制语句来绘图 (3)VC绘图/游戏简易教程--5:数学知识在绘图中的运用 (5)VC绘图/游戏简易教程--6:实现简单动画 (6)VC绘图/游戏简易教程--7:捕获按键,实现动画的简单控制8 VC绘图/游戏简易教程--8:用函数简化相同图案的制作 (10)VC绘图/游戏简易教程--9:绘图中的位运算 (12)VC绘图/游戏简易教程--10:用鼠标控制绘图/游戏程序 (16)VC绘图/游戏简易教程--11:随机函数 (18)VC绘图/游戏简易教程--12:数组 (20)VC绘图/游戏简易教程--13:getimage / putimage / loadimag / saveimage / IMAGE 的用法 (25)VC绘图/游戏简易教程--14:位运算实现颜色分离处理 (27)VC绘图/游戏简易教程--16:设备上下文句柄 (29)VC绘图/游戏简易教程--1:创建新项目输入以下代码试试(无需理解代码含义):#include <graphics.h>#include <conio.h>void main(){initgraph(640, 480);line(200, 240, 440, 240);line(320, 120, 320, 360);getch();closegraph();}执行后应该可以看到屏幕正中央有一个十字。
VC绘图/游戏简易教程--2:简单绘图,学习单步执行[本期目标]学会简单绘图,并学会简单调试。
先看看上一课的代码,我加上了注释#include <graphics.h> // 绘图库头文件,绘图语句需要#include <conio.h> // 控制台输入输出头文件,getch()语句需要void main(){initgraph(640, 480); // 初始化640x480的绘图屏幕line(200, 240, 440, 240); // 画线(200,240) - (440,240)line(320, 120, 320, 360); // 画线(320,120) - (320,360)getch(); // 按任意键closegraph(); // 关闭绘图屏幕}解释一下:1. 创建的绘图屏幕640x480,表示横向有640个点,纵向有480个点。
利用VC编写简单的绘图程序上机实验环境亦可选择Microsoft Visual C++〔以下简称VC〕。
VC是美国微软公司生产的基于其Windows系统的软件开发工具。
它具有使用灵活,并与32位Windows内核〔使用于Windows 2000/Windows XP〕高度兼容的特点,从而被Windows程序员们广泛使用。
VC 在图形图像处理方面有着广泛的应用,MFC中提供了大量的图形图像函数,下面我们将对使用VC/MFC编写简单的绘图程序。
一、使用VC编写MFC单文档应用程序很简单,只需要按照下面几个步骤进行:1.翻开MSVC集成开发环境。
双击桌面或“开始〞菜单中的Microsoft VisualC++6.0,不久将看到VC的编辑窗口,如图3-5:图1 VC启动界面2.选择菜单“File | New〞,在弹出的对话框中1)单击上方的选项卡“Project〞,2)选择“MFC AppWizard(exe)〞,3)在“Project name〞一栏中填写工程名,例如draw,4)在“Location〞一栏中填写你想把文件存放的位置〔目录〕。
然后按“OK〞。
见图2。
注意:第4〕步中指定你自己的目录,不要使用系统的缺省目录或者随便放在根目录或者其他的目录下。
这样便于你找到自己编写的程序。
图2 应用程序向导主界面3.在MFC Appwizard-Step 1中选择“Single Document〞,即单文档应用程序,点击“Finish〞,如图3所示。
注意:对于下面的操作我们可以忽略,直接点Finish即可。
图3 应用程序向导中选择单文档视图4.系统弹出一个当前工程信息的对话框,如图4所示,直接点“OK〞即可。
图4 新建工程信息5.进入程序编写的主界面,屏幕左下方为工作区,如图5所示,工作区中共有三种视图,分别是:1)文件视图〔“FileView〞〕,主要包括头文件,cpp文件以及资源文件。
我们在头文件中一般添加类的定义,类的成员变量和函数的声明,而在cpp文件中具体实现函数。
用VC6.0单文档进行数字图像处理以前写一些VC6.0的数字图像处理程序,大多是用对话框写的。
主要是因为对话框就那么两个类:App类和Dlg类,所以理解也比较简单。
但是,最近,听到有人这么讲文档视图类才是MFC的核心。
所以,也想尝试一下。
这两天做了点简单的尝试,特此总结一下。
1、写一个DIB类,因为在单文档或多文档下,如果不写一个DIB 类,那么你做处理就比较麻烦了。
因为我们经常要将这个DIB类的对象来共享,比如一般的DIB类的对象都是放到Doc类中。
那么我们经常要在View类和MainFrame类中引用到Doc类的Dib类的实例。
如果是多个Doc类和View类,这种数据的共享就显得更加重要了。
2、在DIB类中要有一个获得图像像素数据的指针的函数和一个能够设置DIB类的像素数据的指针。
因为,在MainFrame类中我们需要获得Doc类的一个DIB类的对象之后,可以获得指向该对象的像素数据的指针,因为我们要对其中的像素数据进行操作。
另外,我们要将操作之后的像素数据拷贝进DIB类的对象的像素数据中。
3、DIB类中还需要有获得操作像素数据中要用到的函数:获得图像高度、获得图像宽度、获得图像位数、获得图像每行像素所占的字节数。
4、DIB类中当然还需要有读入和写出图像的函数。
5、由于菜单的响应函数都是在MainFrame类中,所以,我们需要在MainFrame类中获得Doc类和View类的指针。
获得Doc类的指针主要是利用其中的DIB类的对象;获得View类的指针主要是更新显示处理后的图像效果。
所以在MainFrame类的cpp文件的包含文件中要包含Doc类和View类的h文件。
获得方法是调用MainFrame类的GetActiveDoc()和GetActiveView()函数。
好了,下面说说主要的程序:DIB类的头文件:// Dib.h: interface for the CDib class.////////////////////////////////////////////////////////////// //////////#if !defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_A AF8D2F15064__INCLUDED_)#defineAFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__I NCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CDib{public:CDib();//构造函数virtual ~CDib();//析构函数private:BITMAPFILEHEADER *m_pBmfh;//保存位图文件头BYTE *m_pBmInfo;//保存位图信息头+调色板(用于显示位图)BYTE *m_pPixel;//保存位图像素数据BITMAPINFOHEADER *m_pBmih;//保存位图信息头public:BOOL m_bRead;//标志是否调用了Read函数public:int Read(CString filename);//读入位图void Draw(CDC *pDC);//显示位图int Write(CString filename);//写出位图public:DWORD GetWidth() const;//获得位图宽度DWORD GetHeight() const;//获得位图高度WORD GetBitCount() const;//获得位图位数DWORD GetLineBytes() const;//获得位图每行像素所占字节数BYTE* GetPixelPointer() const;//获得指向位图像素数据的指针void SetPixelMatrix(BYTE *newPixel);//设置位图的像素矩阵};#endif// !defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D 2F15064__INCLUDED_)DIB类的cpp文件:// Dib.cpp: implementation of the CDib class.////////////////////////////////////////////////////////////// //////////#include "stdafx.h"#include "VampireImage.h"#include "Dib.h"//包含DIB类的头文件#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////// //////////// Construction/Destruction//////////////////////////////////////////////////////////// //////////CDib::CDib(){m_pBmfh=new BITMAPFILEHEADER;m_pBmih=new BITMAPINFOHEADER;m_pBmInfo=NULL;m_pPixel=NULL;m_bRead=FALSE;}CDib::~CDib(){if(m_pBmfh){delete m_pBmfh;m_pBmfh=NULL;}if(m_pBmih){delete m_pBmih;m_pBmih=NULL;}if(m_pBmInfo){delete[] m_pBmInfo;m_pBmInfo=NULL;}if(m_pPixel){delete[] m_pPixel;m_pPixel=NULL;}}//////////////////////////////////////////////////////////////////////// Methods//////////////////////////////////////////////////////////// //////////int CDib::Read(CString filename){CFile dib;if(!dib.Open(filename,CFile::modeRead)){return -1;}if(dib.Read(m_pBmfh,sizeof(BITMAPFILEHEADER))!=size of(BITMAPFILEHEADER)){//读取位图文件头dib.Close();return -1;}m_pBmInfo=new BYTE[m_pBmfh->bfOffBits-14];//为信息头+调色板分配空间if(!m_pBmInfo){dib.Close();return -1;}if(dib.Read(m_pBmInfo,m_pBmfh->bfOffBits-14)!=(m_pBmfh->bfOffBits-14)){//读取位图信息头+调色板(如果有)delete[] m_pBmInfo;m_pBmInfo=NULL;dib.Close();return -1;}memcpy(m_pBmih,m_pBmInfo,sizeof(BITMAPINFOHEAD ER));//拷贝40字节到位图信息头中WORD bitCount=m_pBmih->biBitCount;DWORD width=m_pBmih->biWidth;DWORD height=m_pBmih->biHeight;DWORD lineBytes=(width*bitCount+31)/32*4;m_pPixel=new BYTE[height*lineBytes*sizeof(BYTE)];//为位图像素矩阵分配空间if(!m_pPixel){dib.Close();return -1;}if(dib.Read(m_pPixel,height*lineBytes*sizeof(BYTE))!=(h eight*lineBytes*sizeof(BYTE))){//读取位图像素矩阵dib.Close();delete[] m_pBmInfo;m_pBmInfo=NULL;delete[] m_pPixel;m_pPixel=NULL;return -1;}dib.Close();m_bRead=TRUE;//标志已经使用过Read函数return 0;}int CDib::Write(CString filename){CFile dib;if(!dib.Open(filename,CFile::modeWrite | CFile::modeCreate | CFile::typeBinary)){return -1;}dib.Write(m_pBmfh,sizeof(BITMAPFILEHEADER));//写入位图文件头dib.Write(m_pBmInfo,m_pBmfh->bfOffBits-14);//写入位图信息头+调色板(如果有)dib.Write(m_pPixel,GetHeight()*GetLineBytes()*sizeof(B YTE));//写入位图像素矩阵dib.Close();return 0;}void CDib::Draw(CDC *pDC){DWORD width=GetWidth();DWORD height=GetHeight();StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,h eight,m_pPixel,(BITMAPINFO*)m_pBmInfo,DIB_RGB_COLORS ,SRCCOPY);//用StretchDIBits显示位图}//////////////////////////////////////////////////////////// //////////// Get/Set Functions//////////////////////////////////////////////////////////// //////////WORD CDib::GetBitCount() const{return m_pBmih->biBitCount;}DWORD CDib::GetWidth() const{return m_pBmih->biWidth;}DWORD CDib::GetHeight() const{return m_pBmih->biHeight;}DWORD CDib::GetLineBytes() constreturn (GetWidth()*GetBitCount()+31)/32*4;}BYTE* CDib::GetPixelPointer() const{return m_pPixel;}void CDib::SetPixelMatrix(BYTE *newPixel){delete[] m_pPixel;//删除原来的像素矩阵m_pPixel=NULL;m_pPixel=new BYTE[GetHeight()*GetLineBytes()];//为新的像素矩阵分配空间if(!m_pPixel){return;}memcpy(m_pPixel,newPixel,GetHeight()*GetLineBytes()); //将心的像素矩阵拷贝到DIB类中}View类中的OnDraw函数:void CVampireImageView::OnDraw(CDC* pDC){CVampireImageDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereif(pDoc->GetDibInstance()->m_bRead==TRUE){//如果已经读入图片,则调用DIB类的对象的Draw函数来显示位图pDoc->GetDibInstance()->Draw(pDC);}}Doc类中的获得DIB类的对象的指针的函数:CDib* CVampireImageDoc::GetDibInstance(){return m_pDib;}Doc类中的打开和保存菜单的函数:BOOL CVampireImageDoc::OnOpenDocument(LPCTSTR lpszPathName){if (!CDocument::OnOpenDocument(lpszPathName))return FALSE;// TODO: Add your specialized creation code herem_pDib->Read(lpszPathName);return TRUE;}CDib* CVampireImageDoc::GetDibInstance(){return m_pDib;}BOOL CVampireImageDoc::OnSaveDocument(LPCTSTR lpszPathName){// TODO: Add your specialized code here and/or call the base classCFileDialog sfd(false,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"BMP Files(*.bmp)|*.bmp||");if(sfd.DoModal()!=IDOK){return FALSE;}if((m_pDib->Write(sfd.GetPathName()))==-1){AfxMessageBox("保存失败");return FALSE;}return TRUE;;}MainFrame类中灰度图菜单的响应函数:void CMainFrame::OnGrayimage(){// TODO: Add your command handler code hereCVampireImageDoc*pDoc=(CVampireImageDoc*)this->GetActiveDocument();//获得当前的Doc类的指针DWORDwidth=(pDoc->GetDibInstance())->GetWidth();//获得DIB对象的宽度DWORDheight=(pDoc->GetDibInstance())->GetHeight();//获得DIB对象的高度WORDbitCount=(pDoc->GetDibInstance())->GetBitCount();//获得DIB对象的位数DWORDlineBytes=(pDoc->GetDibInstance())->GetLineBytes();//获得DIB对象的每行所占字节数BYTE*dib=(pDoc->GetDibInstance())->GetPixelPointer();//得到DIB对象的像素数据的指针BYTE *newDib=new BYTE[height*lineBytes];//新建一块内存if(!newDib){return;}memcpy(newDib,dib,height*lineBytes);//将DIB对象的像素数据拷贝至新建的内存if(bitCount==8)//如果位图是8位{AfxMessageBox("已经是8位的灰度图了,没有必要再转换。
VC++环境下绘图上机要求:1.在VC中建立单文档工程;熟悉工作区中的类视图,资源视图,文件视图;熟悉视图类。
2.熟悉视图类的OnDraw函数,能够定义矩形;能够在OnDraw函数中画点、画线、画弧、画矩形、画椭圆、画多边形、画折线、画样条曲线。
3.能够设置新的画笔画图;能够定义多边形;能够设置新的画刷填充矩形区域、任意封闭区域。
4.能够在视图类中添加成员变量和成员函数;能够自定义函数将OnDraw的绘图指针传递过去;能够在自定义函数中定义绘图变量并应用其绘图。
5.能够应用应用鼠标事件交互绘图。
举例说明:1.画点void CCyc V iew::OnDraw(CDC* pDC){CCycDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// TODO: add draw code for native data herePOINT pt={20,30}; //等价于pt.x=20; pt.y=30;pDC->SetPixel (50,50,RGB(255,0,0));COLORREF color=RGB(0,0,255);pDC->SetPixel(pt, color);}2.画线段pDC->MoveT o(50,100);pDC->LineT o(100,50);3.定义矩形CRect rect(x1,y1, x2, y2);矩形对象rect的对角线为(x1,y1)—(x2, y2)注意:所给参数必须满足x1<x2 , y1<y24.画弧函数原型:BOOL Arc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);或BOOL Arc(LPCRECT lpRect, POINT ptStart, POINT ptEnd);(x1,y1)与(x2, y2)作为矩形对角线,所画弧为该矩形内切椭圆的一部分,从ptStart即(x3,y3)逆时针到ptEnd即(x4,y4)的弧,如图。
第5章图形绘制在Visual C++6.0中,掌握图形程序设计方法是非常重要的。
因为图形在任何一个可视化工程项目中都是不可缺少的。
CDC(设备环境)类封装了图形绘制所需要的各种操作。
一、设备环境与设备环境类(CDC)1 设备环境设备环境也称设备上下文(Device Context,简称DC),是计算机物理设备的代表,也是图形设备接口的主要组成部分。
由于Windows是一个与设备无关的操作系统,即Windows不允许直接访问硬件,如果用户想将文本和图形绘制到显示器或其它设备中去,必须通过“设备环境”这个抽象层与硬件进行通信,设备上下文对象的作用就是实现Windows的设备无关性,任何向屏幕上进行输出的功能都要间接地通过它来完成。
设备上下文是Windows的一种数据结构,它包含了有关如显示器或打印机等设备的绘图属性信息。
所有绘画都是通过设备上下文对象来实现的,该对象封装了Windows 的画线、图形和文本的API函数。
设备上下文允许在Windows下独立于设备的绘画。
设备上下文不仅能够被用来在屏幕上绘画,它也可以将绘画输出到打印机和图元文件中。
2 设备环境类设备环境类CDC直接继承于CObject类,该类定义了一类设备对象。
CDC对象提供了非常多的成员函数,与设备环境的显示器、打印机等一起工作。
例如,如果要在显示器等设备上绘制图形,我们可以用MFC提供的设备环境类CDC类,因为CDC类中包含了绘图所需要的所有成员函数。
同时。
MFC还提供了以下几个CDC的派生类:1、CPaintDC类此类比较特殊,它的构造函数和析构函数都是针对OnPaint进行的。
用户一旦获得相关的CDC指针,就可以将它当做任何设备环境(包括屏幕、打印机)指针来使用,CPaintDC类的构造函数会自动调用BeginPaint,而它的析构函数则会自动调用EndPaint。
2、CClientDC和CWindowDC类CClientDC只能在窗口的客户区(不包括边框、工具条、标题栏、滚动条、菜单栏以及状态栏)进行绘图,点(0,0)通常指的是客户区的左上角。