Windows GDI和GDI+编程实例剖析 (1)
2011-03-23 11:07
501 查看
1.基本概念
GDI在Windows中定义为Graphics Device Interface,即图形设备接口,是Windows
API(Application Programming
Interface)的一个重要组成部分。它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具体设备的细节,而只需在一
个虚拟的环境(即逻辑设备)中进行操作。它的桥梁作用体现在:
(1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。
为实现图形设备无关性,Windows
的绘图操作在一个设备描述表上进行。用户拥有自己的"逻辑坐标"系统,它独立于实际的物理设备,与"设备坐标"相对应。开发Windows应用程序时,程
序员关心的是逻辑坐标,我们在逻辑坐标系上绘图,利用GDI将逻辑窗口映射到物理设备上。
(2)GDI能检测具体设备的能力,并依据具体的设备以最优方式驱动这些设备,完成真实的显示。
GDI函数大致可分类为:设备上下文函数(如GetDC、CreateDC、DeleteDC)、
画线函数(如LineTo、Polyline、Arc)、填充画图函数(如Ellipse、FillRect、Pie)、画图属性函数(如
SetBkColor、SetBkMode、SetTextColor)、文本、字体函数(如TextOut、GetFontData)、位图函数(如
SetPixel、BitBlt、StretchBlt)、坐标函数(如DPtoLP、LPtoDP、ScreenToClient、
ClientToScreen)、映射函数(如SetMapMode、SetWindowExtEx、SetViewportExtEx)、元文件函数
(如PlayMetaFile、SetWinMetaFileBits)、区域函数(如FillRgn、FrameRgn、InvertRgn)、路径函
数(如BeginPath、EndPath、StrokeAndFillPath)、裁剪函数(如SelectClipRgn、
SelectClipPath)等。
GDI虽然使程序员得到了一定程度的解脱,但是其编程方式仍很麻烦。譬如,显示一张位图,程序员需要进行"装入位图―读取位图文件头信息―启用设备场景―调色板变换"等一连串操作。而有了GDI+,这些问题便迎刃而解了。
顾名思义,GDI+是GDI的增强版。它是微软在Windows 2000以后操作系统中提供的新接口,其通过一套部署为托管代码的类来展现,这套类被称为GDI+的"托管类接口"。GDI+主要提供了以下三类服务:
(1) 二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;
(2) 图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。
(3) 文字显示:GDI+支持使用各种字体、字号和样式来显示文本。
GDI接口是基于函数的,而GDI+是基于C++类的对象化的应用程序编程接口,因此使用起来比GDI要方便。
2.例程简述
单击此处下载本文例程源代码
。
本文后续的讲解都基于这样的一个例子工程(例程的开发环境为Visual C++6.0,操作系统为Windows XP),它是一个基于对话框的MFC应用程序,包括2个父菜单:
(1) GDI
GDI父菜单下包括一个子菜单:
ID:IDM_GDI_DRAW_LINE caption:画线
单击事件:在窗口绘制正旋曲线
(2) GDI+
DIB位图父菜单下包括两个子菜单:
a. ID:IDM_GDIP_DRAW_LINE caption:画线
单击事件:在窗口绘制正旋曲线
b. caption:新增功能,其下又包括下列子菜单:
(ⅰ)ID:IDM_Gradient_Brush caption:渐变画刷
单击事件:在窗口演示GDI+的渐变画刷功能
(ⅱ)ID:IDM_Cardinal_Spline caption:基数样条
单击事件:在窗口演示GDI+的基数样条函数功能
(ⅲ)ID:IDM_Transformation_Matrix caption:变形和矩阵对象
单击事件:在窗口演示GDI+的变形和矩阵对象功能
(ⅳ)ID:IDM_Scalable_Region caption:可伸缩区域
单击事件:在窗口演示GDI+的可伸缩区域功能
(ⅴ)ID:IDM_IMAGE caption:图像
单击事件:在窗口演示GDI+的多种图像格式支持功能
(ⅵ)ID:IDM_Alpha_Blend caption:Alpha混合
单击事件:在窗口演示GDI+的Alpha混合功能
(ⅶ)ID:IDM_TEXT caption:文本
单击事件:在窗口演示GDI+的强大文本输出能力
后续篇章将集中在对上述菜单单击事件消息处理函数的讲解,下面的代码是整个对话框类CGdiexampleDlg的消息映射:
BEGIN_MESSAGE_MAP(CGdiexampleDlg, CDialog)
//{{AFX_MSG_MAP(CGdiexampleDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDM_GDI_DRAW_LINE, OnGdiDrawLine)
ON_COMMAND(IDM_GDIP_DRAW_LINE, OnGdipDrawLine)
ON_COMMAND(IDM_Gradient_Brush, OnGradientBrush)
ON_COMMAND(IDM_Cardinal_Spline, OnCardinalSpline)
ON_COMMAND(IDM_Transformation_Matrix, OnTransformationMatrix)
ON_COMMAND(IDM_Scalable_Region, OnScalableRegion)
ON_COMMAND(IDM_IMAGE, OnImage)
ON_COMMAND(IDM_Alpha_Blend, OnAlphaBlend)
ON_COMMAND(IDM_TEXT, OnText)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
![](http://hi.csdn.net/attachment/201103/23/0_13008495399y95.gif)
![](http://hi.csdn.net/attachment/201103/23/0_13008495538362.gif)
![](http://hi.csdn.net/attachment/201103/23/0_1300849570XxR7.gif)
![](http://hi.csdn.net/attachment/201103/23/0_1300849580kHhx.gif)
归纳可得,利用GDI进行图形、图像处理的一般操作步骤为:
1. 取得指定窗口的DC;
2. 确定使用的坐标系及映射方式;
3. 进行图形、图像或文字处理;
4. 释放所使用的DC。
4.GDI+编程
"GDI+"菜单下的"画线"子菜单单击事件消息处理函数的代码如下:
由于我们使用的是Visual
C++6.0而非VS.Net,我们需要下载微软的GDIPLUS支持包。在微软官方网站下载时需认证Windows为正版,我们可从这个地址下
载:http://www.codeguru.com/code/legacy/gdi/GDIPlus.zip。一个完整的GDI+支持包至少包括如下
文件:
(1)头文件:gdiplus.h
(2)动态链接库的.lib文件:gdiplus.lib
(3)动态链接库的.dll文件:gdiplus.dll
少了(1)、(2)程序不能编译,少了(3)程序能以共享DLL的方式编译但是不能运行,运行时找不到.dll文件。
为使得Visual C++6.0支持GDI+,我们需要在使用GDI+对象的文件的开头添加如下代码:
在Visual C++中使用GDI+必须先进行GDI+的初始化,我们在CWinApp派生类的InitInstance函数中进行此项工作是最好的:
单击"GDI+"菜单下的"画线"子菜单,也会出现如图1所示的效果。观察void CGdiexampleDlg::OnGdipDrawLine() 函数,我们发现用GDI+进行图形、图像操作的步骤为:
(1)创建 Graphics 对象:Graphics 对象表示GDI+绘图表面,是用于创建图形图像的对象;
(2)使用 Graphics 对象绘制线条和形状、呈现文本或显示与操作图像。
Graphics 对象是GDI+的核心,GDI中设备上下文dc和Graphics
对象的作用相似,但在GDI中使用的是基于句柄的编程模式,而GDI+中使用的则是基于对象的编程模式。Graphics封装了GDI+
绘图面,而且此类无法被继承,它的所有成员函数都不是虚函数。
下面,我们来逐个用实际代码实现GDI+的新增功能,这些新增功能包括:渐变的画刷(Gradient
Brushes)、基数样条函数(Cardinal Splines)、持久的路径对象(Persistent Path
Objects)、变形和矩阵对象(Transformations &Matrix Object)、可伸缩区域(Scalable
Regions)、Alpha混合(Alpha Blending)和丰富的图像格式支持等。
GDI在Windows中定义为Graphics Device Interface,即图形设备接口,是Windows
API(Application Programming
Interface)的一个重要组成部分。它是Windows图形显示程序与实际物理设备之间的桥梁,GDI使得用户无需关心具体设备的细节,而只需在一
个虚拟的环境(即逻辑设备)中进行操作。它的桥梁作用体现在:
(1)用户通过调用GDI函数将逻辑空间的操作转化为具体针对设备驱动程序的调用。
为实现图形设备无关性,Windows
的绘图操作在一个设备描述表上进行。用户拥有自己的"逻辑坐标"系统,它独立于实际的物理设备,与"设备坐标"相对应。开发Windows应用程序时,程
序员关心的是逻辑坐标,我们在逻辑坐标系上绘图,利用GDI将逻辑窗口映射到物理设备上。
(2)GDI能检测具体设备的能力,并依据具体的设备以最优方式驱动这些设备,完成真实的显示。
GDI函数大致可分类为:设备上下文函数(如GetDC、CreateDC、DeleteDC)、
画线函数(如LineTo、Polyline、Arc)、填充画图函数(如Ellipse、FillRect、Pie)、画图属性函数(如
SetBkColor、SetBkMode、SetTextColor)、文本、字体函数(如TextOut、GetFontData)、位图函数(如
SetPixel、BitBlt、StretchBlt)、坐标函数(如DPtoLP、LPtoDP、ScreenToClient、
ClientToScreen)、映射函数(如SetMapMode、SetWindowExtEx、SetViewportExtEx)、元文件函数
(如PlayMetaFile、SetWinMetaFileBits)、区域函数(如FillRgn、FrameRgn、InvertRgn)、路径函
数(如BeginPath、EndPath、StrokeAndFillPath)、裁剪函数(如SelectClipRgn、
SelectClipPath)等。
GDI虽然使程序员得到了一定程度的解脱,但是其编程方式仍很麻烦。譬如,显示一张位图,程序员需要进行"装入位图―读取位图文件头信息―启用设备场景―调色板变换"等一连串操作。而有了GDI+,这些问题便迎刃而解了。
顾名思义,GDI+是GDI的增强版。它是微软在Windows 2000以后操作系统中提供的新接口,其通过一套部署为托管代码的类来展现,这套类被称为GDI+的"托管类接口"。GDI+主要提供了以下三类服务:
(1) 二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;
(2) 图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。
(3) 文字显示:GDI+支持使用各种字体、字号和样式来显示文本。
GDI接口是基于函数的,而GDI+是基于C++类的对象化的应用程序编程接口,因此使用起来比GDI要方便。
2.例程简述
单击此处下载本文例程源代码
。
本文后续的讲解都基于这样的一个例子工程(例程的开发环境为Visual C++6.0,操作系统为Windows XP),它是一个基于对话框的MFC应用程序,包括2个父菜单:
(1) GDI
GDI父菜单下包括一个子菜单:
ID:IDM_GDI_DRAW_LINE caption:画线
单击事件:在窗口绘制正旋曲线
(2) GDI+
DIB位图父菜单下包括两个子菜单:
a. ID:IDM_GDIP_DRAW_LINE caption:画线
单击事件:在窗口绘制正旋曲线
b. caption:新增功能,其下又包括下列子菜单:
(ⅰ)ID:IDM_Gradient_Brush caption:渐变画刷
单击事件:在窗口演示GDI+的渐变画刷功能
(ⅱ)ID:IDM_Cardinal_Spline caption:基数样条
单击事件:在窗口演示GDI+的基数样条函数功能
(ⅲ)ID:IDM_Transformation_Matrix caption:变形和矩阵对象
单击事件:在窗口演示GDI+的变形和矩阵对象功能
(ⅳ)ID:IDM_Scalable_Region caption:可伸缩区域
单击事件:在窗口演示GDI+的可伸缩区域功能
(ⅴ)ID:IDM_IMAGE caption:图像
单击事件:在窗口演示GDI+的多种图像格式支持功能
(ⅵ)ID:IDM_Alpha_Blend caption:Alpha混合
单击事件:在窗口演示GDI+的Alpha混合功能
(ⅶ)ID:IDM_TEXT caption:文本
单击事件:在窗口演示GDI+的强大文本输出能力
后续篇章将集中在对上述菜单单击事件消息处理函数的讲解,下面的代码是整个对话框类CGdiexampleDlg的消息映射:
BEGIN_MESSAGE_MAP(CGdiexampleDlg, CDialog)
//{{AFX_MSG_MAP(CGdiexampleDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(IDM_GDI_DRAW_LINE, OnGdiDrawLine)
ON_COMMAND(IDM_GDIP_DRAW_LINE, OnGdipDrawLine)
ON_COMMAND(IDM_Gradient_Brush, OnGradientBrush)
ON_COMMAND(IDM_Cardinal_Spline, OnCardinalSpline)
ON_COMMAND(IDM_Transformation_Matrix, OnTransformationMatrix)
ON_COMMAND(IDM_Scalable_Region, OnScalableRegion)
ON_COMMAND(IDM_IMAGE, OnImage)
ON_COMMAND(IDM_Alpha_Blend, OnAlphaBlend)
ON_COMMAND(IDM_TEXT, OnText)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
![](http://hi.csdn.net/attachment/201103/23/0_13008495399y95.gif)
![](http://hi.csdn.net/attachment/201103/23/0_13008495538362.gif)
![](http://hi.csdn.net/attachment/201103/23/0_1300849570XxR7.gif)
![](http://hi.csdn.net/attachment/201103/23/0_1300849580kHhx.gif)
归纳可得,利用GDI进行图形、图像处理的一般操作步骤为:
1. 取得指定窗口的DC;
2. 确定使用的坐标系及映射方式;
3. 进行图形、图像或文字处理;
4. 释放所使用的DC。
4.GDI+编程
"GDI+"菜单下的"画线"子菜单单击事件消息处理函数的代码如下:
void CGdiexampleDlg::OnGdipDrawLine() { // TODO: Add your command handler code here CClientDC dc(this); //逻辑坐标与设备坐标变换 CRect rect; GetClientRect(&rect); dc.SetMapMode(MM_ANISOTROPIC); dc.SetWindowOrg(0, 0); dc.SetWindowExt(rect.right, rect.bottom); dc.SetViewportOrg(0, rect.bottom / 2); dc.SetViewportExt(rect.right, - rect.bottom); //创建Graphics对象 Graphics graphics(dc); //创建pen Pen myPen(Color::Red); myPen.SetWidth(1); //画正旋曲线 for (int i = 0; i < rect.right; i++) { graphics.DrawLine(&myPen, i, 100 *sin(2 *(i / (rect.right / 5.0)) *PI), i + 1, 100 *sin(2 *((i + 1) / (rect.right / 5.0)) *PI)); } //画X轴 myPen.SetColor(Color::Blue); graphics.DrawLine(&myPen, 0, 0, rect.right, 0); } |
C++6.0而非VS.Net,我们需要下载微软的GDIPLUS支持包。在微软官方网站下载时需认证Windows为正版,我们可从这个地址下
载:http://www.codeguru.com/code/legacy/gdi/GDIPlus.zip。一个完整的GDI+支持包至少包括如下
文件:
(1)头文件:gdiplus.h
(2)动态链接库的.lib文件:gdiplus.lib
(3)动态链接库的.dll文件:gdiplus.dll
少了(1)、(2)程序不能编译,少了(3)程序能以共享DLL的方式编译但是不能运行,运行时找不到.dll文件。
为使得Visual C++6.0支持GDI+,我们需要在使用GDI+对象的文件的开头添加如下代码:
#define UNICODE #ifndef ULONG_PTR #define ULONG_PTR unsigned long* #endif #include "c:/gdiplus/includes/gdiplus.h" using namespace Gdiplus; #pragma comment(lib, "c://gdiplus//lib//gdiplus.lib") |
///////////////////////////////////////////////////////////////////////////// // CGdiexampleApp initialization BOOL CGdiexampleApp::InitInstance() { AfxEnableControlContainer(); // Standard initialization #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif //初始化gdiplus的环境 GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; // 初始化GDI+. GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); CGdiexampleDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK){} else if (nResponse == IDCANCEL){} //关闭gdiplus的环境 GdiplusShutdown(gdiplusToken); return FALSE; } |
(1)创建 Graphics 对象:Graphics 对象表示GDI+绘图表面,是用于创建图形图像的对象;
(2)使用 Graphics 对象绘制线条和形状、呈现文本或显示与操作图像。
Graphics 对象是GDI+的核心,GDI中设备上下文dc和Graphics
对象的作用相似,但在GDI中使用的是基于句柄的编程模式,而GDI+中使用的则是基于对象的编程模式。Graphics封装了GDI+
绘图面,而且此类无法被继承,它的所有成员函数都不是虚函数。
下面,我们来逐个用实际代码实现GDI+的新增功能,这些新增功能包括:渐变的画刷(Gradient
Brushes)、基数样条函数(Cardinal Splines)、持久的路径对象(Persistent Path
Objects)、变形和矩阵对象(Transformations &Matrix Object)、可伸缩区域(Scalable
Regions)、Alpha混合(Alpha Blending)和丰富的图像格式支持等。
相关文章推荐
- Windows GDI和GDI+编程实例剖析[转]
- Windows GDI和GDI+编程实例剖析
- Windows GDI和GDI+编程实例剖析(1)
- Windows GDI和GDI+编程实例剖析
- Windows GDI和GDI+编程实例剖析(1)
- Windows GDI和GDI+编程实例剖析(1)
- Windows GDI和GDI+编程实例剖析 (2)
- Windows GDI和GDI+编程实例剖析
- Windows GDI和GDI+编程实例剖析
- Windows GDI和GDI+编程实例剖析(2)
- Windows GDI和GDI+编程实例剖析(3)
- Windows GDI和GDI+编程实例剖析
- MFC之GDI GDI+ 编程实例剖析
- Windows GDI和GDI+区别(实例剖析)
- Windows GDI和GDI+区别(实例剖析)
- GDI和GDI+编程实例剖析
- GDI和GDI+编程实例剖析
- GDI和GDI+编程实例剖析
- Windows GDI和GDI+区别(实例剖析)
- Windows GDI和GDI+编程实例剖析(2)