ImageVerifierCode 换一换
格式:DOCX , 页数:50 ,大小:328.70KB ,
资源ID:11509362      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-11509362.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(编程绘图.docx)为本站会员(b****3)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

编程绘图.docx

1、编程绘图第8章 GDI编程1-绘图详细介绍了GDI绘图,希望对你有帮助:GDI(Graphics Device Interface,图形设备接口)是Windows操作系统的传统图形子系统,负责与设备无关的图形绘制,Win32 API为应用程序提供了丰富的绘图函数和功能,MFC对它们进行了C+类封装,参见图8-1。Windows应用程序MFCWin32 API执行程序用户界面(User)GDI+图形子系统(GDI)设备驱动程序内核(Kernel)图形驱动程序硬件抽象层(HAL)计算机硬件图8-1 GDI与Windows操作系统(其中彩色部分为操作系统)传统GDI是随Windows 1.0于198

2、5年11月推出的,新式GDI+则是随Windows XP于2001年10月推出的GDI的改进版,增加了混色、渐变画刷、样条曲线、矩阵变换、图像处理、持久路径等新功能。随Windows Vista及.NET框架3.0微软于2006年11月又推出了基于DirectX和.NET框架的全新图形子系统WPF(Windows Presentation Foundation,视窗显示/展现基础),它统一了桌面和浏览器等客户端应用程序的图形界面,采用XAML声明式编程,将用户界面的设计和编程彻底分离开来,是Windows的下一代GUI显示系统。本书从第8章到第11章,将详细讨论如何使用GDI进行传统的Wind

3、ows图形编程,包括绘图、文字、图像、动画、图标、图元文件和打印等内容。GDI+是建立在GDI之上的,计划在第14和15章中作简单介绍。WPF则是以.NET框架为基础的,准备在第19上和20章中再加以讨论。在MFC应用程序中,绘图一般在视图类的(屏幕/打印机)绘图消息响应函数OnDraw中进行,例如:void CDrawView:OnDraw(CDC* /*pDC*/) CDrawDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; / TODO: 在此处为本机数据添加绘制代码每次需要重绘窗口时(如程序启动、窗口大小

4、改变、全部或部分窗口重现、程序员调用函数RedrawWindow或Invalidate/UpdateWindow),应用程序框架都会调用此CWnd消息响应成员函数(的覆盖)来绘制窗口客户区。在Windows中,绘图一般在框架窗口的客户区(对应于视图类C*View)进行,使用的是封装在MFC的设备上下文(Device-Context,DC)类CDC中的各种绘图函数。在绘图前,一般需先得到客户区大小和CDC对象、设置绘图颜色,然后再根据文档数据或用户操作来绘制各种图形。8.1 几何对象的结构和类图8-2 GDI几何对象的结构与类为了使用绘图函数,应该先了解绘图所用到的几种表示几何对象的结构和类,包

5、括点、大小和矩形,其中常用的是点和矩形。这些结构和类被分别定义在头文件windef.h和afxwin.h中。MFC中的几何对象类都是独立的类(不是CObject的派生类),是对API中对应结构的C+封装,参见图8-2。8.1.1点点(point)在API中的结构为POINT,对应的MFC类为CPoint。1点结构POINTAPI中的点数据结构POINT用来表示一点的x、y坐标:typedef struct tagPOINT LONG x; LONG y; POINT;其中,类型LONG(32位整数)的定义为:typedef long LONG;2点类CPointMFC中的点类CPoint为一个

6、没有基类的独立类,封装了POINT结构,有成员变量x和y,其构造函数有5种:CPoint( ); / 默认CPoint( int initX, int initY ); / 常用CPoint( POINT initPt );CPoint( SIZE initSize );CPoint( LPARAMdwPoint ); / 低字设为x、高字设为yCPoint类还定义了4个平移和设置的成员函数:void Offset(int xOffset, int yOffset);void Offset(POINT point);void Offset(SIZE size);void SetPoint(in

7、t X, int Y);另外,CPoint类还重载了+、-、+=、-=、=、!= 等运算符来支持CPoint对象和CPoint、POINT、SIZE对象之间的运算。8.1.2大小大小(size,尺寸)在API中的结构为SIZE,在MFC中的类为CSize。1大小结构SIZE大小结构SIZE用来表示矩形的宽cx和高cy:typedef struct tagSIZE LONGcx;LONGcy; SIZE;2大小类CSizeMFC中的大小类CSize也为一个没有基类的独立类,封装了SIZE结构,有成员变量cx和cy,其构造函数也有5种:CSize( );CSize( int initCX, int

8、 initCY );CSize( SIZE initSize );CSize( POINT initPt );CSize( DWORD dwSize ); / 低字设为cx、高字设为cyCSizet类也重载了+、-、+=、-=、=、!= 等运算符来支持CSize对象和CSize、POINT、SIZE、RECT对象之间的运算。8.1.3矩形矩形(rectangle)在API中的结构为RECT,在MFC中的类为CRect。1矩形结构RECTAPI中的矩形结构RECT定义了矩形的左上角与右下角的坐标:typedef struct tagRECT LONG left; LONG top; LONG r

9、ight; LONG bottom; RECT;2矩形类CRectMFC中的矩形类CRect也为一个没有基类的独立类,封装了RECT结构,有成员变量left、top、right和bottom,其构造函数有6种:CRect( ); / 默认CRect( int l, int t, int r, int b ); / 常用CRect( const RECT& srcRect );CRect( LPCRECT lpSrcRect );CRect( POINT point, SIZE size );CRect( POINT topLeft, POINT bottomRight );CRect类重载了=

10、,+、-,+=、-=,=、!=,&、|,&=、|= 等运算符来支持CRect对象和CRect、POINT、SIZE、RECT对象之间的运算。还定义了转换符LPCRECT和LPRECT来自动完成CRect对象到矩形结构和类指针LPCRECT和LPRECT的转换。CRect类中常用的属性和成员函数有:int Width( ) const;int Height( ) const;CSize Size( ) const;CPoint& TopLeft( );CPoint& BottomRight( );CPoint CenterPoint( ) const;void SwapLeftRight();B

11、OOL IsRectEmpty( ) const;BOOL PtInRect( POINT point ) const;void SetRect( int x1, int y1, int x2, int y2 );void SetRect(POINT topLeft, POINT bottomRight);void OffsetRect(int x, int y);void MoveToXY(int x, int y);3判断点是否在矩形中有时需要判断某点(如鼠标位置)是否在某一矩形区域(如控件)中,这可以调用CRect类的PtInRect函数来做:BOOL PtInRect( POINT p

12、oint ) const;该函数当点point在其矩形区域内时,返回真。注意,该矩形区域不包括矩形的右边界和底边界。例如:CRect rect( 10, 10, 371, 267 );void CDrawView:OnLButtonUp(UINT nFlags, CPoint point) / TODO: 在此添加消息处理程序代码和/或调用默认值 if ( rect.PtInRect( point ) ) . . CView:OnLButtonUp(nFlags, point);8.1.4 获得客户区大小绘图一般都是在框架窗口的客户区(对应于视图类)进行,而客户区的大小在运行时可由用户动态改变

13、,为了使绘制的图形能随窗口大小而自动改变,需先得到当前客户区大小的数据(宽和高)。获取客户区大小的方法有如下两种:1OnSize获取客户区大小的第一种方法是通过消息响应函数OnSize中获得。可利用属性窗口的消息页,为视图类添加WM_SIZE消息的响应函数OnSize。该函数会在窗口第一次显示或窗口大小被改变时被系统调用。其输入参数中的cx和cy就是当前客户区的宽和高,可将它们赋值给类变量(如m_iW和m_iH)供绘图时使用。例如:void CDrawView:OnSize(UINT nType, int cx, int cy) CView:OnSize(nType, cx, cy); / T

14、ODO: 在此处添加消息处理程序代码 m_iW = cx; m_iH = cy;其中,nType的值为: SIZE_MAXIMIZED(窗口已被最大化) SIZE_MINIMIZED(窗口已被最小化) SIZE_RESTORED(窗口已被改变大小) SIZE_MAXHIDE(其他窗口被最大化) SIZE_MAXSHOW(其他窗口从最大化还原)2GetClientRect获取客户区大小的第二种方法是调用窗口类的获取客户区矩形成员函数GetClientRect来得到。具体做法是,在绘图前定义一个矩形结构变量rect,然后再调用CWnd类的成员函数GetClientRect来得到当前客户区矩形的数据

15、,该函数的原型为:void GetClientRect( LPRECT lpRect ) const;其中,矩形结构的右(right)与底(bottom)就是客户区的宽与高(其左left与顶top都为0)。例如: RECT rect; GetClientRect(&rect); int iW = rect.right, iH = rect.bottom;8.2 绘图环境DC在Windows中,绘图包括绘制图形、显示位图和输出文字,它们都需要使用绘图环境DC(Device-Context, 设备上下文)。MFC将DC结构和所有的绘图函数、绘图对象的访问函数、绘图模式与参数的设置函数都封装到了CD

16、C类中。8.2.1DC结构DC是Windows为设备无关的图形绘制而定义的一种数据结构,包含了一组图形对象及关联属性和若干影响输出的图形模式和绘图参数。所有的GDI绘图操作,都是采用DC中的当前图形对象作为绘图工具,并且都是在DC中的当前图形模式下使用当前的绘图参数进行的。1图形对象Windows的图形对象(graphic object)包括画线状图的笔、绘制和填充面状图的刷、用于复制和滚动部分屏幕的位图、定义可用颜色的调色板、用于裁剪和其他操作的区域、用于绘制和画图操作的路径、及用于输出文字的字体,参见表8-1。图像对象所对应的MFC类将在8.3.6中介绍,其中笔和刷在8.3.3和8.3.4

17、中介绍,字体在9.2中介绍。表8-1 图形对象及DC的默认值图形对象关联属性DC默认值笔风格、宽度、颜色实心、单像素、黑色刷风格、颜色、图案、原点实心、白色、单色、(0, 0)位图大小(字节)、尺寸(像素)、颜色格式、压缩方式等无调色板颜色与大小(或颜色数)20种标准系统色区域定位与尺寸窗口矩形路径形状无字体字体名、宽、高、粗细、字符集等system(宋体)、7、16、700(粗体)、GB2312_CHARSET2图形模式图形模式(graphics mode)用于确定颜色如何混合、输出在何处出现、输出如何缩放等,参见表8-2。表8-2 图形模式及DC的默认值图形模式描述DC默认值介绍章节映射定

18、义图形输出如何从逻辑(或世界)空间映射到窗口、屏幕或打印机纸,即坐标体系文本(MM_TEXT),即设备坐标(单位为像素、x向右、y向下)8.4.1绘图对笔、刷、位图和文本操作,定义前景色如何与已存在的窗口或屏幕颜色混合覆盖(R2_COPYPEN)8.5.2背景对位图和文本操作,定义背景色如何与已存在的窗口或屏幕颜色混合不透明(OPAQUE)8.5.1拉伸定义在位图被压缩(或缩小)时,定义位图颜色如何与已存在的窗口或屏幕颜色混合存黑去白(BLACKONWHITE)9.3.3多边形填充定义刷图案如何用来填充复杂区域的内部交替(ALTERNATE),即按奇偶规则填充8.5.33图形参数除了图形对象和

19、图形模式外,DC中还保存有当前的笔位置(默认值为坐标原点)、背景色(默认为白色)、文本色(默认为黑色)、文本对齐(默认为左顶)、画弧方向(逆时针)等绘图参数。虽然DC是一种结构,但是Windows不允许应有程序的代码直接访问它。程序员必须通过调用各种对应的Set*和Get*函数以及Select*来设置和获取其中的对象、模式和参数。8.2.2 CDC类CDC类是MFC对DC结构及其相关绘图和状态设置函数的C+类封装。CDC是CObject的直接派生类,CDC类自己也有若干派生类,其中包括:窗口客户区DC所对应的CClientDC类、OnPaint和OnDraw消息响应函数的输入参数中使用的CPa

20、intDC类、图元文件对应的CMetaFileDC类和整个窗口所对应的CWindowDC类,参见图8-3。在普通的MFC绘图中,一般直接使用CDC类即可。CDC类中有许多成员函数,可以用来设置各种绘图环境、属性和参数,以及绘制各种图形和图像等,将在后面陆续加以介绍。图8-3 DC类1获得DC在OnDraw函数中应该使用输入参数pDC,在其他函数中则可调用从CWnd类继承的成员函数GetDC来获得当前窗口(如客户区/视图类)DC的指针,该函数的原型为:CDC* GetDC( );注意,每次从OnDraw函数的输入参数或调用GetDC所获得的DC,都是一个全新的临时默认DC,具有默认的绘图环境和设

21、置。它不能用类变量来长期保存,而且原来选入的各种GDI对象全都被作废、原来设置的各种状态也失效,一切都必须从头再来。2释放DC因为Windows限制可用DC的数量,所以DC属于稀缺的公用资源。因此,对每次获得的DC,在使用完成后必须立即释放。从OnDraw函数的输入参数pDC获得的DC,在该函数运行结束后,系统会自动释放。但由GetDC所获得的DC,则必须自己来手工释放,这可以通过调用从CWnd类继承的成员函数ReleaseDC来完成。该函数的原型为:int ReleaseDC( CDC* pDC ); / 成功返回非0例如:void CDrawView:OnLButtonUp(UINT nF

22、lags, CPoint point) CDC* pDC = GetDC(); / 获取DC pDC-SelectObject(&pen); / 选入笔 pDC-Rectangle(&rect); / 绘制矩形ReleaseDC(pDC); / 释放DC CView:OnLButtonUp(nFlags, point);3安全DC句柄可以用CDC类的成员函数GetSafeHdc来获取DC所对应窗口(如客户区)的安全DC句柄,该函数的原型为:HDC GetSafeHdc();与用GetDC函数所得到的临时DC不同,该安全DC句柄在窗口的存在期间内一直是有效的。例如,可先定义类变量HDC m_hD

23、C;,再在适当的地方给它赋值m_hDC = GetDC()-GetSafeHdc();,然后就可以放心地使用了。还可以使用CDC类的成员函数Attach来将一空CDC对象与此安全DC句柄连接在一起,该函数的原型为:BOOL Attach(HDC hDC); / 成功返回非04屏幕DC可以以NULL为输入参数,调用全局的API函数GetDC:HDC GetDC(HWND hWnd);来可获取屏幕DC的句柄。例如: HDC hdc = :GetDC(NULL); / 获取屏幕DC的句柄 Ellipse(hdc, 0, 0, 150, 100); / 用API函数在屏幕左上角画一椭圆也可以利用CDC

24、类的成员函数Attach,将屏幕DC的句柄选入自定义的CDC类中,来 构造屏幕CDC类的对象。例如: HDC hdc = :GetDC(NULL); / 获取屏幕DC的句柄 CDC sDC; / 定义屏幕DC(空)对象 sDC.Attach(hdc); / 粘上屏幕DC句柄 sDC.Ellipse(0, 0, 150, 100); / 在屏幕左上角画一椭圆8.3 绘图颜色与工具在Windows API中用4个字节的双字来定义颜色类型COLORREF,有红(Red)绿(Green)蓝(Blue)三个字节分量,可用RGB宏来为颜色赋值。在GDI中有画线状图的笔(pen)、画填充图的刷(brush)

25、、画文字的字体(font)等绘图工具。而GDI中使用的颜色种类则有4种之多,它们分别是像素所对应的点色、笔所对应的线色、刷所对应面色、文字所对应的文本色。其中的像素和文本色,可以通过调用对应的专门函数来设置和获取。而笔和刷的颜色,则必须先利用颜色参数创建笔和刷对象,然后调用通用的选择对象函数SelectObject将笔、刷等绘图工具选入DC,再利用DC来绘制各种颜色的图形。8.3.1颜色Windows中的颜色一般用4个字节表示(0BGR(整数序)或RGB0(字节序),因为Intel CPU的低位字节在前),Win32 API中定义了一个专门表示颜色索引值的变量类型COLORREF(windef

26、.h):typedef DWORD COLORREF; / 0x00bbggrr和一个由红绿蓝三原色构造颜色值的宏RGB(wingdi.h):#defineRGB(r,g,b)(COLORREF)(BYTE)(r)|(WORD)(BYTE)(g)8)|(DWORD)(BYTE)(b)SetPixel(10, 10, RGB(0, 255, 0); 另外,还可以用CDC的成员函数COLORREF GetPixel( int x, int y ) const;COLORREF GetPixel( POINT point ) const;来获得指定点(x, y)或point的颜色。例如: COLOR

27、REF col; col = pDC-GetPixel(10, 10);8.3.3线色(笔)在Windows中,线状图必须用笔(pen)来画,所以线的颜色就由笔色来确定。在MFC中,笔的属性和功能由CPen类提供(CPen是CGDIObject的派生类)。笔的创建与使用的步骤为:1创建笔对象创建CPen类笔对象的方法有如下两种: 使用非默认构造函数创建初始笔:CPen( int nPenStyle, int nWidth, COLORREF crColor );其中: nPenStyle为笔的风格,可取值见表8-3。表8-3笔风格nPenStyle值符号常量数值风格名称线例PS_SOLID0实

28、心PS_DASH1虚线PS_DOT2点线PS_DASHDOT3虚点线PS_DASHDOTDOT4虚点点线PS_NULL5空笔PS_INSIDEFRAME6框内注意:14号笔风格只是在笔宽=0或1时有效,笔宽1时总为实心的。 nWidth为笔宽,与映射模式有关,使用默认映射时为像素数,若nWidth = 0,则不论什么映射模式,笔宽都为一个像素。 crColor为笔的颜色值。默认的笔为单像素宽的黑色实心笔。例如:CPen* pGrayPen = new CPen(PS_SOLID, 0, RGB(128, 128, 128);CPen grayPen(PS_SOLID, 0, RGB(128, 128, 128); 使用成员函数CreatePen(多次)创建笔:BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor );可先用CPen类的默认构造函数创建一个空笔对象,然后再调用CreatePen创建具有新内容的笔,例如:CPen grayPen;grayPen.CreatePen(PS_SOLID, 0, RGB(128, 128, 128);不过在用CreatePen创建新笔之前,必须先调用Delete

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2