CSDN博客

img winne_ll

GDI+编程简介

发表于2004/7/9 8:48:00  2166人阅读

1.引言
GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,并添加了许多新的功能。
作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需调用GDI+库输出的类的一些方法即可完成图形操作,真正的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相互隔离.从而使开发人员编写设备无关的应用程序变得非常容易.
 
2.GDI+新增功能
(1)渐变的画刷(Gradient Brushes)
GDI+允许用户创建一个沿路径或直线渐变的画刷,来填充外形(shapes),路径(paths),区域(regions),渐变画刷同样也可以画直线、曲线、路径,当你用一个线形画刷填充一个外形(shapes)时,颜色就能够沿外形逐渐变化。
 
(2)基数样条函数(Cardinal Splines)
GDI+支持基数样条函数,而GDI不支持。基数样条是一组单个曲线按照一定的顺序连接而成的一条较大曲线。样条由一系列点指定,并通过每一个指定的点。由于基数样条平滑地穿过组中的每一个点(不出现尖角),因而它比用直线连接创建的路径更精确。下面是分别使用两种方法创建的图形,一个使用基数样条,一个使用直线。
 
(3)持久路径对象Persistent Path Objects
在GDI中,路径属于设备描述表(DC),画完后路径就会被破坏。在GDI+中,绘图工作由Graphics对象来完成,你可以创建几个与Graphics分开的路径对象,绘图操作时路径对象不被破环,这样你就可以多次使用同一个路径对象画路径了。
(4)变形和矩阵对象Transformations & Matrix Object
GDI+提供了矩阵对象,一个非常强大的工具,使得编写图形的旋转、平移、缩放代码变得非常容易。一个矩阵对象总是和一个图形变换对相联系起来,比方说,路径对象(PATH)有一个Transform方法,它的一个参数能够接受矩阵对象的地址,每次路径绘制时,它能够根据变换矩阵绘制。下面的图形是一个图形变换前后的例子,变换按照先缩放后旋转完成。
 
(5)可伸缩区域 Scalable Regions
GDI+ 在区域(regions)方面对GDI进行了改进,在GDI中,Regions存储在设备坐标中,对Regions 唯一可进行图形变换的操作就是对区域进行平移。而GDI+用世界坐标存储区域(Regions),允许对区域进行任何图形变换(譬如如图所示的缩放),图形变换以变换矩阵存储,下面例子是一个区域变换前后的例子(缩放、旋转、平移)
 
(6)Alpha Blending(混合)
你可能会注意到上面显示的图形,红色未平移区域与变换后区域有一部分交叉区域,这一部分形成的梦幻效果就是由GDI+支持的Alpha Blending(混合)实现的,利用alpha融合,你可以指定填充颜色的透明度,透明颜色与背景色相互融合,填充色越透明,背景色显示越清晰,下图所示的四个椭圆被填充了同样的颜色,但由于拥有不同的透明度而呈现不同的显示效果。
 
(7)多种图像格式支持.
图像在图形界面程序中占有举足轻重的地位,GDI+除了支持BMP等GDI支持的图形格式外,还支持JPEG(Joint Photographic Experts Group)、GIF(Graphics Interchange Format)、PNG(Exchangeable Image File)、EXIF(Portable Network Graphics)、TIFF(Tag Image File Format)等图像格式,你可以直接在程序中使用这些图片文件,而无需考虑它们所用压缩算法。
(8)其它。
GDI+还将支持其它技术,譬如重新着色、颜色校正、元数据、图形容器,也许这些功能我们会在将来的WindowsXP或者Microsoft VisualStudio。Net中看到. 


3.编程模式的改变

 Device Contexts(设备描述表), Handles(句柄), 和 Graphics Objects(图形对象)
如果你曾经使用过GDI编写过应用程序,你肯定对设备描述表(DC)的概念非常熟悉,设备描述表是Windows使用的一个数据结构,用于存储具体设备能力和与如何在设备上重绘一些项目的有关属性信息。而且视频设备的设备描述表还与特定的窗口有关。首先你必须获得一个设备描述表句柄,然后在图形绘制时,你把这个句柄作为一个参数传递给GDI图形绘制函数。当然你也可以把它传递给获得或设置设备描述表有关属性的函数。
利用GDI+函数,你不必使用句柄或者设备描述表。相反,你可以简单地创建一个图形对象(Graphics),然后以你熟悉的面向对象的编程方式调用它的方法即可,譬如myGraphicsObject.DrawLine(parameters)。Graphics对象是GDI+的核心,正如设备描述表是GDI的核心一样,设备描述表(DC)和图形对象(Graphics)在不同的环境下扮演着同样的角色,发挥着类似的作用,但是两者也存在着这质的不同。前者使用基于句柄的编程方法而后者使用面向对象的编程方法。
图形对象和设备对象一样,与屏幕的显示窗口有关,它包含着与项目重绘有关的属性信息(譬如平滑度),然而图形对象并没有像GDI那样与Pen(画笔)、Path(路径)、Image(图像)、Font(字体)等搅在一起。在GDI中,所有与绘图有关的绘图对象必须选入指定设备描述表中(使用SelectObject函数),才能被指定的设备描述表所使用。而在GDI+中,你只需把这些绘图对象作为一个参数传递给图形对象Graphics方法调用即可,每一个图形对象所使用的绘图工具至于它调用方法使用的参数有关,它可以通过参数使用多种Pen和Brush绘图,而不是与特定的笔和画刷联系在一起。
下面的代码分别用两种方法实现红线的绘制,其中线宽3,起点(20,10),终点(200,100)
GDI
HDC hdc;
PAINTSTRUCT ps;
HPEN hPen;

hdc = BeginPaint(hWnd, &ps); 获得设备句柄,开始绘制
hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));创建红色画笔,宽3
SelectObject(hdc, hPen); 选入设备描述表
MoveToEx(hdc, 20, 10, NULL); 画线
LineTo(hdc, 200, 100);
EndPaint(hWnd, &ps); 结束绘制
GDI+
HDC hdc;
PAINTSTRUCT ps;
Pen* myPen;
Graphics* myGraphics;

hdc = BeginPaint(hWnd, &ps);
myPen = new Pen(0xffff0000, 3); 创建一个笔,宽3,红色
myGraphics = new Graphics(hdc); 利用设备句柄创建图形对象
myGraphics->DrawLine(myPen, 20, 10, 200, 100);调用图形对象画线的方法
EndPaint(hWnd, &ps);
四 如何使用GDI+
GDI+并不是Windows XP的专利,它同样可以在其它Windows操作系统下使用(不包括Win3.X),包括64位的Windows版本,按照微软官方的话说,GDI+支持所有基于Windows的应用程序。你只要把GDIPlus.dll拷入Windows的系统目录,即可使用需要GDI+支持的应用程序。Microsoft Visual C#全面支持GDI+,Microsoft Visual C++.net
使用GDI+有两种方法,一种方法是通过托管(managed )的应用程序实现,另一种方法是在非托管项目中借助于调用C++面向对象类实现。
下面是一个基于Win32 SDK的窗口程序。使用要包含GDIplus.h头文件,连接设置要包含GdiPlus.lib库文件。
#define UNICODE
#include 
#include 
using namespace Gdiplus;
 
void OnPaint(HWND hWnd)
{
HDC hdc;
PAINTSTRUCT ps;
 
hdc = BeginPaint(hWnd, &ps);
 
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
 
graphics.DrawLine(&pen, 0, 0, 200, 100);
 
EndPaint(hWnd, &ps);
 
} // OnPaint
 
 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE,
PSTR szCmdLine, int iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndClass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
 
// GDI+ 初始化
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("GettingStarted");
 
RegisterClass(&wndClass);
 
hWnd = CreateWindow(
TEXT("GettingStarted"), // window class name
TEXT("Getting Started"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
 
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
 
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
 
GdiplusShutdown(gdiplusToken); 关闭GDI+
 
return msg.wParam;
 
} // WinMain
 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_PAINT:
OnPaint(hWnd);
return 0;
 
case WM_DESTROY:
PostQuitMessage(0);
return 0;
 
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
} // WndProc
 
综上所述,我们可以看出使用GDI+进行图形编程更容易,功能更强大,GDI+不仅是Microsoft Visual Studio.net的组成部分,也是WindowXP的重要组成部分,未来是GDI+的天下,GDI将逐渐退出历史舞台,这是大势所趋,不可逆转。早日锁定GDI+是你明智的选择

0 0

相关博文

我的热门文章

img
取 消
img