windows编程之GDI绘图 -- 多边形绘图

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

返回值:

  1. 如果函数调用成功,返回值是非 0;

  2. 如果函数调用失败,返回值是 0。

备注:

  1. 该函数会自动连接最后一个顶点和第一个顶点,构成一个闭合的多边形 (Polyline函数不会这么做)。

  2. 该函数并不会使用和改变当前位置。


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 总共绘制多边形的数量

返回值:

  1. 如果函数调用成功,返回值是非 0;

  2. 如果函数调用失败,返回值是 0。

备注:

  1. 该函数并不会使用和改变当前位置。

SetPolyFillMode

SetPolyFillMode 函数设置多边形的填充模式,用于填充多边形。

  • API 函数原型:
int SetPolyFillMode(
  _In_  HDC hdc,
  _In_  int iPolyFillMode
);

参数解析:

参数 含义
hdc 指定设备环境句柄
iPolyFillMode 指定新的填充模式

iPolyFillMode 参数指定的填充模式可以是以下值之一:

含义
ALTERNATE 交替模式(GDI 填充每条扫描线从多边形的奇数边到偶数边之间的区域)
WINDING 螺旋模式(GDI 填充所有能够一笔完成的多边形)

返回值:

  1. 如果函数调用成功,返回值是先前的填充模式;

  2. 如果函数调用失败,返回值是 0。

备注:

  1. 在通常情况下,两种模式仅在绘制复杂、重叠的多边形才会有不同的显示(例如五角星)。

  2. 当填充模式为 ALTERNATE,GDI 填充每条扫描线从多边形的奇数边到偶数边之间的区域。也就是说,GDI 依次填充多边形的第一、第二条边之间的区域,接着填充第三、第四条边之间的区域(第二、第三条边之间的区域留空),以此类推。

  3. 当填充模式为 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 ~

猜你喜欢

转载自blog.csdn.net/a924282761/article/details/127550120