windows程序设计(十)图形基础(2)

边界框函数

边界框函数有很多,常见的边界框函数有Arc 、Ellipse 、Rectangle 、RoundRect、Chord 、Pie 。这些函数严格意义上来讲不算是画线函数。这些函数是在画线,但它们同时又填入画刷填入一个封闭区域。
上面提到的函式有一个共同特性,即它们都是依据一个矩形边界框来绘图 的。定义一个包含该物件的框,即边界框(bounding box),Windows 就在这个框内画出该物件。
最简单的函数就是Rectangle函数。

BOOL Rectangle(
  HDC hdc,
  int left,
  int top,
  int right,
  int bottom
);

点(left,top)为矩形的左上角,(right,bottom)是矩形的右下角,下图为该函数画出的矩形,矩形的边总是垂直或者平行于显示器。
在这里插入图片描述
Windows 在边界框内画图。可以将显示器想像成一个网格, 其中,每个图素都在一个网格单元内。边界框画在网格上,然后在边界框内画 矩形,下面说明了图形画出来时的样子:
在这里插入图片描述
Rectangle并不算作严格画线函数,GDI也会填入到封闭区域,只不过由于使用白色填入封闭区域内不明显。
下面是使用Rectangle函数的例子

/*
例1:Rectangle函数的使用
*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {

	HDC hdc;
	static int cxClient, cyClient;
	int i;
	PAINTSTRUCT ps;
	RECT rect;


	switch (message)
	{
	case WM_SIZE:
		cxClient = LOWORD(lparam);
		cyClient = HIWORD(lparam);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		GetClientRect(hwnd, &rect);
		Rectangle(hdc, 0, 0, 400, 400);
		EndPaint(hwnd, &ps);
		return 0;

	case WM_DESTROY:  //正在销毁窗口
					  //向消息序列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
		::PostQuitMessage(0);
		return 0;
	}
	return ::DefWindowProc(hwnd, message, wparam, lparam);
}

在这里插入图片描述
画椭圆的函数与矩形类似,画椭圆的函数为Ellipse

BOOL Ellipse(
  HDC hdc,
  int left,
  int top,
  int right,
  int bottom
);

用该函数画出的图形如下图所示:
在这里插入图片描述
如果要是画出圆角圆角矩形需要使用RoundRect 函数,函数的用法与 Rectangle、Ellipse函数类似,只不过多了两个参数:

BOOL RoundRect(
  HDC hdc,
  int left,
  int top,
  int right,
  int bottom,
  int width,
  int height
);

其中hdc、left、reight、bottom这几个参数与上面的完全一直,width参数绘制圆角的椭圆的宽度,height圆角的椭圆的高度,参数的意义如下图所示:
在这里插入图片描述Windows 使用一个小椭圆来画圆角,这个椭圆的宽为 xCornerEllipse,高为 yCornerEllipse。可以想像这个小椭圆分为了四个部分,一个象限一个,每 个刚好用在矩形的一个角上。 xCornerEllipse 和 yCornerEllipse 的值越大, 角就越明显。 如果xCornerEllipse等于xLeft与xRight的差, 且yCornerEllipse 等於 yTop 与 yBottom 的差,那么 RoundRect 函式将画出一个椭圆。
在绘制圆角矩形时,可用以下公式来计算椭圆尺寸:

xCornerEllipse = (xRight - xLeft) / 4 ;
 yCornerEllipse = (yBottom- yTop) / 4 ; 

如果看起来别扭,就让这两个参数的值相等。
剩下的Arc、Chord 和 Pie 这几个函数的参数形式都相同

Arc (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) ; 
Chord (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) ; 
Pie (hdc, xLeft, yTop, xRight, yBottom, xStart, yStart, xEnd, yEnd) ; 

使用Arc画出的线如下所示:
在这里插入图片描述
使用 Chord 函数画出的线如下所示:
在这里插入图片描述
使用Pie画出的线如下所示:
在这里插入图片描述
Windows 用一条假想的线将(xStart, yStart)与椭圆的中心连接,从该线与边界框的交点开始, Windows 按反时针方向,沿著椭圆画一条弧。Windows 还用另一条假想的线将(xEnd,yEnd)与椭圆的中心连接,在该线 与边界框的交点处,Windows 停止画弧。
下面是一个综合的小例子,对上面函数的使用:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {

	HDC hdc;
	static int cxClient, cyClient;
	PAINTSTRUCT ps;
	RECT rect;

	switch (message)
	{
	case WM_SIZE:
		cxClient = LOWORD(lparam);
		cyClient = HIWORD(lparam);
		return 0;
	case WM_PAINT:
		hdc = BeginPaint(hwnd, &ps);
		GetClientRect(hwnd, &rect);
		Rectangle(hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8);//画一个大矩形
		
		MoveToEx(hdc, 0, 0, NULL);//画交叉线
		LineTo(hdc, cxClient, cyClient);
		MoveToEx(hdc, cxClient, 0, NULL);
		LineTo(hdc, 0, cyClient);

		Ellipse(hdc, cxClient / 8, cyClient / 8, 7 * cxClient / 8, 7 * cyClient / 8);//画椭圆

		RoundRect(hdc, cxClient / 4, cyClient / 4, 3 * cxClient / 4, 3 * cyClient / 4, cxClient / 4, cyClient / 4);

		EndPaint(hwnd, &ps);
		return 0;

	case WM_DESTROY:  //正在销毁窗口
					  //向消息序列投递一个WM_QUIT消息,促使GetMessage函数返回0,结束消息循环
		::PostQuitMessage(0);
		return 0;
	}
	return ::DefWindowProc(hwnd, message, wparam, lparam);
}

运行的结果如下所示:
在这里插入图片描述

使用现有的画笔(Stock pens)

画笔样式可以是 实线、点划线或者虚线,内定装置内容中画笔为 BLACK_PEN。不管映射方式是什 么,这种画笔都画出一个图素宽的黑色实线来。windows总共提供三种画笔,分别是 WHITE_PEN 、BLACK_PEN 、NULL_PEN 。
可以使用GetStockObject 函数来获得画笔代号

hPen = GetStockObject (WHITE_PEN) ;

然后将获取的画笔装入当前内容:

SelectObject (hdc, hPen) ;

也可以使用下面的这种方法来获得:

SelectObject (hdc, GetStockObject (WHITE_PEN)) ;

参考资料:
[1]《Windows程序设计(第五版)》
[2]https://docs.microsoft.com/zh-cn/welcome-to-docs

发布了20 篇原创文章 · 获赞 0 · 访问量 747

猜你喜欢

转载自blog.csdn.net/LeavingBook/article/details/104923431
今日推荐