windows程序设计 例题解析 BEZIER.C

来源:互联网 发布:阿里云配置cdn 编辑:程序博客网 时间:2024/05/14 14:34

/*---------------------------------------
   BEZIER.C -- Bezier Splines Demo
               (c) Charles Petzold, 1998
  ---------------------------------------*/

#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 ("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))
     {
          MessageBox (NULL, TEXT ("Program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
    
     hwnd = CreateWindow (szAppName, TEXT ("Bezier Splines"),
                          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;

  return 0;
 case WM_LBUTTONDOWN: //鼠标左键按下
 case WM_RBUTTONDOWN: //鼠标右键按下
 case WM_MOUSEMOVE:   //鼠标移动

//对于这三个消息,可以参加MSDN,那里有对这些消息的说明:

//wParam表示哪些鼠标键触发了LOWORD(lParam),HIWORD(lParam);//低字节保存鼠标当前x坐标,高字节保存y坐标

  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);//低字节保存鼠标当前x坐标,高字节保存y坐标,可以重看msdn获取消息


 

//按下鼠标右键,第二个控制点起作用


    apt[1].y = HIWORD(lParam);
   }

   if(wParam & MK_RBUTTON)
   {
    apt[2].x = LOWORD(lParam);  //低字节保存鼠标当前x坐标,高字节保存y坐标,可以重看msdn获取消息
    apt[2].y = HIWORD(lParam);
   }
//重新用黑色画笔绘图
   SelectObject(hdc,GetStockObject(BLACK_PEN));
   DrawBezier(hdc,apt);  //可以把这句话注释掉,该为InvalidateRect(hwnd,NULL,TRUE);效果是一样的
   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);
}

原创粉丝点击