GDI原理

GDI原理


Windows 98 和Microsoft Windows NT 中的图形主要由GDI32.DLL 动态连结程式库输出的函数来处理。在Windows 98 中,这个GDI32.DLL 实际是利用16位元GDI.EXE 动态连结程式库来执行许多函数。在Windows NT 中,GDI.EXE 只用於16 位元的程式。
这些动态连结程式库呼叫您安装的视讯显示器和任何印表机呼叫驱动程式中的常式。视讯驱动程式存取视讯显示器的硬体,印表机驱动程式将GDI 命令转换为各种印表机能够理解的代码或者命令。显然,不同的视讯显示卡和印表机要求不同的装置驱动程式。
因为PC 相容机种上可以连接许多种不同的视讯设备,所以,GDI 的主要目的之一是支援与装置无关的图形。Windows 程式应该能够毫无困难地在Windows支援的任意一种图形输出设备上执行,GDI 通过将您的程式和不同输出设备的特性隔离开来的方法来达到这一目的。
图形输出设备分为两大类:位元映射设备和向量设备。大多数PC的输出设备是位元映射设备,这意味著它们以图点构成的阵列来表示图像,这类设备包括视讯显示卡、点阵印表机和雷射印表机。向量设备使用线来绘制图像,通常局限於绘图机。

许多传统的电脑图形程式设计方式都是完全以向量为主的,这意味著使用向量图形系统的程式与硬体有著一定层次的隔离。输出设备用图素表示图形,但是程式与程式介面之间并不是用图素进行沟通的。您当然可以使用WindowsGDI 作为一个高阶的向量绘制系统,同时也可以将它用於比较低阶的图素操作。
从这方面来看,Windows GDI 和传统的图形介面语言之间的关系,就如同C和其他程式设计语言之间的关系一样。C 以它在不同作业系统和环境之间的高度可携性而闻名,然而C 也以允许程式写作者进行低阶系统呼叫而闻名,这些呼叫在其他高阶语言中通常是不可能的。正如C 有时被认为是一种「高级组合语言」一样,您可以认为GDI 是图形设备硬体之间的一种高阶介面。
您已经看到,Windows 内定使用图素座标系统。大多数传统的图形语言使用「虚拟」座标系,其水平和垂直轴的范围在0 到32,767 之间。虽然有些图形语言不让您使用图素座标,但是Windows GDI 允许您使用两种座标系统之一(甚至依据实际度量衡的座标系)。您可以使用虚拟座标系以便让程式独立於硬体之外,或者也可以使用设备座标系而完全迎合硬体设备提供的环境。

早期,许多使用者在单色显示器上执行Windows。即使是几年前,笔记本电脑也还只有灰阶显示。为此,GDI 的设计保证了您可以在编写一个程式时不必太担心色彩问题——也就是说,Windows可以将色彩转换为灰阶显示。甚至在今天,Windows 98 使用的视讯显示已经具有了不同的色彩能力(16 色、256 色、「high-Color」以及「true-color」)。虽然,彩色喷墨印表机的成本已经很
低了,但是大多数使用者仍然坚持使用黑白印表机。盲目地使用这些设备是可以的,但是您的程式也应该能决定在某种显示设备上有多少色彩可以使用,从而最佳利用硬体功能。
当然,就如同您编写C 程式时,为了使它在其他电脑上执行而遇到一些微妙的移植性问题一样,您也可能不小心让装置依赖性溜进您的Windows 程式,这就是不与硬体完全隔离的代价。您还应该知道Windows GDI 的局限。虽然可以在显示器上到处移动图形物件,但GDI 通常是一个静态的显示系统,只有有限的动画支援。如果需要为游戏编写复杂的动画,就应该研究一下Microsoft
DirectX,它提供了您需要的支援。

函数调用举例

Windows可以画直线、椭圆线(椭圆圆周上的曲线)和贝塞尔曲线。Windows
98 支援的7 个画线函数是:

  • LineTo 画直线。
  • Polyline 和PolylineTo 画一系列相连的直线。
  • PolyPolyline 画多组相连的线。
  • Arc 画椭圆线。
  • PolyBezier 和PolyBezierTo 画贝塞尔曲线。

画一条直线,必须呼叫两个函数。第一个函数指定了线的开始点,第二个
函数指定了线的终点:
MoveToEx (hdc, xBeg, yBeg, NULL) ;
LineTo (hdc, xEnd, yEnd) ;
MoveToEx 实际上不会画线,它只是设定了装置内容的「目前位置」属性。然後LineTo 函数从目前的位置到它所指定的点画一条直线。

下面的程式码从视窗的左上角开始,在显示区域中画一个网格,线与线之间相隔100 个图素,其中hwnd 是视窗代号,hdc 是装置内容代号,而x 和y 是整数:
GetClientRect (hwnd, &rect) ;
for ( x = 0 ; x < rect.right ; x+= 100)
{
MoveToEx (hdc, x, 0, NULL) ;
LineTo (hdc, x, rect.bottom) ;
}
for (y = 0 ; y < rect.bottom ; y += 100)
{
MoveToEx (hdc, 0, y, NULL) ;
LineTo (hdc, rect.right, y) ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值