ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

第5章,[Win32 章节] :边框绘制函数(四)

第5章,[Win32 章节] :边框绘制函数(四)

专栏导航

上一篇:第5章,[Win32 章节] :边框绘制函数(三)

回到目录

下一篇:第5章,[Win32 章节] :边框绘制函数(五)

本节前言

对于本节所讲解的知识,有可能,你会需要时不时地参考本专栏的其它文章。真的遇到了需要参考之前的文章的知识点,请你自行查阅。

我呢,也会提到一部分的参考课节。但是呢,你不应该依赖于我的主动提及。最好呢,你自己能够多去了解和查看本专栏目录。

之前的三节,我们讲了矩形的绘制。这三节,应该成为本节的先修课节。

参考课节:第5章,[Win32 章节] :边框绘制函数(一)

参考课节:第5章,[Win32 章节] :边框绘制函数(二)

参考课节:第5章,[Win32 章节] :边框绘制函数(三)

本节呢,我们来学习椭圆的绘制。圆形,我们将其看成是一种特殊的椭圆。也就是,本节讲解椭圆的绘制,实际上,它也涵盖了圆形的绘制。

一. Ellipse 函数讲解

绘制椭圆和圆形,使用的函数,叫做 Ellipse 。它的使用方法如下:

Ellipse (hdc, xLeft, yTop, xRight, yBottom);

绘制椭圆的 Ellipse 函数与绘制矩形的 Rectangle 函数,它们的参数数量与参数含义,都是一样的,只是函数名不一样而已。

绘制椭圆的示意图如下。

图1

在图1 里面,我们所绘制出来的椭圆,实际上是红色虚线所示的矩形的内接椭圆。相对地,红色虚线的矩形,它实际上就是蓝色的椭圆的外接矩形。

既然是说,红色虚线的矩形是蓝色线条的椭圆的外接矩形,那么,整个的一个椭圆,它实际上,它是可以由外接矩形来进行定位的。

也就是说,外接矩形的 x 坐标的范围若是 [x1, x2],则内接椭圆的 x 坐标的范围也是 [x1, x2] 。同理,外接矩形的 y 坐标的范围若是 [y1, y2],则内接椭圆的 y 坐标的范围也是 [y1, y2] 。

椭圆函数 Ellipse 的使用方法,我们再来看一看,如下所示:

Ellipse (hdc, xLeft, yTop, xRight, yBottom);

在上面的公式中,hdc 是设备环境句柄。我们若以客户区内部的最左侧的一列像素为 0 列像素,再往右一列是 1 号列像素,再往右一列是 2 号列像素,等等。在这种规定之下,则 xLeft 是椭圆所在的外接矩形的左边的起始像素的列号,xRight 是椭圆所在的外接矩形的右边的结束像素的右边一列像素的列号。也就是,椭圆所在的外接矩形的 x 坐标的范围,是 xLeft <= x <= (xRight - 1),xRight 是椭圆所在的外接矩形达不到的像素列号。

讲完了xLeft 和 xRight,我们再来看一看 yTop 和 yBottom 。

我们若以客户区内部最上边的一行像素为 0 行像素,则此行像素再往下一行为 1 号行像素,再往下一行为 2 号行像素,等等。在这种规定之下,则 yTop 是椭圆所在外接矩形的上边的起始像素的行号,而 yBottom 是椭圆所在的外接矩形的下边的结束像素的下一行像素的行号。也就是,椭圆所在的外接矩形的 y 坐标的范围,是 yTop <= y <= (yBottom - 1),yBottom 是椭圆所在的外接矩形达不到的像素行号。

如果,所绘制的椭圆,它的外接矩形的宽度和高度相同,则所绘制的椭圆便是一个正圆。

也就是,当满足 (xRight - xLeft) == (yBottom - yTop) 条件时,所绘制的椭圆为正圆。

还需要强调一点,用 Ellipse 绘制出来的椭圆,它不止是会画外侧的曲线,实际上,它也会填充内部。只是,默认的情况下,所使用的画刷为白色画刷,我们的程序客户区的背景画刷也是白色画刷,所以呢,现阶段的你可能注意不到椭圆内部的填充色。以后,我们在讲完画刷的时候,你会明白这一点的。

二. 程序示例

讲完了基础知识,我们还是给出来一个简单的程序示例吧。

程序代码如下。

/*------------------------------------------------------------ WinMain.cpp:绘制两个矩形。 ------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("Ellipse_Lx"); HWND hwnd; MSG msg; WNDCLASS wndclass; 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 = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("注册窗口类失败!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, // window class name TEXT("The Ellipse_Lx Program"), // 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); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int x1, x2, y1, y2; switch (message) { case WM_CREATE: return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); x1 = 60; x2 = 360; y1 = 60; y2 = 260; Ellipse(hdc, x1, y1, x2, y2); x1 = 400; x2 = 700; y1 = 60; y2 = 360; Ellipse(hdc, x1, y1, x2, y2); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }

程序应该是不难看懂的。

编译过程我就不详细写了。如果你忘了如何编译和运行程序,请参考下述课节。

参考课节:使用 VS2010 编写 C语言程序

参考课节:用 VS2019 编写C语言程序

程序的运行结果如下。

图2

结束语

本节的课程内容不难。不过呢,你仍然是需要好好地来学习的。

专栏导航

上一篇:第5章,[Win32 章节] :边框绘制函数(三)

回到目录

下一篇:第5章,[Win32 章节] :边框绘制函数(五)

返回列表