windows编程之GDI绘图 – 多边形绘图
多边形函数
- Polygon
- PolyPolygon
填充模式函数
- SetPolyFillMode
- GetPolyFillMode
Polygon
Polygon 函数用于绘制一个由直线相连的两个以上顶点组成的多边形。
该函数用当前画笔绘制多边形的轮廓,用当前画刷和多边形填充模式填充多边形。
- API 函数原型:
BOOL Polygon(
_In_ HDC hdc,
_In_ const POINT *lpPoints,
_In_ int nCount
);
参数解析:
参数 | 含义 |
---|---|
hdc | 指定设备环境句柄 |
lpPoints | 指向用于指定多边形顶点的 POINT结构 数组的指针 |
nCount | 指定数组中顶点的个数,此值必须大于等于 2 |
返回值:
-
如果函数调用成功,返回值是非 0;
-
如果函数调用失败,返回值是 0。
备注:
-
该函数会自动连接最后一个顶点和第一个顶点,构成一个闭合的多边形 (
Polyline
函数不会这么做)。 -
该函数并不会使用和改变当前位置。
PolyPolygon
PolyPolygon 函数用于一系列多边形。
该函数用当前画笔绘制多边形的轮廓,用当前画刷和多边形填充模式填充多边形。
该函数绘制的多边形可以重叠。
- API 函数原型:
BOOL PolyPolygon(
_In_ HDC hdc,
_In_ const POINT *lpPoints,
_In_ const INT *lpPolyCounts,
_In_ int nCount
);
参数解析:
参数 | 含义 |
---|---|
hdc | 指定设备环境句柄 |
lpPoints | 指向用于指定所有多边形顶点的 POINT结构 数组的指针 |
lpPolyCounts | 【1】 一个指向数组的指针,数组中每个元素用于指定相应多边形的顶点的数量 【2】 每个数组元素的值必须大于等于 2 |
nCount | 总共绘制多边形的数量 |
返回值:
-
如果函数调用成功,返回值是非 0;
-
如果函数调用失败,返回值是 0。
备注:
- 该函数并不会使用和改变当前位置。
SetPolyFillMode
SetPolyFillMode 函数设置多边形的填充模式,用于填充多边形。
- API 函数原型:
int SetPolyFillMode(
_In_ HDC hdc,
_In_ int iPolyFillMode
);
参数解析:
参数 | 含义 |
---|---|
hdc | 指定设备环境句柄 |
iPolyFillMode | 指定新的填充模式 |
iPolyFillMode 参数指定的填充模式可以是以下值之一:
值 | 含义 |
---|---|
ALTERNATE | 交替模式(GDI 填充每条扫描线从多边形的奇数边到偶数边之间的区域) |
WINDING | 螺旋模式(GDI 填充所有能够一笔完成的多边形) |
返回值:
-
如果函数调用成功,返回值是先前的填充模式;
-
如果函数调用失败,返回值是 0。
备注:
-
在通常情况下,两种模式仅在绘制复杂、重叠的多边形才会有不同的显示(例如五角星)。
-
当填充模式为
ALTERNATE
,GDI 填充每条扫描线从多边形的奇数边到偶数边之间的区域。也就是说,GDI 依次填充多边形的第一、第二条边之间的区域,接着填充第三、第四条边之间的区域(第二、第三条边之间的区域留空),以此类推。 -
当填充模式为
WINDING
,GDI 填充所有能够一笔完成的多边形。
代码示例
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "Gdi32.lib")
#include <windows.h>
#include <wingdi.h>
#include <cmath>
#define PI 3.1415926
#define R 400
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("NueXini");
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("Error"), szAppName, MB_ICONERROR | MB_OK);
return 0;
}
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
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;
RECT rect;
POINT star[5];
POINT starCenter;
HGDIOBJ hBrush, hOldBruch;
switch (message)
{
case WM_SIZE:
GetClientRect(hwnd, &rect);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
// 五角星 中心点
starCenter.x = (rect.right - rect.left) / 2;
starCenter.y = (rect.bottom - rect.top) / 2;
// 左上点
star[0].x = starCenter.x - (R * sin(2 * PI / 5));
star[0].y = starCenter.y - (R * cos(2 * PI / 5));
// 右上点
star[1].x = starCenter.x + (R * sin(2 * PI / 5));
star[1].y = starCenter.y - (R * cos(2 * PI / 5));
// 左下点
star[2].x = starCenter.x - (R * sin(PI / 5));
star[2].y = starCenter.y + (R * cos(PI / 5));
// 顶点
star[3].x = starCenter.x;
star[3].y = starCenter.y - R;
// 右下点
star[4].x = starCenter.x + (R * sin(PI / 5));
star[4].y = starCenter.y + (R * cos(PI / 5));
hBrush = CreateSolidBrush(RGB(255, 0, 0));
hOldBruch = SelectObject(hdc, hBrush);
SetPolyFillMode(hdc, WINDING);
Polygon(hdc, star, 5);
DeleteObject(hOldBruch);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
enjoy it ~