3.4.2 图形绘制
3.4.1小节中讲解了如何使用画笔和画刷,在这一小节中将讲解绘图函数。同时还将结合上一小节的知识来讲解具体绘制图形的方法。比如如何使用红色的画笔来绘制一条线段。
1.点的绘制
点的绘制是图形绘制中最基本的,也可以这么说,点是组成任何图形的最基本的元素。比如圆也是由一系列的点构成的。下面看看点的绘制函数的原型:
COLORREF SetPixel( HDC hdc, int x, int y, COLORREF crColor ); |
其中(x,y)是窗口客户区内容任何一点的坐标。函数是在这个指定的(x,y)位置,使用crColor色彩绘制一个点。如果函数执行成功,那么函数返回的色彩就是绘制的点的色彩。
需要注意的是点的绘制并不需要创建画笔。原因是,点的绘制是直接将某个点设定成希望的色彩,而不是用画笔在上面绘制一个点。因此不需要创建画笔,直接给点指定色彩就可以了。
2.线条的绘制
介绍完点的绘制以后,下面来看看线条的绘制。线条是由一系列的点构成的,因此,线条的绘制函数其实就是找到这些要绘制的点,然后用画笔将它们连在一起就实现了一条线的绘制。线条的绘制函数有两个,通常情况下,这两个函数要一起使用才可以绘制出线条。下面是函数原型:
BOOL MoveToEx( HDC hdc, int x, int y, LPPOINT lpPoint ); BOOL LineTo( HDC hdc, int xEnd, int yEnd ); |
MoveToEx函数是将现在的绘图坐标移动到(x,y)处。lpPoint是一个指针,目的是在调用这个函数的时候,系统将绘图坐标移动后,将原来的坐标保存到这个参数中,方便今后修改使用。但是通常情况下,这个参数都是使用NULL,如果需要取这个值,那么可以指定一个POINT的对象给这个参数。
LineTo函数是通知系统,从当前的绘图坐标开始,向(xEnd,yEnd)坐标位置处绘制一条线段。
通常情况下,都是使用MoveToEx函数将开始坐标确定,然后再通过LineTo函数完成线条的绘制。
实例3-8:从(10,20)的位置开始向(100,90)绘制一条直线,色彩为绿色。
HWND hWnd; // 假设该句柄已经存在 HDC hDC = GetDC( hWnd ); // 创建画笔,并且选入设备环境 HPEN hPen = CreatePen( PS_SOLIC, 1, RGB( 0, 255, 0 ) ); HPEN hOld = SelectObject( hDC, hPen ); // 绘制线条 MoveToEx( hDC, 10, 20, NULL ); LineTo( hDC, 100, 90 ); // 完成绘制,恢复设备环境 SelectObject( hDC, hOld ); DeleteObject( hPen ); ReleaseDC( hWnd, hDC ); |
上面的程序是一个完整的线条绘制程序,该程序绘制了一条直线。如果将上面的程序进行扩展,就可以绘制出更加复杂的图形。例如三角形也可以通过这样的方法来绘制。当然对于多边形的绘制(三角形也是多边形中的一种),会有专门的函数来实现。
3.矩形的绘制
通过上面对线条绘制的处理,对在Windows环境下如何绘图应该有了一个比较深入的理解。在这一个部分里面将讲解矩形的绘制。下面首先来看看矩形的绘制函数原型:
BOOL Rectangle( HDC hdc, int nLeftRect, //左上角x坐标 int nTopRect, //左上角y坐标 int nRightRect, //右下角x坐标 int nBottomRect //右下角y坐标 ); |
Rectangle是使用当前选定的画笔和画刷进行矩形的绘制。在绘制矩形的时候需要指定矩形的左上角的坐标(x,y)和右下角的坐标(x,y),这样函数可以根据这两个值绘制出矩形。
除了这个函数以外,矩形的绘制还有两个专用的函数,FillRect和FrameRect,原型如下:
int FillRect( HDC hDC, CONST RECT *lprc, //需要绘制的矩形的区域坐标 HBRUSH hbr //填充使用的画刷的句柄 ); int FrameRect( HDC hDC, CONST RECT *lprc, //矩形区域 HBRUSH hbr //绘制矩形使用的画刷句柄 ); |
FillRect填充一个指定矩形时,不包括矩形的右边界和下边界,而不管当前模式如何。因此要在一个矩形中填充(10,10)和(20,20),必须传递矩形结构中的(10,10)和(21,21)的区域。
FrameRect函数只能绘制有边界的中空矩形,但不可思议的是,这个函数仅使用画刷来绘制,而不是使用画笔来绘制。
下面是使用Rectangle绘制一个矩形的代码。
实例3-9:使用红色画笔绘制矩形,并且使用蓝色画刷填充。
//创建画笔和画刷 HPEN hPen = CreatePen( PS_SOLID, 1, RGB( 255, 0, 0 ) ); HBRUSH hBrush = CreateSolidBrush( RGB( 0, 0, 255 ) ); //选入设备环境 SelectObject( hPen ); SelectObject( hBrush ); //绘制矩形 Rectangle( hDC, 20, 20, 40, 40 ); |
下面是使用FillRect函数绘制矩形的实例。
实例3-10:使用FillRect函数绘制一个矩形。
//创建画笔和画刷 HPEN hPen = CreatePen( PS_SOLID, 1, RGB( 255, 0, 0 ) ); HBRUSH hBrush = CreateSolidBrush( RGB( 0, 0, 255 ) ); //选入设备环境 SelectObject( hPen ); SelectObject( hBrush ); //绘制矩形 Rectangle( hDC, 20, 20, 40, 40 );
|
使用FrameRect绘制矩形的方法和上面的实例代码类似,这里就不举例说明了。这三个函数中最常使用的就是Rectangle函数。因为Rectangle函数也可以实现FillRect和FrameRect函数的功能。因此,对Rectangle要特别留意。
4.圆的绘制
圆看起来是一种简单的图形,但是要绘制一个圆却需要一个复杂的算法。Win32 SDK中提供了一个函数用于绘制圆,从而减少了编写圆算法的复杂度。Win32提供的圆的函数实际上是根据给定的一个矩形边界,然后在矩形内绘制这个圆。由于是根据矩形的边框来绘制的,因此这个函数实际上是绘制椭圆的函数,圆是椭圆的特例。函数原型为:
BOOL Ellipse( HDC hdc, int nLeftRect, //左上角x坐标 int nTopRect, //左上角y坐标 int nRightRect, //右下角x坐标 int nBottomRect //右下角y坐标 ); |
如果需要绘制一个圆或者椭圆,那么必须要知道其边界矩形。比如要绘制一个圆心为(20,20)、半径为5的圆,那么函数的写法为:
Ellipse( hdc,15,15,25,25 ); |
如果是要绘制一个椭圆,那么也需要知道其矩形边界。Windows会根据这个矩形得到椭圆的长、短轴,从而绘制出椭圆。比如长轴为10,短轴为5,中心还是在(20,20)处,那么函数的写法为:
Ellipse( hdc,10,15,30,25); |
从这两个例子中,可以看出在绘制圆的时候,必须要知道矩形边界,否则Windows是不能够绘制出圆的。
5.多边形的绘制
最后来讨论一下最后一种基本图形——多边形的绘制,函数原型是:
BOOL Polygon( HDC hdc, CONST POINT *lpPoints, //多边形的点集合 int nCount //点的数量 ); |
只有向Polygon()传递一个POINT的列表及其数量,就可以使用当前的画笔和画刷绘制一个闭合的多边形。下面是绘制一个多边形的实例。
实例3-11:绘制一个5个定点的多边形。假设顶点坐标分别是(10,10)、(20,20)、(30,25)、(25,35)和(10,30)。设备句柄HDC已经存在。程序代码如下:
POINT poly[5]; poly[0].x = 10; poly[0].y = 10; poly[1].x = 20; poly[1].y = 20; poly[2].x = 30; poly[2].y = 25; poly[3].x = 25; poly[3].y = 35; poly[4].x = 10 poly[4].y = 30; Polygon( hdc, poly, 5); |
多边形的绘制就是这样的容易。如果传递绘制一个非凸的多边形或者是自我封闭的多边形的点,GDI会尽最大的可能来绘制,但不能够保证绘制的和理想状态完全一致。
【责任编辑:
雪花 TEL:(010)68476606-8007】