首页 > 代码库 > win32下的贝塞尔曲线

win32下的贝塞尔曲线

简单的利用windows api来实现的贝赛尔曲线。两个端点是固定的,垂直方向的位置为显示区域高度的一半,水平方向则分别位于显示宽度的1/4和3/4处。

两个控点可以改变,按住鼠标左键并拖动鼠标可以改变第一个控点,按住右键并拖动鼠标可以改变第二个控点。

如图:

技术分享

代码如下:

#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("贝塞尔曲线");    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("这个程序需要运行在Windows NT下!"), szAppName, MB_ICONERROR);        return 0;    }    hwnd = CreateWindow(szAppName,        TEXT("贝塞尔曲线!"),        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;}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){    static POINT apt[4];    HDC hdc;    int cxClient, cyClient;    PAINTSTRUCT ps;    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 / 2;        apt[1].y = cyClient / 4;        apt[2].x = cxClient / 2;        apt[2].y = 3 * cyClient / 4;        apt[3].x = 3 * cxClient / 4;        apt[3].y = cyClient / 2;    case WM_LBUTTONDOWN:    case WM_RBUTTONDOWN:    case WM_MOUSEMOVE:        if (wParam & MK_LBUTTON || wParam && MK_RBUTTON)        {            hdc = GetDC(hwnd);            SelectObject(hdc, GetStockObject(WHITE_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(BLACK_PEN));            DrawBezier(hdc, apt);            ReleaseDC(hwnd, hdc);        }        return 0;    case WM_PAINT:        InvalidateRect(hwnd, NULL, TRUE);        hdc = BeginPaint(hwnd, &ps);        DrawBezier(hdc, apt);        EndPaint(hwnd, &ps);        return 0;    case WM_DESTROY:        PostQuitMessage(0);        return 0;    }    return DefWindowProc(hwnd, message, wParam, lParam);}

 

win32下的贝塞尔曲线