GDI编程小结

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.****.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏幕输出。GDI负责Windows的所有图形输出,包括屏幕上输出像素、在打印机上输出硬拷贝以及绘制Windows用户界面。也就是Windows的图形编程。

一、GDI体系结构

1、  GDI32.DLL导出的函数

GDI提供几百个Windows程序中可以调用的函数。这些函数大多数是从Win32的子系统DLL GDI32.DLL中导出的。窗口管理模块UER32.DLL是使用GDI函数的大用户,它用GDI函数来绘制菜单、图标、滚动条、标题栏和每个窗口的框架等细节内容。有一些绘图函数从USER32.DLL导出,提供给应用程序。仅Windows2000 GDI32.DLL就导出了543个入口点。与DevStudio一起发行的dumpbin工具是一个简单的工具,能列出模块导出的函数。下面就是由dumpbin gdi32.dll /export 产生的部分内容:

AbortDoc
AbortPath
AddFontMemResourceEx
AddFontResourceA
AddFontResourceExA
AddFontResourceExW
AddFontResourceTracking
AddFontResourceW
AngleArc
AnimatePalette
AnyLinkedFonts
Arc
ArcTo
具体查看:http://www.cnblogs.com/del/archive/2008/03/11/1101291.html
GDI编程小结  

 

2、  GDI函数分类

GDI的功能太多了,所以我们需要一种办法对Win32 GDI API的函数分类,以便理解GDI的结构,MSDN库将GDI API分成17个领域,清楚地描述了GDI的功能。

(1)位图:处理创建、绘制设备相关位图(DDB)、设备无关位图(DIB)DIB段、像素和区域填充的函数。

(2)画刷:处理创建、修改GDI画刷对象的函数。

(3)剪裁:处理设备上下文可绘制区域的函数。

(4)颜色:调色板管理。

(5)坐标和变换:处理映射模式、设备坐标映射逻辑和通用变换矩阵的函数。

(6)设备上下文:创建设备上下文,查询、设置其属性,及选择GDI对象的函数。

(7)填充形状:绘制闭合区域及其周线的函数。

(8)字体和文本:在系统中安装和枚举字体,并用它们绘制文本字符串的函数。

(9)直线和曲线:绘制直线、椭圆曲线和贝赛尔曲线的函数。

(10)元文件:处理Windows格式的元文件或增强型元文件的生成和回放的函数。

(11)多显示监视器:允许在一个系统中使用多个显示监视器的函数。这些函数实际上是从uer32.dll导出的。

(12)画图和绘图:负责绘图消息管理和窗口已绘图区域的函数。其中一些函数实际上是从uer32.dll导出的。

(13)路径:负责将一系列直线和曲线组成名为路径的GDI对象,并用它来绘制的函数。

(14)画笔:处理直线绘制属性的函数。

(15)打印和打印池:负责将GDI绘图命令发送到硬拷贝设备(如行式打印机和绘图仪)并平滑地管理这些任务的。打印池函数是由Win32打印池提供的,包括几个系统提供的DLL和销售自定义的模块。

(16)矩形:user32.dll提供的处理RECT结构的函数。

(17)区域:负责用区域GDI对象描述一个点集的函数,并对该点集进行操作。

还有一些没有文档记载的函数。有一些GDI函数在DDK中说明,还一些没有文档记载但系统DLL使用的函数,另处还有一些函数则没有用过。下面是这些函数的粗略分类:

用户模式打印机驱动程序。

OPENGL

EUDC

其他系统DLL支持。

其他没有文档记载的函数。

3、  GDI对象句柄

32位的GDI句柄由8位未知的高位、1位堆对象标记、7位对象类型信息和高4位是016位索引组成。借助7位对象类型信息,可以确定设备上下文、区域、位图、调色板、字体、画刷、加强型图元文件、画笔和扩展画笔。

GDI编程小结

4GDI对象类型

GDI对象表

typedef struct

{

void * pKernel;

unsigned short nProcess;

unsigned short nCount;

unsigned short nUpper;

unsigned short nType;

void * pUser;

}GdiTableCell;

1 pKernel指向页面池:对每个有效GDI对象,pKernel从不为空,并且值总是唯一的。因此看起来对每个GDI对象有一个相应的数据结构,这个数据结构只能从内核模式代码存取,甚至不能从GDI32.DLL直接存取。对于不同进程的对象,从pKernel的值中看不出明显区分区域来。pKernel指向的对象起始地址是0xE1000000,根据《Inside Windows NT》,起始地址是0xE1000000的区域一般是被称为“页面池”的可分页系统的内存堆。

2nCount 是一个部分选择计数器:在Windows 2000下,nCount总是零,就是说未使用。但在Windows NT 4.0中,某些GDI对象用了它。为了理解nCount的意义,我们试着将对象句柄选入和取消一个或多个设备上下文中,观察选入和取消是否能根据nCount值的变化而成功。

3nProcess使得GDI句柄绑定到进程:如果程序想使用另一个进程的GDI对象句柄,Win32 API调用一般会失败。GdiTableCell中的nProcess字段就是这种现象背后的原因。对于库存(stock)对象,如GetStockObjectBLACK_PEN),nProcess被置为零。对于用户进程创建的其他 GDI对象,nProcess是创建进程的进程标识符。

有了这个字段,GDI就会很容易地检查当前进程标识符是否和GDI对象的nProcess字段一致,目的是强制对象句柄不能在另一个进程中访问的规则。

根据微软的文档,进程终止时,由该进程创建的所有GDI对象会被释放。如果你想知道这是怎样实现的,我们现在有一点线索了。GDI只需搜索GDI对象表并删除有指定进程标识符的对象。

4nUpper:再次检查句柄:我们发现GDI对象表入口的nUpper字段是4字节GDI对象句柄的高两个字节的完全拷贝——对GDI对象句柄进行错误检查是低成本的冗余校验。

5nType:内部对象类型:nType的低字节通常和HGDIOBJ中的是7位类型信息相同,高位字节通常是零。

6pUser指向用户模式数据结构。

GDI对象类型列表:

GDI编程小结

5、GDI函数大致分类

   设备上下文函数(GetDCCreateDCDeleteDC) 画线函数(LineToPolyline