windows程序设计(7):绘制贝塞尔曲线

来源:互联网 发布:sql时间转换成字符串 编辑:程序博客网 时间:2024/05/22 06:21
#include <windows.h>#include <math.h>#define NUM 1000#define TWOPI (2*3.14159)LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);int WINAPI WinMain(HINSTANCE hInstance,//当前实例句柄   HINSTANCE hPrevInstance, //先前实例句柄   LPSTR lpCmdLine,//命令行   int iCmdShow)//显示状态{static TCHAR szAppName[] = TEXT("Bezier");//窗口句柄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)){return -1;}//创建窗口hwnd = CreateWindow(szAppName,//窗口类的名称,必须是已经注册的TEXT("贝塞尔函数"),//窗口标题WS_OVERLAPPEDWINDOW,//窗口风格CW_USEDEFAULT,//X坐标CW_USEDEFAULT,//Y坐标CW_USEDEFAULT,//宽度CW_USEDEFAULT,//高度NULL,//父窗口句柄NULL,//菜单窗口句柄hInstance,//高级版本的windos忽略NULL);//显示窗口//ShowWindow(hwnd,SW_SHOWNA);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){HDC hdc;PAINTSTRUCT ps;int i,j;static int cxClient,cyClient;static POINT apt[4] ;switch(message){case WM_SIZE:cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);//4个点分别是起点,第一控制点,第二控制点。终点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 ;return 0;case WM_LBUTTONDOWN:case WM_RBUTTONUP: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, CreatePen (PS_DASH, 0, RGB (255, 0, 0))) ;//画曲线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);}


在windows中,使用PolyBezier函数绘制贝塞尔曲线。

程序中要注意的是:WM_MOUSEMOVE下的消息处理方式:先用白色的画笔画曲线,再用黑色的画笔画曲线,这样就做出了皮筋一样的效果:第一条曲线实际上是随着鼠标运动而产生的轨迹,不是我们想要的结果,我们想要的是最后移动到位置时的曲线,所以最后才用我们自定义的笔(这里定义为红色,虚线)画图。

原创粉丝点击