本来以为暑假好好学习Windows程序设计第五版的,结果因为一些事耽误了,回到学校后,转专业后右到补修什么的,尽量抽时间来专攻吧,废话不说,开始吧
这就是贝塞尔(Bezier)样条,加上两条直线有助于理解,windows中有画Bezier样条的函数,就是PolyBezier;
不知道函数怎么用,可以查阅微软的官方帮助文档msdn,下面是msdn的解释
BOOL PolyBezier( HDC hdc, // handle to device context
CONST POINT* lppt, // endpoints and control points
DWORD cPoints // count of endpoints and control points);
windwos编程特点就是消息机制,主要是窗口过程,想到当时没接触过windows编程时,看windows程序设计第五版这本书是一头雾水,头都炸了,在这里要声明一下,感谢孙鑫老师,看了他的视频,在结合书,简直是如虎添翼啊
好了,贴上代码了
# include<windows.h>
LRESULT CALLBACK WndProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow
)
{
WNDCLASS wndclass;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//这里用NULL表示使
//用微软提供的图标
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //同上
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = TEXT("Bezier");
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndclass);//注册窗口类
HWND hwnd;
hwnd = CreateWindow(TEXT("Bezier"), TEXT("Bezier Splines"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL, hInstance, NULL);
//在窗口风格用或语句就可以加上滚动条了
//cw_usedefault表示采用系统默认的值
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
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 uMsg,
WPARAM wParam,
LPARAM lParam
)
{
static POINT apt[4];
int cxClient, cyClient;
HDC hdc;
PAINTSTRUCT ps;
switch (uMsg)
{
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:
if (wParam&MK_LBUTTON || wParam&MK_RBUTTON)//为什么要用wParam
{
hdc = GetDC(hwnd);
//当背景为白色使,用白色画笔就将上一次的用黑色画笔画的线条
DrawBezier(hdc, apt);
//擦除了,看起来的效果就是只有一条Bezier线条
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));
//鼠标移动或按下左键或右键后,用黑色画笔画Bezier样条,上一次的样条被
//白色画笔画的样条覆盖了
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_PAINT:
//InvalidateRect(hwnd, NULL, TRUE);如果去掉注释,那些白色线条
//不会消失
hdc = BeginPaint(hwnd, &ps);
DrawBezier(hdc, apt);//创建窗口时,会产生一个WM_PAINT消息,
//所以程序已运行,就会看到一条Bezier样条
EndPaint(hwnd, &ps);
return 0;
case WM_CLOSE:
PostQuitMessage(0);
//DestroyWindow(hwnd);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
把背景色改为灰色就很清楚了,如图
是不是很有趣,哈哈