恩,加快时间复习,依旧不再废话

之前我们简单说明了Windows的基本消息机制,并且成功创建了一个空白的窗口,今天我们将简单介绍一下Windows的GDI.

###GDI的定义

我们现阶段的网络游戏大部分还是依靠显示器来向玩家传递信息的,而WINDOWS的子系统–图形设备接口(GDI:Graphics Device Interface)正是负责对显示器和打印机进行控制的接口.

###GDI的原理 在WIN95后,我们的图形主要由GDI32.DLL动态链接库输出的函数来处理.这些动态链接库调用我们显示器驱动程序中的例程.这极大的方便了我们的编程.

因为我们需要了解,显卡的类型并非一致的,而各自的驱动程序更是不同,我们在安装驱动程序时候会发现不同的驱动很少能兼容不同显卡的,这说明我们显卡的各种功能是不同的,提供的接口也是不同的,我们若直接对它们操作,将会需要了解各种显卡的机能和接口,这对程序员来说是极其痛苦的,GDI为我们提供了一套统一的接口,使我们无需直接针对显卡进行操作,而更无需知道显卡驱动中到底写了些什么接口和程序.我们需要做的仅仅是对GDI函数的调用,由它对我们的显卡驱动进行操作.

###GDI的函数类型

我们需要明白的一个事情是,组成GDI的函数有几百个,而我们没有能力去一个一个的了解和使用,而且我们3D网络游戏中,会很少的使用它来进行图形输出,所以我们这里仅仅是理解一个大概.

GDI函数虽然有几百个,但从功能来看,可以分为以下几类:

  1. 建立和释放设备的函数.

我们在绘图的时候需要使用设备句柄,以确定我们具体是用什么设备,哪个设备来进行图形的输出.这时GetDC和RealseDC函数在非WM_PAINT的消息处理期间来做到这一点,而BeginPaint和EndPaint函数将会在进行绘图的WM_PAINT消息处理期间来使用.我们可以在其中加入我们需要绘制的图象信息.

  1. 取得当前设备信息的函数.

我们创建了设备,在我们的程序运行中间,我们可能有时会需要对设备进行监视,以免出现某种设计上的错误,这时可以调用此类函数来获得设备的当前部分信息,方便我们控制和纠错.如GetTextMetrics函数可以取得有关设备内容中目前所选字体的尺寸信息.

  1. 绘图函数.

GDI本身是一个图形设备接口,能够输出图形是它的最基本的功能,我们当然要求它有一定的绘图能力,这部分相对比较常用和重要,我在下面将会更详细的讲述.

  1. 设置设备信息的函数.

大家应该接触过PhotoShop吧,在我们绘图之前,我们必须先选择画笔,颜色,大小,笔刷风格等信息,这就想当于GDI中的Set类函数,它可以控制我们GDI设备中的大部分信息,方便我们绘图,当然,PS是可视化的图形制作工具,我们的GDI绘图中经常会不知道当前的笔刷是什么样子,所以每个Set函数都对应一个Get函数,就是上面说的取得当前设备信息的函数.方便我们查看当前状态.

  1. 使用GDI对象的函数.

GDI对象可以用于建立填入封闭区域的画刷,字体,位图以及GDI的其它一些方面.

###GDI的基本图象

  1. 点,直线和曲线.
  2. 矩形,椭圆,弧型(当然包括特殊矩形–正方型,长方型,特殊椭圆–圆)
  3. 贝塞尔曲线(Bezier spline)
  4. 折线(当然使用折线可以构造大部分图形了)
  5. 填充区域(当一定的区域被封闭时,可填充颜色,就如PS中的填充啦)
  6. 位图.(其实就是一系列存储象素点坐标色彩的矩形数组)
  7. 文字

###GDI编程的基本步骤

  1. 取得设备句柄.

无论我们画什么图,我们首先要准备一张纸.程序也是如此,我们必须先给GDI一个图形输出的设备句柄.让它明白我们准备在哪儿上面绘制图形和输出图形.通常使用的函数是:

hdc = BeginPaint (hwnd, &ps) ;
       …绘图程序
EndPaint (hwnd, &ps) ;

其中hwnd是窗口的句柄,变量ps是型态为PAINTSTRUCT的结构,该结构的hdc字段是BeginPaint传回的设备内容句柄。 PAINTSTRUCT结构又包含一个名为rcPaint的RECT(矩形)结构,rcPaint定义一个包围窗口显示区域无效范围的矩形。使用从BeginPaint获得的设备内容句柄,只能在这个区域内绘图。

然而这个函数被WINDOWS规定仅可在WM_PAINT消息内进行使用,但是若我们出了PAINT消息也想制作输出图形怎么办?我们可以使用下述函数来获得设备句柄.

hdc = GetDC (hwnd) ;
 …其它程序
ReleaseDC (hwnd, hdc) ;

当然我们注意到每个Get/Begin之后,我们都有句EndPaint/或ReleaseDC这句,这是因为我们创建了设备句柄之后,在内存中将为其开辟一个空间,在我们的功能使用完毕后,它们并不会自动释放,需要我们去使用释放的函数去通知系统释放内存.当然,释放后的设备句柄将不再有效.

  1. 取得设备信息.

当我们获得一个设备句柄后,WINDOWS将默认的设定其一切属性.但我们并不知道这个属性到底是多少,这需要我获得信息,例如:

 iValue = GetDeviceCaps (hdc, iIndex) ;

Index为HORZRES时将使GetDeviceCaps传回设备的宽度(单位为像素);

iIndex为VERTRES时将让GetDeviceCaps传回设备的高度(单位为像素)。

当然我们可以获得更多的信息以方便我们去进行调整为适合我们使用的属性.

###使用GDI绘制图元

当然这一切都是在取得设备句柄和销毁设备句柄之间进行的,我们需要使用设备来进行这一系列的程序操作.

  1. 绘制点

SetPixel (hdc, x, y, crColor) ;

第一个参数是设备内容的句柄。第二个和第三个参数指明了坐标位置,最后一个参数是COLORREF型态指定了颜色 对应的有GetPixel函数传回指定坐标处的图素颜色

crColor = GetPixel (hdc, x, y) ;

  1. 绘制线

Windows可以画直线,椭圆线和贝塞尔曲线.其中

  • LineTo 画直线
  • Polyline和PolylineTo 画一系列相连的直线.
  • Arc 画椭圆.
  • PolyBezier和PolyBezierTo 画贝齐尔曲线.
  • ArcTo和AngleArc 画椭圆线.

因为时间关系,这里不再一一讲述,仅仅拿直线做为例子介绍一下,大家有兴趣的话可以查找WINDOWS API大全.

我们画一条直线,必须调用两个函数。第一个函数指定了线的开始点,第二个函数指定了线的终点.如例:

MoveToEx (hdc, xBeg, yBeg, NULL) ;
LineTo (hdc, xEnd, yEnd) ;

在内定的设备内容中,目前位置最初设定在点(0,0).如果在调用LineTo之前没有设定目前位置,那么它将从显示区域的左上角开始画线 .


呃,不行了,其他的东东明天再说吧,困了,休息第一.>_<