标 题: 一些关于GDI+的文字——编程模式的变化 发信站: 浙江大学海纳百川站 (Tue Oct 26 11:54:19 2004), 转信 设备上下文、句柄和图形对象 如果您使用过 GDI(Windows 的以前版本中包括的图形设备接口)编写程序,就会熟悉 设备上下文的知识。设备上下文是 Windows 使用的一种结构,用于存储与特殊显示设备 的功能和指定如何在该设备上绘制项目的属性相关的信息。用于视频显示的设备上下文 还与显示的特定窗口关联。首先,您获得一个设备上下文的句柄 (HDC),然后将该句柄 作为参数传递至实际进行绘制的 GDI 函数。您还可将此句柄作为参数传递给获取或设置 设备上下文属性的 GDI 函数。 使用 GDI+,您不需要再使用句柄或设备上下文,而是只需创建一个 Graphics 对象,然 后在您熟悉的面向对象样式 myGraphicsObject.DrawLine(参数)中调用其方法。正如 设备上下文位于 GDI 的核心,Graphics 对象也位于 GDI+ 的核心。设备上下文和 Gra phics 对象的作用相似,但在使用设备上下文 (GDI) 的、基于句柄的编程模式和使用G raphics 对象 (GDI+) 的、面向对象的编程模型之间存在一些基本的差异。 Graphics 对象(像设备上下文一样)与屏幕上的特定窗口关联,并具有指定如何绘制项 目的属性(例如,SmoothingMode 和 TextRenderingHint)。但是,Graphics 对象不受 钢笔、画笔、路径、图像或字体的约束,这与设备上下文不同。例如,使用设备上下文 绘制线条之前,必须先调用 SelectObject 以使钢笔对象和设备上下文关联。这是指将 钢笔选入设备上下文中。在设备上下文中绘制的所有线条均使用该钢笔,直到您选择另 一支不同的钢笔为止。在 GDI+ 中,将 Pen 对象作为参数传递给 Graphics 类的 Draw Line 方法。您可以在一系列 DrawLine 调用的每个调用中使用不同的 Pen 对象,而不 必使给定的 Pen 对象与 Graphics 对象关联。 绘制线条的两种方法 下面每个示例都在位置 (20, 10) 和位置 (200, 100) 之间绘制了一条宽为 3 的红色线 条。第一个示例调用 GDI,第二个示例通过托管类接口调用 GDI+。 使用 GDI 绘制线条 要使用 GDI 绘制线条,需要两个对象:设备上下文和钢笔。先获得设备上下文句柄;通 过调用CreatePen,则可以获得 直示浔O乱 步,调用 SelectObject 以将钢笔选入设 备上下文。调用MoveToEx,将钢笔位置设在 (20, 10),然后调用 LineTo,在钢笔位置 与位置 (200, 100) 之间绘制一条线条。请注意,MoveToEx 和 LineTo 均将 hdc(设备 上下文的句柄)作为参数接收。 使用 GDI+ 和托管类接口绘制线条 下面的示例是用 C++ 编写的,但用任何能产生托管代码的语言都可以编写这些示例。要 使用 GDI+ 和托管类接口绘制线条,您需要 Graphics 对象和 Pen 对象。获取 Graphi cs 对象引用的一种方法是通过窗体的 OnPaint 方法。OnPaint 方法的一个参数是类型 PaintEventArgs 的结构,它将 Graphics 对象作为其成员。 绘制线条涉及调用 Graphics 类的 DrawLine 方法。DrawLine 方法的第一个参数是 Pe n 对象。与前面 GDI 示例中显示的技术(将钢笔选入设备上下文)相比,这是一个更加 简单而灵活的方案。 Pen* myPen = new Pen(Color(255, 0xff, 0, 0), 3); Graphics myGraphics(hDC); myGraphics.DrawLine(myPen, 20, 10, 200, 100); 作为参数的钢笔、画笔、路径、图像和字体 前面的示例显示:创建和维护 Pen 对象可以与提供绘制方法的 Graphics 对象分开。创 建和维护 Brush、GraphicsPath、Image 和 Font 对象也可以与 Graphics 对象分开。 Graphics 类提供的许多绘制方法都将 Brush、GraphicsPath、Image 或 Font 对象作为 参数接收。例如,Brush 对象作为参数传递至 FillRectangle 方法,GraphicPath 对象 作为参数传递至 DrawPath 方法。同样,Image 和 Font 对象传递至 DrawImage 和 Dr awString 方法。这与 GDI 不同,在 GDI 中,需要将画笔、路径、图像或字体选入设备 上下文,然后将设备上下文的句柄作为参数传递至绘制函数。 无当前位置 请注意,前面所述的 DrawLine 方法中显示:线条的起点和终点均被作为参数接收。这 与 GDI 方案不同,在 GDI 中,调用 MoveToEx(hdc, x1, y1, NULL) 来设置当前钢笔位 置之后,再调用 LineTo(hdc, x2, y2) 以绘制一条从 (x1, y1) 到 (x2, y2) 的线条。 GDI+ 从总体上已经放弃了当前位置的概念。 绘制和填充的不同方法 论及绘制轮廓和填充图形内部时,GDI+ 要比 GDI 更灵活。GDI 有一个 Rectangle 函数 ,可一步完成绘制轮廓和填充矩形内部。轮廓由当前选定的 直 绘制,而内部则由当前 选定的画笔来填充。 hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 0, 255)); hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); SelectObject(hdc, hBrush); SelectObject(hdc, hPen); Rectangle(hdc, 100, 50, 200, 80); GDI+ 使用不同的方法来绘制轮廓和填充矩形内部。Graphics 类的 DrawRectangle 方法 将 Pen 对象作为其参数之一,而 FillRectangle 方法将 Brush 对象作为其参数之一。 HatchBrush* myHatchBrush = new HatchBrush( HatchStyleHorizontal, Color(255, 0, 255, 0), Color(255, 0, 0, 255)); Pen* myPen = new Pen(Color.FromArgb(255, 255, 0, 0), 3); myGraphics.FillRectangle(myHatchBrush, 100, 50, 100, 30); myGraphics.DrawRectangle(myPen, 100, 50, 100, 30); 请注意,GDI+ 中的 FillRectangle 和 DrawRectangle 方法接收指定矩形左边缘、上边 缘、宽和高的参数。这与 GDI 的 Rectangle 函数不同,Rectangle 函数接收指定矩形 左边缘、右边缘、上边缘和下边缘的参数。另请注意,GDI+ 中 Color 类的 FromArgb 方法有四个参数。后三个参数是常见的红色、绿色和蓝色值。第一个参数是 alpha 值, 它指定所绘制颜色与背景颜色的混合程度。 构造区域 GDI 提供几种用于创建区域的函数:CreateRectRgn、CreateEllpticRgn、CreateRound RectRgn、CreatePolygonRgn 和 CreatePolyPolygonRgn。您或许希望 GDI+ 中的 Regi on 类也有类似的构造函数,将矩形、椭圆、圆角矩形和多边形作为参数接收,但事实并 非如此。GDI+ 中的 Region 类提供一个接收 Rectangle 对象的构造函数和另一个接收 GraphicsPath 对象的构造函数。如果您想基于椭圆、圆角矩形或多边形构造区域,可 以通过创建一个 GraphicsPath 对象(例如包含椭圆的对象),然后将其传递至 Regio n 构造函数来轻松实现。 GDI+ 通过组合图形和路径,使得构成复杂区域十分简单。Region 类具有 Union 和 In tersect 方法,可用于扩展具有路径的现有区域或其他区域。GDI+ 方案一个很好的功能 就是 GraphicsPath 对象在作为参数传递至 Region 构造函数时不会被破坏(在 GDI 中 ,可以使用 PathToRegion 函数将路径转换为区域,但在此过程中,路径将被破坏)。 另外,GraphicsPath 对象在作为参数传递给 Union 或 Intersect 方法时也不会被破坏 ,因此,在一些单独的区域中,您可以将给定的路径作为构造块使用。该过程如下例所 示。假定 onePath 是一个已初始化的 GraphicsPath 对象(简单或复杂)。 Region* region1 = new Region(rect1); Region* region2 = new Region(rect2); region1->Union(onePath); region2->Intersect(onePath); -- ■■■■■■■■■■■■■■■■■■■■■■■■ 这个世界只有10种人,懂二进制的和不懂二进制的 ■■■■■■■■■■■■■■■■■■■■■■■■ jackyang@cs.zju since 2001 ※ 来源:·浙江大学海纳百川站 bbs.zju.edu.cn·[FROM: jackyang] |
|
来自: shaolong007 > 《一些关于GDI 的文字》