




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第17章
在窗口中绘图
本章将介绍Windows下的图形编程。Windows中负责图形输出的是GraphicsDeviceInterface(图形设置接口),或称GDI。GDI为应用程序提供了可供调用的多种服务,这些服务一起构成了一种强大、通用的图形编程语言。GDI+是GDI的升级版本,它是.NETFramework中的绘图技术,使用它进行绘图操作要比GDI简单的多。MFC设备描述表绘图模式映射模式坐标使用GDI对象绘图使用不同的字体绘制文本使用鼠标绘图GDI+中的绘图类GDI+图形处理
17.1WindowsGDI
在Windows环境下,所有的输出都是图形,而不管它是直线、矩形还是文件。Windows使用GDI(图形设备接口)绘制用户界面元素,如窗口、菜单和对话框,基至鼠标也是通过GDI绘制的。GDI支持与是显示硬件无关的图形输出,这就意味着程序中使用GDI输出的图形和文本可以在不同的显示设备中正常显示。
17.1.1MFC设备描述表类
当Windows程序在图形输出设备上进行绘图操作时,它并不是将像素直接输出到设备上,而是将图形绘制到由设备描述表(DC)表示的逻辑意义的“平面”。设备描述表是Windows定义的一种数据结构,它包含的信息允许Windows将输出请求转换成特定物理设备的输出动作。在MFC应用程序中,CDC类将Windows设备描述表和相关的GDI函数封装在一起,组成了设备描述表类。而CDC的派生类如CPaintDC和CClientDC则代表Windows应用程序使用的不同类型的设备描述表。
17.1.2设备描述表的属性
当使用CDC输出函数在屏幕上绘图时,输出的某些特性需要通过设备描述表进行设置。例如,在调用CDC::DrawText()绘制文本时,可以指定输出文本的颜色和字体。表17-2列出了一些设备描述表中最常用的属性和访问这些属性的CDC函数。
17.1.3绘图模式
GDI在进行输出时,并不是直接将像素点输出。相反,它是通过一系列的布尔运算将输出像素点的颜色和输出目标位置上像素点的颜色合成在一起。它所使用的布尔运算由设备描述表当前的绘图模式确定。使用CDC::SetROP2()函数可以更改绘图模式。默认的绘图模式为R2_COPYPEN,它将像素点复制到显示平面上。表17-3列出了几种可选的绘图模式,所有这些绘图模式代表了由AND、OR、XOR和NOT构成的运算。17.1.4映射模式
映射模式作为设备描述表的属性,用于确定从逻辑坐标值到设备坐标值的转换方式。调用CDC输出函数的坐标是逻辑坐标值,而设备坐标值是指窗口中相应的像素点位置。例如:dc.Rectangle(0,0,200,100);这里设置的矩形宽为200个逻辑单位,高为100个逻辑单位;而不是200个像素点高,100个像素点宽的矩形。在默认映射模式MM_TEXT下,一个逻辑单位等于一个像素点。但在其他映射模式中,逻辑单位被解释为不同的设备单位。
17.1.5移动坐标原点
在所有的映射模式下,设备描述表的原点都是左上角,这与数学中经常使用坐标系不相同。然而,如果改变映射模式一样,也可以移动坐标原点。MFC的CDC类提供了两个可移动坐标原点的函数:CDC::SetWindowOrg()和CDC::SetViewportOrg()。
17.1.6获取设备信息CDC::GetDeviceCaps()函数可以检索设备的各种信息,从设备支持的颜色数目到水平和坚直方向上显示的像素点数。表17-5列出了一些参数,将这些参数传递给GetDeviceCaps()函数将获得与设备描述表有关的信息。
17.2用GDI绘图
了解GDI的基础知识后,接下来就可以调用GDI函数在窗口中绘制图形。在使用MFC应用程序向导生成的程序中包含了一个派生于CView类的视图类,该类就是专门用于在屏幕上显示文档数据。
17.2.1应用程序中的视图类
MFC应用程序向导生成的类主要负责显示文档中的数据。该类包括了几个重写后的虚函数,其中有一个OnDraw()函数特别重要。每当需要重新绘制视图时,都将调用这个函数。当程序接收到WM_PAINT消息时,就会调用该函数。
17.2.2绘制直线和曲线
MFC的CDC类中包含了许多可用来画直线和曲线的成员函数。表17-6列出了几个主要的函数。
17.2.3绘制椭圆和矩形
GDI不仅仅可以绘制简单的直线和曲线,还允许绘制椭圆、矩形和饼形等封闭图形。MFC的CDC类将相关的GDI函数封装为类的成员函数。表17-7列出其中几个常用的成员函数。
17.2.4画笔
到目前为止,绘制图形在屏幕中都是黑色的,宽度为一个像素点。如果要改变这种情况,需要创建一个GDI画笔,并由CDC::SelectObject()将它设为设备描述表所使用的画笔。MFC使用类CPen表示GDI画笔。创建画笔的最简单方法是创建一个CPen对象,并使用适当的属性初始化该对象:CPenpen(PS_SOLID,1,RGB(255,0,0));第二种方法是先构造一个未初始化的CPen对象,然后调用CPen::CreatePen()初始化画笔对象:CPenpen;pen.CreatePen(PS_SOLID,1,RGB(255,0,0));如果画笔创建成功,则CreatePen()返回TRUE,反之则返回FALSE。定义画笔需要三个特性:样式、宽度和颜色。
17.2.5画刷
在默认情况下,使用Ellipse()、Rectangle()函数以及其他输出函数绘制封闭图形时,图形的内部将填充白色。通过创建GDI画刷,并将之选入设备描述表中可以改变图形的填充颜色。MFC的CBrush类封装了Windows画刷。画刷有三种基本类型:单色、带阴影线和图案画刷。只要将COLORREF的值传递给CBrush的构造函数,就可以创建一个单色画刷。
17.2.6绘制文本
在输出文字时,MFC的CDC类成员提供了一系列的函数,最常用的函数包括:CDC::TextOut()和CDC::DrawText()两个函数,其他的文本函数见表17-10所示。
17.2.7字体
在输出文本时,所有的CDC文本输出函数都使用当前设备描述表中的默认字体。字体是文字显示和打印的外观形式,它包括了文字的字样、风格和尺寸等方面的属性。字样是字符书写和显示时表现出的特定模式。绝大部分GDI字体可分为两类:点阵字体和TrueType字体。与画笔或画刷一样,字体也是一个GDI对象。在MFC中,字体由CFont类表示。创建字体由两步完成:首先创建CFont类对象,然后调用CFont类的创建字体函数CreateFont()、CreateFontIndirect()、CreatePointFont或CreatePointFontIndirect()创建GUI字体。
17.2.9预定义对象
Windows预定义了一些画笔、画刷、字体以及其他一些GDI对象,它们在使有时不需要再显式地创建,直接调用CDC::SelectStockObject()函数将这些预定义对象选入设备描述表即可。表17-13列出了一些可用的预定义对象。
17.3使用鼠标绘图
1.
直线绘制过程
在绘制一条直线时,用户通过按下鼠标左键确定直线的起始位置,然后按住左键移动鼠标来定义直线的终点。在按住鼠标左键移动时,希望能够连续绘制直线,以便让用户确认当前绘制的直线。17.3.1绘制图形分析
2.绘制圆按下鼠标左键的位置被定义为圆心,当按住鼠标左键移动时,图将被连续重新绘制,在释放鼠标左键时圆将定型。
2.绘制矩形按下鼠标左键的位置为矩形的左上角位置,释放鼠标左键的位置为最终矩形的右下角。在按住鼠标左键移动的过程中,将不断更新矩形。
17.3.2创建绘图类
在Drawing应用程序中,用户可以使用鼠标随意绘制直线、圆、矩形和曲线,因此我们可以使用四个类:CLine、CRectangle、CCirle和CCurve分别实现绘制相应的图形。这四个类彼此之间有一些相同的特性,如颜色、画笔宽度等,为了方便使用,我们为这四个类创建一个共同的基类CShape类。另外,我们需要以某种方式在一个文档中保存绘制的图形,以便随后使用。在MFC中,CObject类提供串行化的功能,这也就意味着如果从CObject派生自己的类,则可以使用CObject类提供的串行化功能。
17.3.3完成基类CShape
在基类CShape中包含所有类都通用的一些特性,如颜色、画笔宽度等,以便可以在每个派生类中继承它们。另外,在基类中还应包含一些所有派生类中必须具有的函数,如绘图方法,所有的派生类都应该包含绘图方法,但它们的绘图方法则是完全不相同的,因此该方法就应该在基类中以虚函数的方法实现。
17.3.4绘制直线
直线的绘制是由CLine类来实现。对于直线而言,它需要两个数据:直线的起点和直线的终点。
17.3.5完成其他派生类
在完成绘制直线的CLine类后,CRectangle和CCircle类与此类似。1.绘制矩形在绘制矩形时需要知道矩形的左上角和右下角坐标,根据这两点可以构造一个表示矩形的CRect类类型的对象。2.绘制圆在绘制圆时,按下鼠标左键的位置将是圆的圆心,移动鼠标指针后,释放鼠标左键的位置将为最终圆的圆周上一点。因此,在构造函数中需要根据圆心和圆的半径计算出圆的外接矩形。3.绘制曲线CCure类与其他类不同,为了绘制曲线,它必须接收一系列的点。这就需要一个集合类来保存和管理这些点。也就是说,需要在CCurve类中添加一个vector<CPoint>容器类数据成员,以存储构成曲线的点。
17.3.6创建绘图类对象
在定义各种绘图类后,接下来就需创建各绘图类对象,调用其成员函数完成绘图功能。在Drawing程序中,当用户通过相应的菜单项选择希望绘制的图形,然后再使用鼠标进行绘图,因此,首先需要为程序添加绘图和颜色菜单项。绘图和颜色菜单项的各属性设置如表17-14所示。
17.4.使用GDI+绘图
GDI是使用C++类对Windows绘图函数的包装,而GDI+则对GDI进行了包装,并对它进行了改进,使GDI+更容易使用。例如,在使用GDI绘图时,必须要指定一个设备环境DC,所有的绘图操作都与该句柄有关。而GDI+不再使用这个设备环境或句柄,取而代之是使用Graphics对象。Pen、Brush,Font,Image等对象是图形对象独立的,Graphics绘图方法直接将Pen对象作为自己的参数,从而避免了在GDI使用SelectObject进行繁琐的切换,类似的还有Brush、Path、Image和Font等。
17.4.1了解GDI+
尽管GDI+基本上是GDI的一个包装器,但Microsoft已经能通过GDI+提供新功能了,并对它有一些性能方面的改进。GDI+封装在一组托管代码中,这些类被称为GDI+的托管类接口,GDI+基类的命名空间信息如下:System::Drawing包含与基本绘图功能有关的大多数类、结构、枚举和委托。System::Drawing::Drawing2D为大多数高级2D和矢量绘图操作提供了支持,例如,消除锯齿、几何转换和图形路径等。System::Drawing::Imaging帮助处理图像(位图、GIF文件等)的各种类。System::Drawing::Printing把打印机或打印预览窗口作为输出设备时使用的类。System::Drawing::Design一些预定义的对话框、属性表和其他用户界面元素,与在设计期间扩展用户界面相关。System::Drawing::Text对字体和字体系列执行更高级的操作的类。命名空间System::Drawing中的Graphics类是GDI+的核心,Graphics类提供将对象绘制到显示设备的方法。Graphics可以与特定设备的上下文相关联,是用于创建图形的对象。它封装了绘制直线、曲线、图形、图像和文本的方法,是GDI+实现绘制直线、曲线、图形、图像和文本的类,是GDI+操作的基础类。
17.4.2图形操作
GDI+定义了一系列与绘图操作相关的绘图类,通过这些绘图类可以和Graphics对象一起实现绘图处理,GDI+内的主要绘图类如下。1.Color结构Color结构表示ARGB颜色,使用Alpha、Red、Green、和Blue的值来表示颜色。Color结构以属性的方式定义了大量的有名称的颜色。2.Pen类Pen类用于绘制直线或曲线,它通过本身的属性绘制具有指定宽度和样式的直线。可以使用DashStyle属性绘制虚线,DashStyle属性是DashStyle枚举类型。3.Brush类Brush类定义用于填充图形形状内部的对象,Brush类是一个抽象基类,不能进行实例化处理。如果需要创建一个画刷对象,应使用派生于Brush的类。
17.4.3坐标和区域
在进行绘图操作时,经常需要使有Point、Rectangle和Size等结构来确定绘制的位置和区域等信息,这几个类都是在System::Drawing命名空间中定义。
1.Point和PointF从概念上讲,Point在这些结构中是最简单的,在数学上,它完全等价于一个二维矢量。它包含两个整数类型的属性,分别特定位置的水平和垂直距离。2.Size和SizeF与Point和PointF一样,Size也有两个变体:Size和SizeF,Size结构用于int类型而SizeF结构用于float类型。3.Rectangle和RectangleFRectangle和RectangleF表示屏幕上的一个矩形区域,两者的具体用法基本类似。RectangleF与Rectangle基本相同,只是RectangleF的属性类型是float,而Rectangle的属性类型是int。
17.4.4使用Font类绘制文本
Font类封装了字体的3个主要特性:字体系列、字体大小和字体样式。Font类在System::Drawing命名空间中。Font类的Style属性设置了字体的样式信息,其值是由FontSty
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论