保存设备描述表
在释放设备描述表之后,仍然保存程序中设备描述表的改变,以便在下一次调用时起作用
在登陆窗口类时,将CS_OWNDC标志包含位窗口类的一部分
wndclass.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC;
这样,基于这个窗口类的所创建的每个窗口将都拥有自己的设备描述表,他一直存在,直到窗口被删除,如果使用了CS_OWNDC,就只需要初始化设备描述表一次,处理WM_CREATE消息期间完成这一操作:
case WM_CREATE
hdc=GetDC(hwnd);
RelaeseDC(hwnd,hdc);
这些属性在改变之前一直有效。
5.3.1写像素
5.3.2直线
MoveToEx 设置设备描述表的当前属性,然后LineTo函数从当前位置到它的点画一条直线。
获取当前位置
GetCurrentPositionEx(hdc,&pt);
绘制网格
GetClientRect(hWnd, &rect);
void paintGrid(HDC hDc, RECT &rect)
{
int x, y;
for (x = 0; x < rect.right; x += 120)
{
MoveToEx(hDc, x, 0, NULL);
LineTo(hDc, x, rect.bottom);
}
for (y = 0; y < rect.bottom; y += 210)
{
MoveToEx(hDc, 0, y, NULL);
LineTo(hDc, rect.right, y);
}
}
绘制正弦曲线
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return (0);
case WM_PAINT:
hDC = ::BeginPaint(hWnd, &ps);
MoveToEx(hDC, 0, cyClient / 2, NULL);
LineTo(hDC, cxClient, cyClient/2);
for (i=0;i<NUM;i++)
{
pt[i].x = i * cxClient / NUM;
pt[i].y = int(cyClient/2 *(1- sin (2*3.1415926*i/NUM)));
}
Polyline(hDC, pt, NUM);
::EndPaint(hWnd, &ps);
return (0);
PolyLine 和 PolyLineTo
5.3.3边界框函数
矩形
Rectangle(hDC, 100, 100, 400, 500);
椭圆形
Ellipse(hDC, 700, 100, 1000, 200);
RoundRect
条弧,弓形扇形
5.3.4贝塞尔曲线
转自:https://blog.csdn.net/thefutureisour/article/details/7578107
#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);
}