Article From:https://www.cnblogs.com/yenyuloong/p/9121522.html

## Bezier Spline curve

Bezier Splines are defined by four points: two endpoints (starting points and endpoints) and two control points (used to bend them to varying degrees).

## Drawing Bezier spline curve

The Bezier spline curve can be drawn by using PolyBezier function and PolyBezierTo function.

```BOOL PolyBezier(
HDC hdc,            // Device environment handle
CONST POINT* lppt,  // The endpoints and control points (the order is the starting point, the first control point, the second control point, the end point).
DWORD cPoints       // The total number of endpoints and points of control
);```
```BOOL PolyBezierTo(
HDC hdc,            // Device environment handle
CONST POINT *lppt,  // The end points and control points (the order is the first control point, the second control point, the end point).
DWORD cCount        // The total number of endpoints and points of control
);```

Note: the PolyBezierTo function takes the current position as the starting point, so only three other points are given. When the function returns, the current position will be set to the end.

## BEZIER Sample program

```#include <windows.h>

void DrawBezier(HDC hdc, POINT apt[]) {
PolyBezier(hdc, apt, 4);

MoveToEx(hdc, apt[0].x, apt[0].y, NULL);
LineTo(hdc, apt[1].x, apt[1].y);

MoveToEx(hdc, apt[2].x, apt[2].y, NULL);
LineTo(hdc, apt[3].x, apt[3].y);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {

HDC hdc;
PAINTSTRUCT ps;
static int cxClient, cyClient;
static POINT apt[4];

switch (message) {
case WM_SIZE:

cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);

apt[0].x = cxClient / 4;
apt[0].y = cyClient / 2;

apt[1].x = cxClient * 4 / 8;
apt[1].y = cyClient / 4;

apt[2].x = cxClient * 4 / 8;
apt[2].y = cyClient * 3 / 4;

apt[3].x = cxClient * 3 / 4;
apt[3].y = cyClient / 2;

return 0;

case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON || wParam & MK_RBUTTON) {
hdc = GetDC(hwnd);

SelectObject(hdc, GetStockObject(BLACK_PEN));
DrawBezier(hdc, apt);

if (wParam & MK_LBUTTON) {
apt[1].x = LOWORD(lParam);
apt[1].y = HIWORD(lParam);
}

if (wParam & MK_RBUTTON) {
apt[2].x = LOWORD(lParam);
apt[2].y = HIWORD(lParam);
}

SelectObject(hdc, GetStockObject(WHITE_PEN));
DrawBezier(hdc, apt);

ReleaseDC(hwnd, hdc);
}

return 0;

case WM_PAINT:
InvalidateRect(hwnd, NULL, TRUE);
hdc = BeginPaint(hwnd, &ps);

SelectObject(hdc, GetStockObject(WHITE_PEN));
DrawBezier(hdc, apt);

EndPaint(hwnd, &ps);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

LPCTSTR lpszClassName = TEXT("BezierDemo");
LPCTSTR lpszWindowName = TEXT("Bezier Demo");
WNDCLASS wndclass;
HWND hwnd;
MSG msg;

wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = lpszClassName;
wndclass.style = CS_HREDRAW | CS_VREDRAW;

if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("This program requires Windows NT!"), lpszWindowName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(
lpszClassName,
lpszWindowName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}```