1
'以下为作者【vIsiaswx】的教程 2 '(该教程发布的原地址已无法访问,此版是流散网络的电子书版复制过来的。如果声明必要,务必与我联系。) 3 ' E-mail : lqx@tyningling.top 4 ' QQ: 1919988942

VB6 GDI+  入门教程[1] GDI+ 介绍
引言:鉴于网上关于 GDI+的教程都是.Net 的,基本上没有 VB6.0 的,而这方面又很多人有
需要,所以我就写一个 Visual Basic 6 GDI+ 入门教程。
目标人群:所有能够较熟练使用 VB 的,对 GDI+感兴趣或有 GDI+编程需要的人。
1. What's GDI+
官方解释:GDI+是 Windows XP 中的一个子系统,它主要负责在显示屏幕和打印设备输出
有关信息,它是一组通过 C++类实现的应用程序编程接口。顾名思义,GDI+是以前版本 GDI
的继承者,出于兼容性考虑,Windows XP 仍然支持以前版本的 GDI,但是在开发新应用程
序的时候,开发人员为了满足图形输出需要应该使用 GDI+,因为 GDI+对以前的 Windows
版本中 GDI 进行了优化,并添加了许多新的功能。
作为图形设备接口的 GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑
具体显示设备的细节,他们只需调用 GDI+库输出的类的一些方法即可完成图形操作,真正
的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相
互隔离,从而使开发人员编写设备无关的应用程序变得非常容易。
我的解释:GDI+其实就是一个绘图模块,用于在屏幕上输出各种需要的内容。
2. GDI+ DLL
GDI+的 Dll 在 Windows XP+中默认存在,如果 Windows XP 以下系统需要使用 GDI+,那么
需要从微软网站上下载安装包。
3. 使用 GDI+
GDI+在.net Framework 中默认集成,只要添加它的命名空间(System.Drawing.Drawing2D)
就能够使用了;而 GDI+在其它上面就没有那么容易了,例如 VB6 就需要添加 GDI+的 API。
对于初学者,写一堆 API 可能比学 GDI+用时还要长,不过我整理好了 API 到了一个模块,
使用时候呢 只要在 VB 里面加载一下就可以啦!
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
VB6 GDI+  入门教程[2] GDI+ 初始化
现在先让我们了解下 GDI+的绘图机制。
1.初始化、关闭 GDI+
我们需要对 GDI+进行初始化,才能使用它的各种功能。如果没有初始化,那么 VB6 就会莫
名其妙的崩溃。呵呵。
当然程序结束了我们还要关闭 GDI+释放内存。
2.Graphics
Graphics 是 GDI+基础。首先我们需要一个图形对象 graphics(可以看作是画板),我们所有
的东西都要画在这个上面。那么如何显示呢?不要急,我们可以通过 GDI+内置函数从一个
对象的 DC(设备描述表)上创建 graphics。这样我们操作 graphics 的时候就会显示在对象
上。当然我们还可以从对象的 hwnd 中创建;在.net 中也可以从 gdi+的图像(image)中创建(直
接操作在图像上)。
3.绘图工具
有了画板,我们还要画笔、画刷才能画画 - -。画笔画刷呢,在 gdi+中就叫做 pen、brush。
画笔 pen 只能画一个轮廓(画线),而画刷可以对一个东西进行填充(刷子)。这个就是一个
基础 呵呵,很简单吧。
4.创建第一个 VB6 的 GDI+ 程序
首先,我们添加下 GDI+模块;然后我们需要对窗体(以后可以是其它容器)属性进行设置:
AutoRedraw=True,开启自动重绘;再把 ScaleMode 设置成 3(Pixel 像素),因为 GDI+基础单
位就是像素(当然可以用别的单位)
好,现在双击窗体,写入下面代码:
Option Explicit
Dim graphics As Long
Private Sub Form_Load()
InitGDIPlus
GdipCreateFromHDC Me.hDC, graphics
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
OK,F5 运行。如果没有问题的话我们第一个最基础的 GDI+程序已经完成了。这个基本的
程序创建了一个 graphics 对象,当然什么还没有画呢。
通过这个程序,我们就大致了解 VB6 中 GDI+如何初始化、关闭了。首先呢要启动 GDI+,
然后要创建一个 graphics;关闭的时候也要做好扫地工作。
5.画线
线嘛,又不是填充,根据前面说的,我们需要一个 pen。那么如何创建 pen 呢?呵呵,下面
的代码就能创建一个 pen(追加在 Form_Load 过程中的末尾):
Dim pen As Long
GdipCreatePen1 &HFFFF0000, 1, UnitPixel, pen
这里已经新建了一个 pen。为什么是 GdipCreatePen1 而不是 GdipCreatePen2 什么的呢?你可
以在代码里面输入“mgdip.”这样就列出了所有的 GDI+函数。通过对象浏览器可以得知 pen2
是根据 brush 来创建 pen 的,现在不用。
&HFFFF0000:这里就是一个 16 进制的 ARGB (Alpha,Red,Green,Blue——透明,红色,绿色,
蓝色程度,255(&HFF)是完全,0(&H0)是完全不) 的数据。当然你可以输入 10 进制,只是
16 进制很方便,2 个位就是一段,如&HFFFF0000 就代表一个透明度是 255(不透明),颜
色是红色的一种颜色。如果你知道点绘图技巧就很容易用这个去写 呵呵~。同时我们还能看
到 gdi+过程是传址的,把 pen 传进去。为什么不用函数传出来呢?因为函数要传出一个标识,
错误标识。一般如果成功了那么就返回的是 0(Ok)。
好,现在已经拿到笔了,接下来就是用这个笔去画线了。通过查询可知有这么个 API:
GdipDrawLine,它的 X1Y1,X2Y2 是 single 型,继续找又发现 GdipDrawLineI,它的坐标值
都是 Long 型(我们一般用不到 single,因此我们一般用 GdipDrawLineI 就行了)。根据它的
参数名字 乱猜都能猜出来哪个参数代表什么了,于是我随便写了一句:GdipDrawLineI
graphics, pen, 10, 10, 200, 100。注意:你需要把 graphics 和 pen 传进去,否则怎么画呢?不
告诉它画在哪里~~,后面 4 个参数分别对应:起始点 X、起始点 Y、终点 X、终点 Y 的坐
标。当然扫地工作也要做好,删除 pen 的语句是 GdipDeletePen;参数很简单,传 pen 进去
综合起来,于是我们有了第一段真正绘制的 GDI+ VB6 程序,虽然它只画了一条线:
Option Explicit
Dim graphics As Long
Dim pen As Long
Private Sub Form_Load()
InitGDIPlus
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
GdipCreateFromHDC Me.hDC, graphics
GdipCreatePen1 &HFFFF0000, 1, UnitPixel, pen
GdipDrawLineI graphics, pen, 10, 10, 200, 100
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeletePen pen '删除这个笔(pen)
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
OK,F5 运行。红线没有出来?^_^……注意了 我们是在 Load 中绘制的。GDI+绘制与 VB
自己语句绘制一样。我们需要让他自动重绘(窗体的 AutoRedraw=True)或者放到 Paint 里
顺便说一下,如果你不是在 Load 事件中绘制的东西,并且 Form的 AutoRedraw 是 True,那
么别忘记全部画完后 Refresh(例如 Me.Refresh)一下~!不然不会出现直到重绘时(例如曾被
终于……哈,一条红色的斜线出现了!
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
VB6 GDI+  入门教程[3]  笔、刷子、矩形、椭圆绘制
好,我们已经学会如何画线了,那么后面的事情只要变通下都可以解决。不过变通前我还是
得说几个基本的东西。
1.绘制,填充一个矩形
绘制一个整型长度的矩形,我们要用到 GdipDrawRectangleI 和 GdipFillRectangleI。前者用
pen 画一个轮廓边框,后者用 brush 刷出一个填充区域。当然接下来就是如何创建刷子的问
题了。GDI+中有多种刷子,有纯色刷子(创建:GdipCreateSolidFill),有渐变刷子(创建:
GdipCreateLineBrush),还有纹理刷子,贴图刷子,路径刷子等等…………它们用于不同的
(1)绘制一个矩形边框
首先,我们需要一个 pen。
第一步,Dim!当然,我这样写了:Dim pen As Long;
第二步,创建一个红色的 pen(线的粗细是 1px):GdipCreatePen1 &HFFFF0000, 1, UnitPixel,
pen 创好了,接下来画矩形。这里我们用 GdipDrawRectangleI 来画矩形。画矩形跟画线可不
一样,虽然指定坐标的都是 4 个参数,但是矩形里面四个参数分别是:X,Y,长,宽。OK,综
合一下,代码如下:
Option Explicit
Dim graphics As Long
Dim pen As Long
Private Sub Form_Load()
InitGDIPlus
GdipCreateFromHDC Me.hDC, graphics
GdipCreatePen1 &HFFFF0000, 1, UnitPixel, pen
GdipDrawRectangleI graphics, pen, 30, 30, 100, 100
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeletePen pen
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
现在我们就绘制了一个 100*100 的红色矩形边框。很简单吧,变通就是这样的。
(2)创建纯色刷子
任何刷子包括其它的 GDI+元素基本上都是一个思路:我们首先要 Dim 一个 long 型变量储
存刷子/其它元素的地址,然后再调用 GDI+相关函数去创建出指定刷子/其它元素。现在来
创建一个蓝色,透明度为&HAA 的刷子,那么代码就是这样:
Dim brush As Long
GdipCreateSolidFill &HAA0000FF, brush
刷子就这样拿到了。当然不要忘记扫地工作:GdipDeleteBrush brush。
(3)用刷子填充一个矩形
很明显,函数里面找一下就会发现我们要的函数:GdipFillRectangleI。它与 DrawRectangleI
很类似,只不过把 pen 变成了 brush,因为现在要刷上去嘛- -。这一步也是很好变通的。把
前面的一翻整理之后我们得到了一个绘制矩形并填充(不如说先填充再画边框,至于原因你
可以自己颠倒一下顺序看下结果)的代码(注意 填充色是有透明度的):
Option Explicit
Dim graphics As Long
Dim pen As Long, brush As Long
Private Sub Form_Load()
InitGDIPlus
GdipCreateFromHDC Me.hDC, graphics
GdipCreatePen1 &HFFFF0000, 1, UnitPixel, pen
GdipCreateSolidFill &HAA0000FF, brush
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
GdipFillRectangleI graphics, brush, 30, 30, 100, 100
GdipDrawRectangleI graphics, pen, 30, 30, 100, 100
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeletePen pen
GdipDeleteBrush brush
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
一样很简单吧!GDI+就是那么简单,只要懂了它的“工作机制”~!
(4)渐变刷子
渐变色很 Cool,纯 VB 代码却要很多,还好,GDI+有一个方便的渐变刷子函数
——GdipCreateLineBrush。看参数,发现不一样:
Function GdipCreateLineBrush(Point1 As POINTF, Point2 As POINTF, Color1 As Long, Color2
As Long, WrapMode As WrapMode, LineGradient As Long) As GpStatus
虽然复杂。。不过又很容易理解:Point1 是一个 PointF 结构,它储存了坐标的 X,Y(浓缩哈),
代表起始位置…………咿,这是刷子啊,怎么也有起始、中止……?其实呢,这是渐变的起
始、中止位置。不过一般情况下我们的起始中止位置是和绘制的图形一致的。Point2 一样,
代表了终点。渐变就在这两个点中“展开”。注意咯,现在是坐标点,不是长宽值啦!Color1
自然就是起始颜色,Color2 嘛 第二颜色。WrapMode 就是填充方向,最后一个参数自然就
是传回 brush 咯。
于是我们又开始写程序了,这次是创建一个蓝色>红色,纵向的刷子。绘制图形免去,如果
想看效果请自己添加 drawrectangle(如果还要使用 point 画矩形请注意啦,rectangle 里面 后
面参数是接受长宽,而刷子里面接受的是点……知道区别和解决方法了么?减呗!)……,
这主要让你知道刷子的“运作模式”呵呵。
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
Dim brush As Long
Dim p1 As POINTF, p2 As POINTF
p1.X = 10
p1.Y = 10
p2.X = 100
p2.Y = 100
GdipCreateLineBrush p1, p2, &HFF0000FF, &HFFFF0000, WrapModeTileFlipy, brush
2.绘制椭圆
椭圆,想想也不会跟 rectangle 画法相差到哪里去。事实的确如此。下面就是一个绘制渐变
椭圆的代码,解释免了吧,应该是很容易理解的。
Option Explicit
Dim graphics As Long
Dim brush As Long
Private Sub Form_Load()
InitGDIPlus
GdipCreateFromHDC Me.hDC, graphics
Dim p1 As POINTF, p2 As POINTF
p1.X = 10
p1.Y = 10
p2.X = 100
p2.Y = 50
GdipCreateLineBrush p1, p2, &H8AFF00FF, &HFFFF0000, WrapModeTileFlipXY, brush
GdipFillEllipseI graphics, brush, p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.X '注意:类似的,绘制椭
圆边框的语句是 GdipDrawEllipseI
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeleteBrush brush
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
3.反锯齿功能
不知你有没有发现,画出来的椭圆是很不圆滑的(虽然用 VB 自己绘制也是如此)。如此强
大的 GDI+怎么可能没有圆滑的功能呢?有!函数是 GdipSetSmoothingMode。我们需要把它
加在绘制内容之前。一般我们把它加在创建好 graphics 之后(注意:它是作用于 graphics 的,
因此请不要还没初始化 graphics 就设置 graphics 的光滑属性- -)。经过一翻调整,我们得出
了一个设置圆滑的语句:
GdipSetSmoothingMode graphics,SmoothingModeAntiAlias
模式自然要设置成 AntiAlias,AntiAlias 顾名思义就是反锯齿(消除锯齿)。现在我们把这句话
加到前面的椭圆程序中去,运行,如何,椭圆很光滑吧!同样,前面任何一个程序都可以这
样加使 gdi+画出来的东西看上去很平滑。
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
VB6 GDI+  入门教程[4]  文字绘制
1.GDI+中文字的必须要素
首先,与其它软件一样,GDI+中的文字也有格式。画文字有多种画法,但是无论如何,我
们都需要创建一个 FontFamily,这其中包含了字体类型的信息,包括字体名称、字体对齐方
式(需要设置)等等。一般的画法然后还要从这个 FontFamily 创建一个 Font,这个 Font 中
包括字体样式(粗体、斜体)、字号等等,再后来我们调用一个函数把文字用这个 Font 显示
出来~;路径画法(可以显示边框画法)则不需要创建字体,直接调用函数,字体的样式包
括在函数里面了。
可见,GDI+中文字是需要一个 FontFamily(一般是全局的),和一些 Font(各种不同样式)
以及文字组成的。
2.GDI+绘制文字
GDI+绘制文字有几种,下面将分别示例。
(1)标准画法:GdipDrawString
这是一般的画文字的办法,这种画法支持 ClearTypeGridFit(还需要用语句再设置下),需要
创建 Font。
以下是主要绘图部分(窗体):
Option Explicit
Dim graphics As Long, Brush As Long
Dim fontfam As Long, strformat As Long, curfont As Long, rclayout As RECTF
Private Sub Form_Load()
InitGDIPlus
GdipCreateFromHDC Me.hDC, graphics
GdipCreateFontFamilyFromName StrPtr("黑体"), 0, fontfam
GdipCreateStringFormat 0, 0, strformat
GdipCreateSolidFill &HFFFF0000, Brush
GdipSetStringFormatAlign strformat, StringAlignmentNear
GdipCreateFont fontfam, 15, FontStyle.FontStyleItalic, UnitPixel, curfont
GdipSetTextRenderingHint graphics, TextRenderingHintClearTypeGridFit
rclayout.Left = 100
rclayout.Top = 100
rclayout.Right = 150
rclayout.Bottom = 150
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
GdipDrawString graphics, StrPtr("Hellow world! 这是我们第一个 GDI+文字~!!"), -1, curfont,
rclayout, strformat, Brush
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeleteFontFamily fontfam
GdipDeleteStringFormat strformat
GdipDeleteFont curfont
GdipDeleteBrush Brush
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
可以看到这种画法思路是:
1.创建 FontFamily (StrPtr:获取字符串指针,这样就能支持中文了!这就是不用 TLB 的原
2.创建 stringFormat(一般也可以不创),设置样式
3.创建 Font。其中一定要注意单位问题。否则不要问我进去 14 输出的怎么不是 14px 大小文
字……这里我们字体样式也巧妙了下,虽然声明中可以改写为 As FontStyle 但是不推荐。于
是我们写就写 FontStyle.xxx 这样又可读性高,又不会出错。
4.创建 Brush(显示文字咯)
5.设置文字区域(RcLayout)
6.绘制图形
7.扫地工作
这样 完美地画出了字。
注意:rectf 中虽然是 right,bottom 但是实际上是 width height,不要被误导哟。!
(2)路径画法:GdipAddPathString
这种画法一般用于绘制旋转文字、描边的文字等等。虽然可以设置 graphics 的圆滑设置,但
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
是它画出来的文字依然不怎么清晰(相对于第一种来说)
Option Explicit
Dim graphics As Long, Brush As Long, Pen As Long
Dim fontFam As Long, strFormat As Long, strPath As Long, rclayout As RECTL
Private Sub Form_Load()
InitGDIPlus
GdipCreateFromHDC Me.hDC, graphics
GdipSetSmoothingMode graphics, SmoothingModeAntiAlias
GdipCreateFontFamilyFromName StrPtr("Verdana"), 0, fontFam
GdipCreateStringFormat 0, 0, strFormat
GdipSetStringFormatAlign strFormat, StringAlignmentNear
GdipCreateSolidFill &HFFDEDEDE, Brush
GdipCreatePen1 &HFF222222, 2, UnitPixel, Pen
rclayout.Left = 10
rclayout.Top = 10
rclayout.Right = 200
rclayout.Bottom = 150
GdipCreatePath FillModeAlternate, strPath
GdipAddPathStringI strPath, StrPtr("描边 0123"), -1, fontFam, FontStyle.FontStyleBold, 55,
rclayout, strFormat
GdipFillPath graphics, Brush, strPath
GdipDrawPath graphics, Pen, strPath
End Sub
Private Sub Form_Unload(Cancel As Integer)
GdipDeleteFontFamily fontFam
GdipDeleteStringFormat strFormat
GdipDeletePath strPath
GdipDeleteBrush Brush
GdipDeletePen Pen
GdipDeleteGraphics graphics '释放 graphics 占用的内存
TerminateGDIPlus
End Sub
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
好 回来了 我们来比较一下这个画法有什么好处。
看出来了 它可以描边……恩 我不是在上面说了嘛 它还支持旋转、合并等等。
对了 我还说过“画出来不怎么清晰”,这里好像很好嘛!其实不然。如果你把描边去掉,单
单 FillPath,并且把字号减小 比如 14,字体样式为普通,你就会发现不清晰了~!
它的过程是这样的:
1.首先前面部分和画普通文字一样 都需要创建 FontFamily 还有可选的创建字体对齐格式等
2.接下来路径画法不需要创建 Font,我们需要创建(初始化)一个路径,否则可是什么都没
3.然后我们需要把文字增加到 Path 中去。
4.我们要 FillPath 填充这个路径 或者是 DrawPath 描出这个路径。如果是实心文字自然就是
FillPath 咯
5.最后别忘了释放 Pen(如果有)和 Brush(如果有) 以及最后一个 Path。
(3)底层画法:GdipDrawDriverString
如名,底层画法。这种画法是最底层的绘制文字,底层到了……它不会自动转换字体(比如
用 Verdana 绘制中文字体就不会显示出来) 由于不常使用,这里不贴画法了。
Generated by Foxit PDF Creator © Foxit Software
http://www.foxitsoftware.com For evaluation only.
VB6 GDI+  入门教程[5]  基础绘图小结
终于……我们的基础绘图部分可以先告一段落了。什么叫基础绘图?画线、画圈圈、画方块、
画字……等等。我们来总结一下。
我们第一点就是总结 DrawXXXX 和 FillXXXX。
1.DrawXXXX:描边可以这么说 例如 DrawRectangle DrawPath。我们都需要一个 Pen(边
框)来描绘它。
2.FillXXXX:填充。例如 FillRectangle 等等。我们需要的是 Brush。
我们第二点总结平滑(反锯齿)——什么时候用 GdipSetTextRenderingHint,什么时候用
GdipSetSmoothingMode。
这里我很简单的借用前面的结论告诉你:
1.凡是你要用 DrawXXXX 或者 FillXXXX 画出来的,你要让他平滑,你就要用
GdipSetSmoothingMode
2.其它的呢看它的类型,比如文字那么就是 GdipSetTextRenderingHint……(言下之意就是还
有其它的东西哦)
我们第三点总结 Brush 和 Pen。
1.Pen 是一只笔(- -||)。用于 DrawXXXX 的。描边。你可以通过一个纯色创建 Pen
(GdipCreatePen1),也可以通过一个 Brush 创建 Pen:GdipCreatePen2(比如说纹理 Pen,
渐变 Pen 等等,不过貌似 GDI+有点 BUG)
2.Brush 呢是刷子。我们有贴图刷子,预置纹理刷子,纯色刷子,渐变刷子,路径刷子等等。
(1)贴图刷:我们会在下一章深入探讨
(2)纯色刷:我们已经用过了,很简单——给一个颜色,传回一个 Brush。
(3)渐变刷:我们也用过了,跟纯刷子差不多,给两个颜色就可以了,还有一个渐变方向~~,
当然也是传回一个 Brush
(4)路径刷:这个刷子很高级 可以实现前面的(2)和(3)的刷子以及他们不能实现的内容——我
们可以按照路径让他去渐变……还有很多其它功能。这个嘛 以后有空我也会说的 呵呵
我们第四点总结路径。
路径我们虽然只借用到了文字路径,但是如果你翻一下我提供的 API 大杂烩会发现 关于
Path 有很多有趣的东西。例如有添加直线路径,添加圆弧路径,添加曲线路径,路径合并,
路径旋转等等……很强大吧。
路径,我们需要给他一个初始化好的 Path,然后按照各种需要给它参数;最后我们要把它画
以后其它的路径东西我们有空会探讨。
最后再说下之前提过的一点:如果你发现复制了我的代码 结果东西没出来,那么请确保你
的窗体的 AutoRedraw=True。切记切记 不要忘记:)