Windows c++界面开发初学(五)win32

今天学习做一个简单的画直线应用。
基本根据这篇博客完成的。

1、思路

主要处理集中在WindowProc函数,WM_LBUTTONDOWNWM_LBUTTONUP消息

  • 首先定义一个结构体,用于存放画线时每根线的起点和终点坐标,以及线的类型(实线、虚线、点线等)

  • 当窗口重绘时需要把之前的直线也画出来,因此需要保存之前画过的直线的信息以重绘直线,可以用一个vector保存

  • 每次按下鼠标左键开始画一根线,该点坐标作为该直线的起点坐标,松开左键时表示该直线画完,松开时的坐标作为该直线的终点坐标。使用弹出式菜单来选择线型,还可以加入颜色、线粗的菜单,但是我这里没有加。

  • 以前做opengl的作业时还有实现过右键点击某直线删除该直线,可以遍历vector判断点击的坐标在哪条直线上然后删除该直线信息。这里没有实现

2、代码

struct PAINTDATA {
    int BeginX, BeignY;
    int EndX, EndY;
    int penStyle;
};

LRESULT CALLBACK WindowProc(
    _In_ HWND hwnd,
    _In_ UINT uMsg,
    _In_ WPARAM wParam,
    _In_ LPARAM lParam
) {
    PAINTSTRUCT ps;
    HDC hdc;

    static vector<PAINTDATA> datas;
    static int penStyle = PS_DOT;
    static PAINTDATA *pCurrentData = NULL;
    switch (uMsg)
    {
    //选择线型
    case WM_COMMAND:
    {
        HMENU mnbar = GetMenu(hwnd);
        HMENU hmnPop = GetSubMenu(mnbar, 0);
        CheckMenuRadioItem(hmnPop, ID_SOLIDLINE, ID_DASHDOT, LOWORD(wParam), MF_BYCOMMAND);
        penStyle = (int)LOWORD(wParam);
    }
        break;
    //开始画线
    case WM_LBUTTONDOWN:
    {
        pCurrentData = new PAINTDATA;
        pCurrentData->penStyle = penStyle;
        pCurrentData->BeginX = GET_X_LPARAM(lParam);
        pCurrentData->BeignY = GET_Y_LPARAM(lParam);
    }
        break;
    //结束画线
    case WM_LBUTTONUP:
    {
        if (pCurrentData != NULL) {
            pCurrentData->EndX = GET_X_LPARAM(lParam);
            pCurrentData->EndY = GET_Y_LPARAM(lParam);
            HDC hdc = GetDC(hwnd);
            HPEN pen = CreatePen(pCurrentData->penStyle, 1, RGB(0, 200, 0));
            HPEN oldpen = (HPEN)SelectObject(hdc, pen);
            MoveToEx(hdc, pCurrentData->BeginX, pCurrentData->BeignY, NULL);
            LineTo(hdc, pCurrentData->EndX, pCurrentData->EndY);
            //加入工具
            SelectObject(hdc, oldpen);
            //释放资源
            DeleteObject(pen);
            ReleaseDC(hwnd, hdc);
            //保存直线信息
            datas.push_back(*pCurrentData);
        }
    }
        break;
    //重绘窗口,比如最小化窗口后还原
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        BeginPaint(hwnd, &ps);
        vector<PAINTDATA>::const_iterator it;
        for (it = datas.begin(); it != datas.end(); it++) {
            HPEN pen = CreatePen(it->penStyle, 1, RGB(0, 200, 0));
            SelectObject(ps.hdc, pen);
            MoveToEx(ps.hdc, it->BeginX, it->BeignY, NULL);
            LineTo(ps.hdc, it->EndX, it->EndY);
            DeleteObject(pen);
        }
        EndPaint(hwnd, &ps);
    }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
        break;
    }
    return 0;
}

3、运行结果

这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/unirrrrr/article/details/81293459