12GDI+基础编程 - 图文(2)

2020-02-20 17:49

3.持久路径对象

GDI中的路径(path)属于设备上下文,并且会在绘制时被毁坏。而GDI+则可以创建并维护多个与Graphics对象分开的持久(persistent)图形路径GraphicsPath对象,在绘图操作时也不会破坏,因此可多次使用同一个GraphicsPath对象来绘制路径。

4.变换和矩阵对象

GDI+提供了Matrix(矩阵)对象,它是一种可以使(缩放、旋转和平移等)变换(transformation)简易灵活的强大工具,矩阵对象一般与变换对象联合使用。例如,GraphicsPath对象具有Transform方法,此方法接收Matrix对象作为参数。参见图12-6和7。

5.可伸缩区域

GDI+通过对可伸缩区域(scalable region)的支持极大地扩展了GDI。在GDI中,区域被存储在设备坐标中,而且,可应用于区域的惟一变换是平移。而GDI+在全局坐标中存储区域,并且允许区域发生任何可存储在变换矩阵中的变换(如缩放和旋转)。图12-7显示一个区域在执行三种变换(缩放、旋转和平移)前后的情况。

图12-6 路径变换 图12-7 区域变换 图12-8 不同透明度

6.α混色

在图12-7中,可以在变换区域(用蓝色阴影画笔填充)中看到未变换区域(用红色填充),这是由GDI+支持的α混色(alpha blending,透明混合)实现的。使用α混色,可以指定填充颜色的透明度。透明色与背景色相混合———填充色越透明,透出的背景色就越多。图12-8显示四个用相同颜色(红色)填充、但透明层次不同的椭圆。

6

7.丰富的图像格式支持

GDI+提供Image、Bitmap和Metafile类,可以用不同的格式加载、保存和操作图像。GDI+支持BMP、GIF、JPEG、EXIF、PNG、TIFF、ICON、WMF、EMF共9种常见的图像格式。其中的部分功能已被ATL/MFC中基于GDI+的CImage类所体现(参见9.3.4)。

8.GDI+的不足

虽然,相对于GDI来说,GDI+确实增加了许多新特性,而且功能更强大,使用也更方便。但是,这并不等于GDI+就能够完全代替GDI。因为GDI+实际上是GDI的高层封装和功能扩展,GDI+的执行效率一般要低于GDI的。

另外,GDI+不支持图形的位运算,那么就不能进行异或绘图等操作。而且在Visual C++中,GDI+还不直接支持双缓存机制(如内存DC和显示DC),这将大大影响GDI+在高速图形、图像、动画和视频等方面的应用。

12.2.2 编程模式的改变

GDI+的出现,也使基于GDI的传统编程模式产生了很大变化:GDI+用一个“无状态模式”,取代了GDI中(需要先将各种工具和项目选入DC对象后,才能进行绘图的)“状态模式”。主要体现在以下几个方面:

1.DC句柄和图形对象

设备上下文(DC)是GDI中使用的一种结构,用于存储与特定显示设备相关的的绘制工具及属性的信息,用于屏幕显示的DC还与特定窗口相关联。为了使用GDI API进行绘图,必须首先获得一个DC的句柄(HDC),然后将该句柄作为参数,传递给实际进行绘图的GDI函数。在MFC中,DC及其绘图功能被封装在CDC类中,DC句柄成为了成员变量,绘图函数变成了成员函数,不再需要显式传递HDC参数。

使用GDI+,不需再(直接)使用句柄或设备上下文,而是只需(通过HDC)创建一个Graphics对象,然后用熟悉的面向对象方式来调用其中的各种绘图方法,例如:

Graphics graph(GetDC()->m_hdc); graph.DrawLine(&pen, x1, y1, x2, y2);

7

正如DC是GDI的核心,Graphics对象也是GDI+的核心。DC和Graphics对象的作用相似,但在使用DC的基于句柄的GDI编程模式和使用Graphics对象的面向对象的GDI+编程模型之间,存在一些基本的差异。

Graphics对象(像DC一样)与屏幕上的特定窗口关联,并具有指定如何绘制项目的属性(如SmoothingMode和TextRenderingHint)。但是,Graphics对象不受笔、刷、路径、图像或字体的约束,这与设备上下文不同。例如,使用设备上下文绘制线条之前,必须先调用SelectObject将笔选入DC中,以使笔对象和DC关联。在设备上下文中绘制的所有线条均使用该笔,直到选择另一支不同的笔为止。在GDI+中,将Pen对象作为参数传递给Graphics类的DrawLine等画线方法。可以在一系列的DrawLine调用的每个调用中,使用不同的Pen对象,而不必将给定的Pen对象与Graphics对象关联。

2.画线的两种方法

下面的两个示例都从点(20, 10)到点(200, 100)绘制一条宽为3的红色线条。第一个示例用GDI,第二个示例则用GDI+,这里都使用MFC。也可以不使用MFC,而直接用API来进行GDI+绘图(由于篇幅有限,这里就不介绍了)。

1)用GDI画线

利用MFC进行GDI绘图的步骤为:

CDC *pDC = GetDC(); // 获取DC对象

CPen pen(PS_SOLID, 3, RGB(255, 0, 0)); // 创建笔 pDC->SelectObject(&pen); // 选笔入DC

pDC->MoveTo(20, 10); // 将当前点移到直线的起点 pDC->LineTo(200, 100); // 从当前点画线到直线的终点

2)用GDI+画线

利用MFC进行GDI+绘图的步骤为:

CDC *pDC = GetDC(); // 获取DC对象

Graphics myGraphics(pDC->m_hDC); // 利用DC句柄创建图形对象 Pen myPen(Color(255, 0 , 0), 3); // 创建笔

myGraphics.DrawLine(&myPen, 20, 10, 200, 100); // 画直线

8

3.作为参数的绘图工具

上面的示例显示:在GDI+中,创建和维护Pen对象,可以与提供绘制方法的Graphics对象分开。同样,创建和维护Brush、GraphicsPath、Image和Font等对象也可以与Graphics对象分开。

Graphics类提供的许多绘制方法,都将笔、刷、路径、图像和字体等对象,作为参数接收。例如,Brush对象作为参数传递至FillRectangle方法,GraphicPath对象作为参数传递至DrawPath方法。同样,Image和Font对象传递至DrawImage和DrawString方法。

这与GDI不同。在GDI中,需要先将笔、刷、路径、图像或字体等GDI工具对象选入DC,然后再利用CDC类的成员函数使用DC中当前的笔、刷、路径、图像或字体来绘图。

4.无当前位置

GDI+从总体上已经放弃了当前位置的概念,如在前面所述的DrawLine方法中线段的起点和终点均被作为参数接收。这与GDI的方案不同,在GDI中,调用MoveTo(x1, y1)来设置当前笔位置之后,再调用LineTo(x2, y2)来绘制一条从(x1, y1)到(x2 , y2)的直线段。

5.绘制和填充的不同方法

GDI的Rectangle和Ellipse等函数,可一步完成绘制轮廓和填充内部的功能。轮廓由当前选定的笔绘制,而内部则由当前选定的刷来填充。GDI+则必须分别调用绘制轮廓和填充内部的两个不同方法来做到这一点。例如,Graphics类的DrawRectangle方法将Pen对象作为其参数之一,而FillRectangle方法将Brush对象作为其参数之一。所以在绘制轮廓和填充图形内部时,GDI+要比GDI更灵活,但也更麻烦。

6.构造区域

GDI提供了几种用于创建区域的函数(在MFC中,它们被封装在区域类CRng里):CreateRectRgn、CreateEllpticRgn、CreateRoundRectRgn、CreatePolygonRgn

CreatePolyPolygonRgn。你或许希望GDI+中的Region类也有类似的构造函数,将矩形、椭圆、圆角矩形和多边形作为参数接收,但事实并非如此。GDI+中的区域类Region提供了一个接收Rectangle对象的构造函数和另一个接收GraphicsPath对象的构造函数。如果想基于

9

椭圆、圆角矩形或多边形来构造区域,可以通过先创建一个GraphicsPath对象(可包含椭圆等各种图形对象),然后再将其传递至Region构造函数来实现。

GDI+通过组合图形和路径,使得构成复杂区域变得十分简单。Region类具有Union(并)和Intersect(交)方法,可用于扩展具有路径的现有区域或其它区域。GDI+方案一个很好的功能就是GraphicsPath对象在作为参数传递至Region构造函数时不会被破坏(在GDI中,虽然可以使用PathToRegion方法将路径转换为区域,但在此过程中,路径将被破坏)。另外,GraphicsPath对象在作为参数传递给Union或Intersect方法时也不会被破坏,因此,在一些单独的区域中,可以将给定的路径作为构造块来使用。例如:

Region region1(rect1), region2(rect2); region1.Union(onePath); region2.Intersect(onePath);

12.3 GDI+的MFC编程

本节介绍利用MFC进行GDI+编程的必要的准备,并通过例子说明GDI+编程的具体步骤,最后给出如何解决现存的new操作符问题的具体方法。

C++封装的GDI+的(英文)帮助内容,位于“Dev Center - Desktop > Docs > Windows Development Reference > Graphics and Gaming > Legacy Graphics > GDI+”中,主要的参考资料位于其子目录“GDI+ Reference”中。

12.3.1 设置与初始化

封装了GDI+ API的各种C++类、函数、常量、枚举和结构,都被定义在Gdiplus.h头文件所包含的一系列头文件中。而GDI+并不是MFC的标准组成部分,所以,在采用MFC进行GDI+编程时,必须自己手工包含Gdiplus.h头文件。

从12.1.1的有关GDI+平面API的讨论可知,封装在GDI+类中的方法,最后都需要调用GDI+平面API中的相关底层函数,才能完成实际的操作。所以,为了运行GDI+应用程序,在操作系统平台中,必须安装动态链接库Gdiplus.dll(不过,对Windows XP及以上版本,该DLL已经被操作系统自动包含)。

该动态链接库所对应的静态库文件为GdiPlus.lib,而且它在VC08及之前的早期版本中不是C++和MFC的默认链接库。所以,对早期的VC版本必须在项目设置中,添加该库作

10


12GDI+基础编程 - 图文(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:公积金养老保险等问题

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: