设置开始点
MoveToEx 函数用于移动画笔到指定的位置:
BOOL MoveToEx( HDC hdc, // 设备环境句柄 int X, // 要移动到的 x 坐标 int Y, // 要移动到的 y 坐标 LPPOINT lpPoint // 之前的位置(POINT 结构地址) );
绘制直线
LineTo 函数用于绘制直线到指定位置(这会改变当前画笔的位置到结束位置):
BOOL LineTo( HDC hdc, // 设备环境句柄 int nXEnd, // 结束位置的 x 坐标 int nYEnd // 结束位置的 y 坐标 );
绘制折线
Polyline 函数用于绘制一系列点构成的折线(这不会改变当前画笔的位置):
BOOL Polyline( HDC hdc, // 设备环境句柄 CONST POINT *lppt, // POINT 结构数组(一系列点) int cPoints // POINT 结构的数量(点的数量) );
PolylineTo 函数用于绘制由画笔位置开始到一系列点所构成的折线(这会改变当前画笔的位置到最后一个点的位置):
BOOL PolylineTo( HDC hdc, // 设备环境句柄 CONST POINT *lppt, // POINT 结构数组(一系列点) DWORD cCount // POINT 结构的数量(点的数量) );
PolyPolyline 函数用于同时绘制多条折线(这不会改变当前画笔的位置):
BOOL PolyPolyline( HDC hdc, // 设备环境句柄 CONST POINT *lppt, // POINT 结构数组(一系列点) CONST DWORD *lpdwPolyPoints, // 数组中的每个元素表示对应折线的点的数量 DWORD cCount // 折线数量(上个参数的元素个数) );
绘制 Sin 函数图像的程序示例
#include <windows.h> #include <strsafe.h> #include <math.h> #define NUMS 10000 #define TWOPI 6.283185307 LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rcClient; POINT apt[NUMS]; TCHAR szBuffer[100]; size_t nLength; int cxClient, cyClient, i; switch (message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rcClient); cxClient = rcClient.right - rcClient.left; cyClient = rcClient.bottom - rcClient.top; MoveToEx(hdc, 0, cyClient / 2, NULL); LineTo(hdc, cxClient, cyClient / 2); for (i = 0; i < NUMS; i++) { apt[i].x = i; apt[i].y = (int)((1 - sin(i * TWOPI / cxClient)) * cyClient / 2); } SetTextAlign(hdc, TA_TOP | TA_RIGHT); StringCchPrintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), TEXT("y = sin x")); StringCchLength(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), &nLength); TextOut(hdc, cxClient - 10, 10, szBuffer, nLength); Polyline(hdc, apt, i - 1); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { LPCTSTR lpszClassName = TEXT("Demo"); LPCTSTR lpszWindowName = TEXT("Demo Program"); WNDCLASS wndclass; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WindowProc; wndclass.lpszClassName = lpszClassName; wndclass.lpszMenuName = NULL; wndclass.style = CS_HREDRAW | CS_VREDRAW; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), lpszWindowName, MB_ICONERROR); return 0; } HWND hwnd = CreateWindow( lpszClassName, lpszWindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }