GDI-贝塞尔曲线 的例子

本文介绍了如何使用Windows API和数学函数实现贝塞尔曲线绘制,并通过窗口事件处理用户输入来调整曲线形状。通过事件监听和绘图函数,实现了响应鼠标点击和移动操作来实时更新和显示曲线,为用户提供直观的图形艺术创作体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

#include <Windows.h>
#include <math.h>

#define  NUM 1000
#define  TWOPI (2*3.14159)


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 WindowProc(
 HWND hwnd,      // handle to window
 UINT uMsg,      // message identifier
 WPARAM wParam,  // first message parameter
 LPARAM lParam   // second message parameter
 )
{
 int cxClient,cyClient;
 HDC hdc;
 
 PAINTSTRUCT ps;
 static POINT apt[4];


 switch(uMsg)
 {
 case WM_CHAR:
  {
   return 0;
  }break;
 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);


   }
  }break;
 case WM_PAINT:
  {
   //hdc = BeginPaint(hwnd,&ps);
   /*
   MoveToEx(hdc,0,cyClient/2,NULL);

   LineTo(hdc,cxClient,cyClient/2);
   for(i = 0;i<NUM;i++)
   {
    apt[i].x = i*cxClient/NUM;
    apt[i].y = (int)(cyClient /2*(1 - sin(TWOPI*i/NUM)));
   }
   Polyline(hdc,apt,NUM);
   */
   //Rectangle(hdc,cxClient/8,cyClient/8,7*cxClient/8,7*cyClient/8);
   //MoveToEx(hdc,0,0,NULL);
   //LineTo(hdc,cxClient,cyClient);
   //Ellipse(hdc,cxClient/8,cyClient/8,7*cxClient/8,7*cyClient/8);
   //Ellipse(hdc,cxClient/8,cxClient/8,cxClient,cyClient);
   //EndPaint(hwnd,&ps);

   InvalidateRect(hwnd,NULL,TRUE);

   hdc = BeginPaint(hwnd,&ps);

   DrawBezier(hdc,apt);

   EndPaint(hwnd,&ps);

 


  }break;
 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;

  }break;
 case WM_DESTROY:
  PostQuitMessage(0);
 default:
  return DefWindowProc(hwnd,uMsg,wParam,lParam);
 }

 return 0;
}

 

int WINAPI WinMain(
 HINSTANCE hInstance,
 HINSTANCE hPrevInstance,
 LPSTR  lpCmdLine,
 int nShowCmd )
{
 //配置属性
 WNDCLASS wndclass;

 wndclass.cbClsExtra = 0;
 wndclass.cbWndExtra = 0;
 //窗体背景
 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 //鼠标样式
 wndclass.hCursor = LoadCursor(NULL,IDC_HAND);
 //窗体图标
 wndclass.hIcon = LoadIcon(NULL,IDI_WARNING);
 //窗体句柄
 wndclass.hInstance = hInstance;
 //消息处理
 wndclass.lpfnWndProc = WindowProc;

 wndclass.lpszClassName = "Magic";

 wndclass.lpszMenuName = NULL;

 wndclass.style = CS_VREDRAW|CS_HREDRAW;

 RegisterClass(&wndclass);
 
 HWND hwnd = CreateWindow("Magic","图片艺术",WS_OVERLAPPEDWINDOW,
  0,0,600,400,NULL,NULL,hInstance,NULL);

 ShowWindow(hwnd,SW_SHOWNORMAL);

 UpdateWindow(hwnd);

 MSG msg;

 BOOL  flag = 0;

 while((flag = GetMessage(&msg,NULL,0,0))!=0)
 {
  if(flag ==-1)
  {
  
  }
  else
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
 }

 return msg.wParam;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值