GDI 直线和折线(6)

设置开始点

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;
}
原文地址:https://www.cnblogs.com/yenyuloong/p/9117563.html