鱼C论坛

 找回密码
 立即注册
查看: 7599|回复: 14

[扩展阅读] 第015讲:GDI 的结构(课文解读)

[复制链接]
发表于 2014-9-19 15:52:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
以下解读来自《Windows 程序设计》(第5版 珍藏版)P99~103


GDI 原理

在 Windows 98 和 Windows NT 中,图形显示主要由动态链接库 GDI32.DLL 中导出的函数来处理。在 Windows 98 中,许多函数是 GDI32.DLL 利用 16 位 GDI.EXE 动态链接库来实现的。在 Windows NT 中,GDI.EXE 只用于 16 位的程序。

小甲鱼解读:Win7 64位 开始已经不支持 16 位程序了,但核心的架构和技术不会改变

这些动态链接库会调用你安装的视讯显示器和打印机的设备驱动程序中的一些函数。视频驱动程序会直接访问视频显示器的硬件,而打印机驱动程序则将 GDI 命令转换为各种打印机所能理解的代码或者命令。所以,不同的显示适配器和打印机要求不同的设备驱动程序。

小甲鱼解读:起初所有的厂商都保持着自己的标准,所以要用哪家的产品就要装哪家的驱动。不过现在好了,逐渐开始有了统一的规则约束这些厂商不要特立独行(像 USB 接口)

各种各样的显示设备都可以与 PC 兼容机连接。因此,GDI 的一个主要目的就是支持与设备无关的图形。Windows 程序应当毫无问题地在 Windows 所支持的任何图形设备上输出。GDI 提供了一种特殊的机制来彻底隔离应用程序和不同输出设备的特性,这样就支持与设备无关的图形。

小甲鱼解读:意思是我们的 WinSDK 编程不需要考虑硬件的物理设备,利用 GDI 就可以很好的做到“与设备无关”编程

C 的闻名之处在于它在不同操作系统和环境之间的高度可移植性。还有就是允许程序员执行底层系统函数,这是其他高级语言做不到的。就如同 C 常被当成“高级汇编语言”一样,你可以把 GDI 当成图形设备硬件的一种高层接口。

小甲鱼解读:因为 C 语言可以轻松转换为汇编语言,汇编语言跟 CPU 机器指令一一对应

如前所述,Windows 默认使用以像素为单位的坐标系统。大多数传统的图形语言都使用一个“虚拟”坐标系统,它的横轴和纵轴的范围是 0 ~ 32767。尽管一些图形语言并不允许使用像素坐标,但是 Windows GDI 允许使用任何一种坐标系统(可以使用其他依据物理测量得到的坐标系统),所以你可以使用虚拟坐标系统来保证程序与硬件独立,也可以使用设备坐标系统来完全迎合硬件的需求。

小甲鱼解读:Windows GDI 很大的一个作用就是充当“翻译官”

一些程序员认为,以像素的形式进行程序设计时,即意味着放弃了设备独立性。通过前边课程的学习,我们知道这么说不完全正确。关键在于要以设备独立的方式来使用像素,这需要设备接口语言为程序提供一种机制来查询设备硬件的特性,以便程序做出合适的调整。例如,在 SYSMETS 程序中,我们使用标准字体字符的像素大小在屏幕上安排字符。这种方法允许程序根据不同的显示适配器来调整分辨率、文本大小以及纵横比。你可以在接下来的视频教程中看到确定显示区域大小的其他一些方法。

小甲鱼解读:大家还记得 GetSystemMetrics 函数吧?

在不同的计算机上运行 C 语言程序时总会有一些细小的移植性问题。同样地,在设计 Windows 程序时多少也会带入一些设备依赖性。比如,尽管你可以在显示器上移动图形对象,但是 GDI 总体上来说只是一个静态显示系统,对动画的支持很有限。如果你需要为游戏编写复杂的动画,应当学习一下 DirectX,它提供了必要的动画支持。

小甲鱼解读:DirectX,(Direct eXtension,简称DX)是由微软公司创建的多媒体编程接口。由C++编程语言实现,遵循COM。被广泛使用于Microsoft Windows、Microsoft XBOX、Microsoft XBOX 360和Microsoft XBOX ONE电子游戏开发,并且只能支持这些平台。


温馨提示:下边内容新鱼油看后可能会导致心烦意乱或内心冲突,若有此症状请记住小甲鱼的一句话“以下内容仅需知道,暂不要求掌握”

GDI 函数调用

GDI 包含有几百个函数,可以分成下面几大类。


获取(或建立)和释放(或销毁)设备环境的函数

我们在前面的教程中已经接触过,你在窗口上绘图时需要一个设备内容句柄。BeginPaint 和 EndPaint 函数(尽管在技术上它们是 USER 模块而不是 GDI 模块的一部分)允许你在处理 WM_PAINT 消息时做到这一点。在处理其他消息时,可以通过调用 GetDC 和 RealseDC 函数来达到相同的目的。后边的教程小甲鱼会介绍其他一些有关设备环境的函数。

获取设备环境信息的函数

在前边的 SYSMETS 程序中,我们使用 GetTextMetrics 函数来取得有关设备内容中目前所选字体的尺寸信息。

绘图函数

显然,在所有前提条件都得以满足之后,这些函数是真正重要的部分。在前边的教程中,我们使用 TextOut 函数在窗口的显示区域显示一些文字(I love FishC.com!)。在紧接着的教程中,我们还将学习到使用其它 GDI 函数绘制线条和填充区域。

设置和获取设备环境属性的函数

设备环境的属性确定绘图函数在绘制时的各种细节。在 SYSMETS 程序中,我们使用 SetTextAlign 函数来通知 GDI,TextOut 函数中文本字符串的起始位置应当在字符串的右边,而不是默认的左边(不懂得请看这篇:如何设置文本对齐模式,并深刻检讨是否有独立完成课后作业)。

所有的设备环境的属性都有一个默认值,这个默认值在获取设备环境时就已经被设置好了。对所有的以“Set”开头的函数,都有相应的一个以“Get”开头的函数用于获取当前设备环境的属性。

使用 GDI“对象”的函数

GDI 在这里变得有点混乱。首先举一个例子:在默认情况下,使用 GDI 绘制的所有直线都是实线,并具有一个标准的宽度。你可能希望绘制更细的直线,或者是由一系列的点或短划线组成的直线。但直线的宽度和画笔的样式并不是设备环境的属性。然而,它们是“逻辑画笔”的特征。你可以通过在 CreatePen、 CreatePenIndirect 或 ExtCreatePen 函数中指定这些特征来建立一个逻辑画笔,这些函数传回一个逻辑画笔的句柄(虽然这些函数被认为是 GDI 的一部分,但是和大多数 GDI 函数调用不一样,它们不要求设备内容的句柄)。要使用这个画笔,就要将画笔句柄选进设备环境中。

我们认为,设备环境中目前选中的画笔就是设备环境的一个属性。这样,您画任何线都使用这个画笔,然后,您可以取消设备内容中的画笔选择,并清除画笔对象。清除画笔对象是必要的,因为画笔定义占用了分配的内存空间。除了画笔以外,GDI 对象还用于建立填入封闭区域的画刷、字体、位图以及 GDI 的其它一些方面使用 GDI 对象。


GDI 的基本图形

在屏幕上或者打印机上显示的图形类型可以分为下面几类,被称为“基本图形”。


线条和曲线

线条是所有矢量图形绘制系统的基础。GDI 支持直线、矩形、椭圆(包括特殊的椭圆,也就是我们所说的圆形)、椭圆弧线(椭圆圆周上的部分曲线)以及贝塞尔样条曲线(Bezier spline),我们将在接下来的教程中分别对它们进行介绍。如果需要绘制一个不同类型的曲线,你可以把它绘制成折线代替(折线就是通过一组非常短的直线来定义一条曲线)。GDI 使用当前选入设备环境的画笔绘制线条。

可被填充的封闭区域

当一系列的线条或者曲线构成一个封闭的区域时,该区域就可以使用当前的 GDI 画刷对象进行填充。这个画刷可以是纯色的,或者是使用某种填充模式(如一系列水平的、垂直的或者倾斜的图案),还可以是在水平或垂直方向不停重复的位图图像。

位图

位图是位的矩形数组(二维数组),每一个位对应于显示设备上的一个像素。位图是光栅图形的基础。位图通常用于在视频显示器或者打印机上显示复杂(一般都是真实世界)的图像。位图也通常用于显示必须要快速绘制的小图像(诸如图标、鼠标光标以及在应用工具条中出现的按钮等)。GDI 支持两种型态的位图-旧式的(虽然还非常有用)“设备相关”位图,属于 GDI 对象;新式的“设备无关”位图(DIB),可以储存在磁盘文件中。

文字

文字的数学味道不像计算机图形的其它方面那样浓。文字和几百年的传统印刷术有关,它被许多印刷工人看作为一门艺术。因此,文字通常不仅是所有的计算机图形系统中最复杂的部分,而且(如果识字还是社会基本要求的话)也是最重要的部分。用于定义 GDI 字体对象和取得字体信息的数据结构是 Windows 中最庞大的部分之一。从 Windows 3.1 开始,GDI 开始支持 TrueType 字体,该字体是在填入轮廓线基础上建立的,这样的填入轮廓线可由其它 GDI 函数处理。


其他

GDI 的其他方面就不太容易分类了,具体如下。


映像模式(mapping mode)和转换(transform)

尽管在默认时是以像素为单位进行绘图,但是你并非别无选择。GDI 的映像模式允许你以英寸(或者甚至以几分之一英寸)、毫米或者任何您想使用的单位来绘图(Windows NT 还支持传统的以 3 * 3 矩阵表示世界坐标变换(world transform)。 这用于倾斜和旋转图形对象。

图元文件(metafile)

一个图元文件是以二进制形式储存的 GDI 命令的集合。图元文件主要用于通过剪贴板转换矢量图形绘制的表现形式。

区域(region)

区域是一个任意形状的封闭图形,通常定义为较简单的绘图区域组合。在 GDI 内部,绘图区域除了储存为最初用来定义绘图区域的线条组合以外,还以一系列扫描线的形式储存。您可以将绘图区域用于绘制轮廓、填入图形和剪裁。

路径(path)

路径是GDI内部储存的直线和曲线的集合。路径可以用于绘图、填入图形和剪裁,还可以转换为绘图区域。

剪裁(clipping)

当绘图被限制在客户区的一个特定的空间位置时,就发生了剪裁。那个特定的空间位置可以是矩形或者非矩形,它通常被指定为一个区域或者一个路径。

调色板(palettes)

仅在支持 256 种颜色时,才能使用自定义的调色板。Windows 仅保留这些色彩之中的 20 种以供系统使用。您可以改变其它 236 种色彩,以准确显示按位图形式储存的真实图像。

打印(printing)

尽管在本章教学中我们只限于讨论视频显示器,但是你在本章中所学到的所有知识几乎都可以应用于打印机。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-20 13:28:23 From FishC Mobile | 显示全部楼层
厉害,这么详细~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-9-22 22:55:52 | 显示全部楼层
小甲鱼真棒!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-11-29 14:53:02 | 显示全部楼层
厉害...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-1-6 01:21:07 | 显示全部楼层
路过路过.楼主辛苦了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-4 20:52:35 | 显示全部楼层
haohaoxuexi
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-12 09:43:02 | 显示全部楼层
顶一下!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-8-11 17:52:26 | 显示全部楼层
调色板是palette而不是plalette
@小甲鱼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-10-18 16:39:24 | 显示全部楼层
辛苦了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-12-20 20:56:22 | 显示全部楼层
:dizzy:看了和不看好像没什么区别
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-23 22:46:22 | 显示全部楼层
好多ing。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-17 13:11:51 | 显示全部楼层
好好学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-14 00:09:02 | 显示全部楼层
小甲鱼讲的还是相当不错的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-5 15:09:08 From FishC Mobile | 显示全部楼层
所以学了Windows sdk还不能做游戏,做游戏要DX
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-24 15:51:22 | 显示全部楼层
非常详细!也能看懂,厉害!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 16:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表