第五章 图形基础
图形设备接口(GDI:Graphics Device Interface)是Windows的子系统,它负责在视频显示器和打印机上显示图形。GDI的主要目的之一是支持与设备无关的图形。Windows程序应该能毫无困难地在Windows支持的任意一种图形输出设备上运行,GDI通过将您的程序和不同输出设备的特性隔离开来的方法来达到这一目的。
<1> GDI函数调用
组成GDI的几百个函数课分为几个大类:
1.获取和释放设备描述表的函数
2.获取有关设备描述表信息的函数
3.绘图函数
4.设置和获取设备描述表参数的函数
5.使用GDI对象的函数
GDI图元:直线和曲线;填充区域;位图;文本。
GDI的其他方面:映射模式和变换;元文件;区域;路径;剪裁;调色板;打印。
可用GetDeviceCaps函数获得设备描述表信息。
<2> 关于色彩
"全色"视频显示器的分辨率是每个像素24位-8位红色、8位绿色、8位蓝色。
"高彩色"显示分辨率是每个像素16位-5位红色、6位绿色、5位蓝色。
256色的视频适配器使用色彩调色板。在大多数GDI函数调用中,使用COLORREF值来表示一种色彩。COLORREF值按照红、绿和蓝色的亮度指定了一种颜色,通常叫做"RGB色彩"。
在16位或256色视频适配器上,Windows可以使用"抖动"来模拟设备能够显示的颜色之外的色彩。抖动利用了由多种色彩的像素组成的像素图案。可以调用GetNearestColor来决定与某一色彩最接近的纯色。
<3>保存设备描述表
wndclass.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;在窗口风格中加入CS_OWNDC,则基于这个窗口类所创建的每个窗口都将拥有自己的设备描述表,它一直存在,直到窗口被删除。如果使用了CS_OWNDC风格,就只需初始化设备描述表一次,可以在处理WM_CREATE消息期间完成这一操作:
case WM_CREATE:
hdc=GetDC(hwnd);
[initialize device context attributes]
ReleaseDC(hwnd,hdc);
CS_OWNDC风格只影响GetDC和BeginPaint获得的设备描述表,不影响其他函数获得的设备描述表。(如GetWindowDC)
SaveDC函数可保存改变属性之后的hdc,RestoreDC函数可恢复调用SaveDC前存在的hdc。
<4> 画点和线
1.写像素
Windows GDI包含了SetPixel和GetPixel来设置像素和获得某点像素值。
2.直线
Windows可以画直线、椭圆线和贝塞尔样条,Windows NT支持的画线函数:
LineTo:画直线
Polyline和PolylineTo:画一系列相连的线
PolyPolyline:画多组相连的线
Arc:画椭圆线
PolyBezier和PolyBezierTo:画贝塞尔样条
ArcTo和AngleArc:画椭圆线
PolyDraw:画一系列相连的线以及贝塞尔样条
下面为既画线也能填充所画图形的封闭区域的函数:
Rectangle:画矩形
Ellipse:画椭圆
RoundRect:画带圆角的矩形
Pie:画椭圆的一部分,使其看起来像一个扇形
Chord:画椭圆的一部分,以呈弓形。
设备描述表的五个属性影响着用这些函数所画线的外观:当前画笔的位置、画笔、背景方式、背景色和绘图模式。
MoveToEx和LineTo画线
GetCurrentPositionEx获得当前位置
贝塞尔样条:一条二维ideas贝塞尔样条由4个点定义-两个端点和两个控制点。曲线的端点在两个端点上,控制点就像磁石一样把曲线从两个端点间的直线处拉走。
<5> 画笔的创建、选择和删除
HPEN hPen;
hPen=GetStockObject(WHITE_PEN);
SelectObject(hdc,hPen);
如上,获得画笔句柄,并把该句柄选进设备描述表后才能使用这个画笔。SelectObject的返回值是此调用前设备描述表中的画笔句柄。
逻辑画笔是一种GDI对象,它是您可以创建的6种GDI对象之一,其他5种是刷子、位图、区域、字体和调色板。除了调色板之外,这些对象都是通过SelectObject选进设备描述表的。
在使用画笔等等GDI对象时,应该遵循三条规则:
1.最后要删除自己创建的所有GDI对象;
2.当GDI对象正在一个有效的设备描述表中时,不要删除它;
3.不要删除现有对象。
CreatePen和CreatePenIndirect函数可以创建自己的画笔,如:
static HPEN hPen;
hPen=CreatePen(PS_SOLID,1,0);
SelectObject(hdc,hPen);
[line-drawing functions]
然后可在WM_DESTROY期间,DeleteObject(hPen);若在WM_PAINT消息期间创建画笔,也可在EndPaint之前或之后删除画笔。
<6> 画刷
Windows有五个函数,可以创建逻辑画刷,然后可用SelectObject将其选进设备描述表。
CreateSolidBrush
CreateHatchBrush
CreatePatternBrush
CreateDIBPatternBrushPt
CreateBrushIndirect
<7> 设备坐标和逻辑坐标
映射方式定义了Windows如何将GDI函数中指定的逻辑坐标映射为设备坐标,这里的设备坐标系取决于您用哪个函数来获得设备描述表。
GetClientRect(hwnd,&rect); //获得客户区大小,为设备单位
DPtoLP(hdc,(POINT)&rect,2); //将设备坐标转换成逻辑坐标
LPtoDP(hdc,pPoints,iNumber);将逻辑点转换成设备点。
<8> 矩形、区域和裁剪
FillRect:用指定的画刷填充矩形,不需要先将画刷选进设备描述表
FrameRect:使用画刷画矩形框,但是不填充矩形
InvertRect:将矩形中所有像素翻转,1换成0,0换成1
PeekMessage(&msg,NULL,0,0,PM_REMOVE)可将消息从消息队列中删除,如果不希望删除消息,那最后一个参数课设置成PM_NOREMOVE。当消息队列中有一个消息时,PeekMessage返回TRUE,并按通常方式处理消息,当队列中没消息,则返回FALSE。
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;
TranslateMesage(&msg);
DispatchMessage(&msg);
}
else
{
[other program lines to do some work]
}
}
CreateRectRgn:创建矩形区域
CreateEllipticRgn:创建椭圆区域
CreateRoundRectRgn:创建圆角的矩形区域
CreatePolygonRgn:创建多边形区域
CombineRgn:将两个源区域组合起来
SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL)将原点设置到客户区的中心。
PS:下面两个链接讲述GetDC和BeginPaint的区别
http://www.quanxue.cn/JC_CLanguage/Sdk/Sdk06.html
http://hi.baidu.com/joyeep/blog/item/d60c9351daabed19367abeaf.html