Chapter 5 Basic Drawing 第五章 绘图基础 — The Structure of GDI - GDI结构

类别:编程语言 点击:0 评论:0 推荐:
ps:您可以转载,但请注明出处;你可以修改,但请将修改结果告诉我。

The Structure of GDI
GDI 结构
From the programmer's perspective, GDI consists of several hundred function calls and some associated data types, macros, and structures. But before we begin looking at some of these functions in detail, let's step back and get a feel for the overall structure of GDI. 从程序员的观点来看,GDI 由几百个函数调用和一些相关联的数据类型,宏和结构组成。但是在我们开始详细地看这些函数中的某些之前,让我们先退一步并对 GDI 的整个结构有一个了解。   The GDI Philosophy GDI 体系
Graphics in Windows 98 and Microsoft Windows NT is handled primarily by functions exported from the dynamic-link library GDI32.DLL. In Windows 98, this GDI32.DLL makes use of the 16-bit GDI.EXE dynamic-link library for the actual implementation of many of the functions. In Windows NT, GDI.EXE is used only for 16-bit programs. 在 Windows 98 和微软 Windows NT 中的图形最初由动态连接库 GDI32.DLL 输出的函数处理。在 Windows 98 中,这个 GDI32.DLL 利用 16 位 GDI.EXE 动态连接库作为许多函数实际的实现。在 Windows NT 中,GDI.EXE 只用于 16 位程序。   These dynamic-link libraries call routines in device drivers for the video display and any printers you may have set up. The video driver accesses the hardware of the video display, and the printer driver converts GDI commands into codes or commands that the various printers understand. Obviously, different video display adapters and printers require different device drivers. 这些动态连接库调用设备驱动程序中的程序用于视频显示和你可能已经安装的任何打印机。视频驱动访问视频显示器硬件,而打印机驱动将 GDI 命令转换为各种打印机理解的编码或命令。显然,不同的视频显示卡和打印机需要不同的设备驱动程序。   A wide variety of display devices can be attached to PC compatibles. One of the primary goals of GDI is to support device-independent graphics. Windows programs should be able to run without problems on any graphics output device that Windows supports. GDI accomplishes this goal by providing facilities to insulate your programs from the particular characteristics of different output devices. 大量各种显示设备可以附加到 PC 兼容机上。GDI 最初的目标之一是支持设备无关图形。Windows 程序应该可以毫无问题地运行在 Windows 支持的任何图形输出设备上。GDI 通过提供将你的程序与不同输出设备特殊的特征相隔离的方便性完成这个目标。   The world of graphics output devices is divided into two broad groups: raster devices and vector devices. Most PC output devices are raster devices, which means that they represent images as a rectangular pattern of dots. This category includes video display adapters, dot-matrix printers, and laser printers. Vector devices, which draw images using lines, are generally limited these days to plotters. 图形输出设备世界分成两个主要团体:光栅设备和矢量设备。大多数 PC 输出设备是光栅设备,这意味着它们将图像表现为点的矩形图案。这类包括视频显示卡,点阵式打印机和激光打印机。用线画图的矢量设备目前通常局限于绘图机。   Much of traditional computer graphics programming (the type you'll find in older books) is based solely on vectors. This means that a program using a vector graphics system is a level of abstraction away from the hardware. The output device uses pixels for a graphics representation, but the program doesn't talk to the interface in terms of pixels. While you can certainly use the Windows GDI as a high-level vector drawing system, you can also use it for relatively low-level pixel manipulation. 许多传统的计算机图形程序设计(你将在旧书中发现的类型)单独地基于矢量。这意味着用适量图形系统的程序在一定水平上远离硬件。输出设备将像素用于图形的表现,但是程序不会按照像素告诉界面。当你的确可以将 Windows GDI 用作高层次的矢量绘图系统时,你也可以将它用于相关的低层次的像素操作。   In this respect, Windows GDI is to traditional graphics interface languages what C is to other programming languages. C is well known for its high degree of portability among different operating systems and environments. Yet C is also well known for allowing a programmer to perform low-level system functions that are often impossible in other high-level languages. Just as C is sometimes thought of as a "high-level assembly language," you can think of GDI as a high-level interface to the hardware of the graphics device. 从这个观点来看,Windows GDI 对于传统的图形界面语言就像 C 对于其它程序设计语言。C 以它的在不同的操作系统和环境之间的高度可携性著名。而 C 也已允许程序员执行在其它高级语言中常常不可能执行的低级系统函数而著名。正如 C 有时候被看作是“高级汇编语言”一样,你可以把 GDI 看作是图形设备硬件的高级接口。   As you've seen, by default Windows uses a coordinate system based on pixels. Most traditional graphics languages use a "virtual" coordinate system with horizontal and vertical axes that range (for instance) from 0 to 32,767. Although some graphics languages don't let you use pixel coordinates, Windows GDI lets you use either system (as well as additional coordinate systems based on physical measurements). You can use a virtual coordinate system and keep your program distanced from the hardware, or you can use the device coordinate system and snuggle right up to the hardware. 正如你看到的,缺省情况下 Windows 使用基于像素的坐标系统。大多数传统的图形语言用具有范围(例如)从 0 到 32,767 的水平和垂直轴的“虚”坐标系统。尽管一些图形语言不让你用像素坐标,但是 Windows GDI 让你用任意一个系统(甚至传统的基于物理度量的坐标系统)。你可以用虚坐标系统并且保持你的程序与硬件的距离,或者你可以用设备坐标系统而完全依赖于硬件。   Some programmers think that when you're working in terms of pixels, you've abandoned device independence. We've already seen in the last chapter that this is not necessarily the case. The trick is to use the pixels in a device-independent manner. This requires that the graphics interface language provide facilities for a program to determine the hardware characteristics of the device and make appropriate adjustments. For example, in the SYSMETS programs we used the pixel size of a standard system font character to space text on the screen. This approach allowed the programs to adjust to different display adapters with different resolutions, text sizes, and aspect ratios. You'll see other methods in this chapter for determining display sizes. 一些程序员认为当你按照像素工作时,你已经放弃了设备独立性。在上一章我们已经看到这是不必要的情况。 窍门是以设备独立的方式使用像素。这要求图形界面语言为程序提供确定设备的硬件特征和做适当的矫正的方便性。例如,在 SYSMETS 程序中我们用标准系统字体字符的像素大小分隔屏幕上的文本。这个方法允许程序用不同的分辨率,文本大小和屏幕高宽比调整不同的显示卡。在这章中你将看到其它确定显示器尺寸的方法。   In the early days, many users ran Windows with a monochrome display. Even in more recent years, laptop users were restricted to gray shades. For this reason, GDI was constructed so that you can write a program without worrying much about color—that is, Windows can convert colors to gray shades. Even today, video displays used with Windows 98 have different color capabilities (16 color, 256 color, "high color," and "true color"). Although ink-jet printers have brought low-cost hard-copy color to the masses, many users still prefer their black-only laser printers for high-quality output. It is possible to use these devices blindly, but your program can also determine how many colors are available on the particular display device and take best advantage of the hardware. 在早期,许多用户以单色显示器运行 Windows。即使在近几年前,膝上型电脑用户也还受限于灰白色图案。由于这个原因,GDI 被构建成以便你可以不用更多考虑颜色就编写程序——也就是说,Windows 可以将颜色转换为灰白色图案。即使今天,运行 Windows 98 的视频显示器有不同的颜色能力(16 色,256 色,“高彩色”和“真彩色”)。虽然喷墨打印机已经使得大众有低成本的硬拷贝颜色,但是许多用户仍然更喜欢他们的单一黑色的激光打印机用于高质量的输出。盲目地使用这些设备是可能的,但是你的程序也可以确定多少种颜色在这个特殊显示设备上是可用的并且最好地利用硬件。   Of course, just as you can write C programs that have subtle portability problems when they run on other computers, you can also inadvertently let device dependencies creep into your Windows programs. That's part of the price of not being fully insulated from the hardware. You should also be aware of the limitations of Windows GDI. Although you can certainly move graphics objects around the display, GDI is generally a static display system with only limited animation support. If you need to write sophisticated animations for games, you should explore Microsoft DirectX, which provides the support you'll need. 当然,正如你可以编写当运行于其它计算机上有微妙的可携性问题的 C 程序一样,你也可以不注意地让设备相关性溜进你的 Windows 程序。那是不完全与硬件隔开的价格的一部分。你也应该知道 Windows GDI 的局限性。尽管你的确可以在显示器上移动图形对象,但是 GDI 通常是一个仅有有限的动画支持的静态显示系统。如果你需要为游戏编写复杂的动画,那么你应该探究微软的 DirectX,它提供你将需要的支持。   The GDI Function Calls GDI 函数调用
The several hundred function calls that comprise GDI can be classified in several broad groups: 包含 GDI 的几百个函数调用可以被分类为几个主要的类:  Functions that get (or create) and release (or destroy) a device context As we saw in earlier chapters, you need a handle to a device context in order to draw. The BeginPaint and EndPaint functions (although technically a part of the USER module rather than the GDI module) let you do this during the WM_PAINT message, and GetDC and ReleaseDC functions let you do this during other messages. We'll examine some other functions regarding device contexts shortly.
获得(或创建)和释放(或销毁)关联设备的函数 - 正如我们在前几章看到的,你需要关联设备的句柄以便绘制。BeginPaint 和 EdnPaint 函数(尽管技术上是 USER 模块而非 GDI 模块)让你在 WM_PAINT 消息期间这样做,并且 GetDC 和 ReleaseDC 函数让你在其它消息期间这样做。不久我将考察一些其它关于关联设备的函数。 Functions that obtain information about the device context In the SYSMETS programs in Chapter 4, we used the GetTextMetrics function to obtain information about the dimensions of the font currently selected in the device context. Later in this chapter, we'll look at the DEVCAPS1 program, which obtains other, more general, device context information.
获得关于关联设备信息的函数 - 在第四章中的 SYSMETS 程序中,我们用 GetTextMetrics 函数获得关于当前在关联设备中选中的字体的尺寸的信息。在本章后面,我们将看到 DEVCAPS1 程序,它获得其它更一般的关联设备信息。 Functions that draw something Obviously, once all the preliminaries are out of the way, this is the really important stuff. In the last chapter, we used the TextOut function to display some text in the client area of the window. As we'll see, other GDI functions let us draw lines and filled areas. In Chapters 14 and 15, we'll also see how to draw bit-mapped images.
绘制一些东西的函数 - 显然,一旦所有的准备都不碍事时,这是真正重要的材料。在上一章,我们用 TextOut 函数在窗口的客户区中显示一些文本。正如我们将看到的,其它 GDI 函数让我们画线和填充区域。在第 14 和 15 章中,我们也将看到如何绘制位图图像。 Functions that set and get attributes of the device context An "attribute" of the device context determines various details regarding how the drawing functions work. For example, you can use SetTextColor to specify the color of any text you draw using TextOut or other text output functions. In the SYSMETS programs in Chapter 4, we used SetTextAlign to tell GDI that the starting position of the text string in the TextOut function should be the right side of the string rather than the left, which is the default. All attributes of the device context have default values that are set when the device context is obtained. For all Set functions, there are Get functions that let you obtain the current device context attributes.
设置和获得关联设备属性的函数 - 关联设备的“属性”确定关于绘图函数如何工作的各种细节。例如,你可以用 SetTextColor 指定你用 TextOut 或其它文本输出函数绘制的任何文本的颜色。在第四章中的 SYSMETS 程序中,我们用 SetTextAlign 告诉 GDI TextOut 函数中文本字符串的开始位置应该是字符串的右边而非左边,这是缺省的。关联设备的所有属性有缺省值,当关联设备被获得时它们被设置。对于所有的 Set 函数,有让你获得当前关联设备属性的的 Get 函数。 Functions that work with GDI "objects" Here's where GDI gets a bit messy. First an example: By default, any lines you draw using GDI are solid and of a standard width. You may wish to draw thicker lines or use lines composed of a series of dots or dashes. The line width and this line style are not attributes of the device context. Instead, they are characteristics of a "logical pen." You can think of a pen as a collection of bundled attributes. You create a logical pen by specifying these characteristics in the CreatePen, CreatePenIndirect, or ExtCreatePen function. Although these functions are considered to be part of GDI, unlike most GDI functions they do not require a handle to a device context. The functions return a handle to a logical pen. To use this pen, you "select" the pen handle into the device context. The current pen selected in the device context is considered an attribute of the device context. From then on, whatever lines you draw use this pen. Later on, you deselect the pen object from the device context and destroy the object. Destroying the pen is necessary because the pen definition occupies allocated memory space. Besides pens, you also use GDI objects for creating brushes that fill enclosed areas, for fonts, for bitmaps, and for other aspects of GDI.
和 GDI “对象”一起工作的函数 - 这里 GDI 变得有点零乱。首先一个例子:缺省情况下,你用 GDI 绘制的任何线是实心的并且是标准宽度。你可能希望绘制粗线或用由一系列点或线组成的线。线宽和线的风格不是关联设备的属性。代替的是,它们是“逻辑画笔”的特征。你可以把画笔看作一束属性的集合。你通过在 CreatePen,CreatePenIndirect 或 ExtCreatePen 函数中指定这些特征创建逻辑画笔。尽管这些函数被认为是 GDI 的一部分,但是并不像大多数 GDI 函数,它们不需要关联设备句柄。这些函数返回逻辑画笔的句柄。为了使用该画笔,你将画笔句柄“选”尽关联设备。选进关联设备的当前画笔被认为是关联设备的属性。从那时起,无论你画什么线都用这个画笔。稍后,你从关联设备取消画笔对象并销毁该对象。销毁画笔是必要的,因为画笔定义占用了分配的内存空间。除画笔之外,你也可以将 GDI 对象用于创建填充封闭区域的画刷,用于字体,用于位图和用于其它 GDI 方面。 The GDI Primitives GDI 的基本图形
The types of graphics you display on the screen or the printer can themselves be divided into several categories, which are called "primitives." These are: 你在屏幕或打印机上显示的图形类型本身可以被分成几个种类,这叫做“基本图形”。它们是: Lines and curves Lines are the foundation of any vector graphics drawing system. GDI supports straight lines, rectangles, ellipses (including that subset of ellipses known as circles), "arcs" that are partial curves on the circumference of an ellipse, and Bezier splines, all of which I'll discuss in this chapter. If you need to draw a different type of curve, you can draw it as a polyline, which is a series of very short lines that define a curve. GDI draws lines using the current pen selected in the device context.
直线和曲线 - 直线是任何向量图形绘制系统的基础。GDI 支持直线,矩形,椭圆(包括叫做圆的椭圆的子集),椭圆四周部分曲线的“弧”和贝塞尔曲线,所有这些我将在本章中讨论。如果你需要绘制不同类型的曲线,那么你可以把它绘制为折线,它是一系列非常短的定义曲线的线。GDI 用当前选进关联设备的画笔绘制直线。 Filled areas Whenever a series of lines or curves encloses an area, you can cause that area to be filled with the current GDI brush object. This brush can be a solid color, a pattern (which can be a series of horizontal, vertical, or diagonal hatch marks), or a bitmapped image that is repeated vertically or horizontally within the area.
填充区域 - 无论什么时候一系列的直线或曲线封闭一块区域,你都可以使得那个区域被用当前的 GDI 画刷对象填充。这个画刷可以是实心颜色,图案(这可能是一系列水平,垂直或对角图案标志),或在区域中垂直或水平重复的位图图像。 Bitmaps A bitmap is a rectangular array of bits that correspond to the pixels of a display device. The bitmap is the fundamental tool of raster graphics. Bitmaps are generally used for displaying complex (often real-world) images on the video display or printer. Bitmaps are also used for displaying small images that must be drawn very quickly, such as icons, mouse cursors, and buttons that appear in application toolbars. GDI supports two types of bitmaps—the old (although still quite useful) "device-dependent" bitmap, which is a GDI object, and the newer (as of Windows 3.0) "device-independent" bitmap (or DIB), which can be stored in disk files. I'll discuss bitmaps in Chapters 14 and 15.
位图 - 位图是符合显示设备的像素的矩阵列。位图是光栅图形的基本工具。位图通常用于视频显示器或打印机上复杂(常常是真实世界)图形的显示。位图也用于必须被非常快地绘制的诸如图标,鼠标指针和出现在应用程序工具栏中按钮的小图像的显示。GDI 支持两种类型的位图——旧的(尽管仍然十分有用)“设备相关”位图,它是 GDI 对象;和新的(从 Windows 3.0 开始)“设备无关”位图(或设备无关点位图),它可以存储在磁盘文件中。我将在第 14 和 15 章中讨论位图。 Text Text is not quite as mathematical as other aspects of computer graphics; instead it is bound to hundreds of years of traditional typography, which many typographers and other observers appreciate as an art. For this reason, text is often the most complex part of any computer graphics system, but it is also (assuming literacy remains the norm) the most important. Data structures used for defining GDI font objects and for obtaining font information are among the largest in Windows. Beginning with Windows 3.1, GDI began supporting TrueType fonts, which are based on filled outlines that can be manipulated with other GDI functions. Windows 98 continues to support the older bitmap-based fonts for compatibility and small memory requirements. I'll discuss fonts in Chapter 17.
文本 - 文本不像计算机图形的其它方面是十分精确的;代替的它一定要几百年的传统印刷,许多印刷者和其它观察者把它欣赏为艺术。由于这个原因,文本常常是任何计算机图形系统中最复杂的部分,但是它也是(假定文化保留标准)最重要的。用来定义 GDI 字体对象和获得字体信息的数据结构在 Windows 中是大量的。从 Windows 3.1 开始,GDI 开始支持 TrueType 字体,它是基于可以被其它 GDI 函数操纵的已填充的图形。为了兼容性和少量内存要求,Windows 98 继续支持旧的基于位图的字体。我将在第 17 章中讨论字体。 Other Stuff 其它材料
Other aspects of GDI are not so easily classifiable. These are: GDI 的其它方面不是如此容易分类的。它们是:  Mapping modes and transforms Although by default you draw in units of pixels, you are not limited to doing that. The GDI mapping modes allow you to draw in units of inches (or rather, fractions of inches), millimeters, or anything you want. In addition, Windows NT supports a traditional "world transform" expressed as a 3-by-3 matrix. This allows for skewing and rotation of graphics objects. The world transform is not supported under Windows 98.
映射模式和转换 - 尽管缺省情况下你用像素单位绘图,但是你并没有被限制要这样做。GDI 映射模式允许你用英寸(或者甚至是英寸的小数),毫米或者任何你想的单位绘图。另外,Windows NT 支持传统的 3×3 矩阵的“转换体系”。这允许图形对象的相位差和旋转。转换体系在 Windows 98 下不被支持。 Metafiles A metafile is a collection of GDI commands stored in a binary form. Metafiles are used primarily to transfer representations of vector graphic drawings through the clipboard. I'll discuss metafiles in Chapter 18.
元文件 - 元文件是以二进制形式存储的 GDI 命令的集合。元文件最初用于通过剪贴板传递矢量图形绘制的图像。我将在第 18 章中讨论元文件。 Regions A region is a complex area of any shape and is generally defined as a Boolean combination of simpler regions. More complex regions can be stored internally in GDI as a series of scan lines derived from the original definition of the region. You can use regions for outlining, filling, and clipping.
区域 - 区域是任何形状的复杂区域,它通常被定义为较简单区域的布尔组合。在 GDI 内部大多复杂区域可以被存储为一系列来源于最初定义的区域的扫描线。你可以将区域用于描绘轮廓,填充和剪裁。 Paths A path is a collection of straight lines and curves stored internally in GDI. Paths can be used for drawing, filling, and clipping. Paths can also be converted to regions.
路径 - 路径是存储在 GDI 内部的直线和曲线的集合。路径可以被用于绘图,填充和剪裁。路径也可以被转换为区域。 Clipping Drawing can be restricted to a particular section of the client area. This is known as clipping. The clipping area can be rectangular or nonrectangular, generally specified as a region or a path.
剪裁 - 绘图可以受限于客户区的特殊区域。这叫做剪裁。剪裁区域可以是规则的或不规则的,通常指定为区域或路径。 Palettes The use of a customized palette is generally restricted to displays that show 256 colors. Windows reserves only 20 of these colors for use by the system. You can alter the other 236 colors to accurately display the colors of real-world images stored in bitmaps. I'll discuss palettes in Chapter 16.
调色板 - 自定义调色板的用处通常是受限于显示 256 色的显示器。Windows 只保留了这些颜色的 20 种给系统使用。你可以将其它 236 种颜色改为精确地显示存储于位图中的真实世界的图像。我将在第 16 中讨论调色板。 Printing Although this chapter is restricted to the video display, almost everything you learn here can be applied to printing. I discuss printing in Chapter 13. 打印 - 尽管本章受限于视频显示器,但是几乎你在这里学到的每一样都可以应用于打印。我在第 13 章中讨论打印。

本文地址:http://com.8s8s.com/it/it26642.htm