{"id":18595672,"url":"https://github.com/wineee/mfcplot","last_synced_at":"2025-09-13T13:07:03.952Z","repository":{"id":54518607,"uuid":"275286141","full_name":"wineee/mfcplot","owner":"wineee","description":"mfc数学函数曲线绘制程序","archived":false,"fork":false,"pushed_at":"2021-09-10T08:00:17.000Z","size":262,"stargazers_count":50,"open_issues_count":0,"forks_count":25,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-23T15:08:43.744Z","etag":null,"topics":["cpp","math","mfc","plot"],"latest_commit_sha":null,"homepage":"https://blog.csdn.net/qq_33831360/article/details/107477430","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wineee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-27T02:35:47.000Z","updated_at":"2025-06-06T09:17:50.000Z","dependencies_parsed_at":"2022-08-13T18:30:41.187Z","dependency_job_id":null,"html_url":"https://github.com/wineee/mfcplot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/wineee/mfcplot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wineee%2Fmfcplot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wineee%2Fmfcplot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wineee%2Fmfcplot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wineee%2Fmfcplot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wineee","download_url":"https://codeload.github.com/wineee/mfcplot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wineee%2Fmfcplot/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262030074,"owners_count":23247592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","math","mfc","plot"],"created_at":"2024-11-07T01:20:39.554Z","updated_at":"2025-06-26T08:32:42.383Z","avatar_url":"https://github.com/wineee.png","language":"C++","readme":"# mfcplot\nmfc数学函数曲线绘制程序\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot?ref=badge_shield)\n### 实验环境\n - window 10 版本19041\n - Microsoft Visual Studio Community 2019 版本 16.6.4\n\n### 实现功能\n - [x]  绘制常见一元函数的图像\n - [x]  支持普通函数，极坐标函数，参数方程，直接输入数据点\n - [x]  可以删除指定函数图像\n - [x]  可以在一个坐标系中绘制多条数学曲线\n - [x]  显示坐标轴，网格，刻度值，图例\n - [x]  可以选择不同颜色线型来绘制不同的曲线\n - [x]  当鼠标移动到曲线上某点时，可以显示该点的坐标\n - [x]  可以用鼠标拖动图像\n - [x]  可以进行图形的放大，缩小，定量设置显示范围，自动缩放\n - [x]  普通函数x取值范围可设置为跟随显示范围变化\n - [x]  状态栏实时显示鼠标位置，双击显示鼠标精确位置\n - [x]  重要数据的序列化和反序列化\n - [ ]  突变函数(如floor(x))和部分y值接近无穷的函数(如tan(x))无法完美显示 \n\n\n\n### 界面展示\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720012121800.png)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/2020072001273763.png)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014118171.png)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014136668.png)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014609420.png)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/2020072001464030.png)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720014714925.png)\n\n### 设计结构\n##### 程序流程及设计\n\u0026emsp; 用户输入函数信息，显示函数图像。还可以通过菜单和工具栏更改设置。\n\n\u0026emsp; 通过计算样本点，相邻样本点用直线连接，当样本点数量足够大时，可近似看成曲线。\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720162214892.png)\n\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720161921318.png)\n##### 程序所有源文件\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720162844144.png)\n##### CalculatorFunc.cpp介绍\n\u003edouble CalcEquation(CString m_sEquation, bool\u0026 succ, char xKey, double xVal) \n\u003em_sEquation:表达式 \n\u003esucc:计算是否成功 \n\u003exKey:未知数是\"x\"还是\"t\"\n\u003exVal:未知数的值\n\n\u003e此文件可以单独拿出来(把CString换成string就行)使用\n\u003ebool  succ = true;\n\u003edouble ans = CalcEquation(\"sin(x)+e^x\",succ,'x',1.1);\n\n\u0026emsp;对方程，分为数（常数，未知数x），双目运算符(+ , - ,*  , / , ^ ) ,单目运算符(sin,cos等等)，单目运算符后面是一个完整的子式，如2+cos(x+1)中，x+1就是一个完整的式子，通过递归调用可以求子式的值，如果已知子式值，这个[单目运算符+子式]就是一个已知数了，那剩下的就等效于只有+ , - , * , / , ^  的公式，用表达式栈法就可以解决。\n##### FuncData.cpp介绍\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20200720161950216.png)\n```cpp\nFuncData类\n成员变量：\n\tint FuncCas;            //函数类型\n\tCString m_Equation;\t\t//函数表达式\n\tdouble minX, maxX;\t\t//x极值\n\tdouble maxY, minY;\t\t//y极值\n\tint stepX;\t\t\t\t//可以理解为样本点的数量\n\tint m_penWidth;\t\t\t//画笔宽度\n\tint m_penType;\t\t\t//画笔类型\n\tCOLORREF m_color;\t\t//画笔颜色\n\tvector\u003cpair\u003cdouble, double\u003e \u003e vetPoint;\t\t\t //储存所有样本点\n成员函数：\n\tvirtual double GetY(double xVal, bool\u0026 succ) = 0;//得到未知数为xVal时函数值，succ表示计算是否成功\n\tvirtual bool CalcList() = 0;\t\t\t\t\t //计算vetPoint\n\tvirtual bool GetNearest(pair\u003cdouble,double\u003e NowPoint, pair\u003cdouble, double\u003e \u0026CmpPoint);//获取本函数与NowPoint最近的点\n\tvirtual CString GetEquation2();\t\t\t\t\t //为了得到参数方程第二个函数式\n\tFuncData();\n\tFuncData(CString Equation,double minX,double maxX,int stepX,COLORREF color, int penWidth,int penType);//构造函数\n\n注意:此处派生类只记录特有的成员\nNormalFD类\n无\n\nPolarFD 类\n成员变量\ndouble maxth, minth;   //自变量θ取值范围\n\nTwoFD类\n成员变量\nCString m_EquationY;\ndouble maxT, minT;\n成员函数\ndouble GetX(double tVal, bool\u0026 succ);//参数方程X也需要求值\n\tvirtual double GetY(double tVal, bool\u0026 succ);\n\nDataFD类\n成员函数\n\tstatic int DataFD_Cnt;  //记录数据点类型函数数量\n```\n\n\n##### mfcplotDoc.cpp介绍\n\u0026emsp;mfcplotDoc中记录着设置信息和函数数据，主要内容如下\n```cpp\npublic:\n\tbool m_WillShowGrid; //是否显示网格\n\tbool m_WillShowAxis; //是否显示坐标轴\n\tbool m_WillShowEdge; //是否显示边框\n\tbool m_SingelMode;   //单函数模式添加函数自动删除上一个函数\n\tbool m_ForceXrange;\t //普通函数x范围是否固定，不固定的话随显示范围变化\n\tbool m_ShowNearPoint;//鼠标接近函数线时是否显示其坐标\n\tdouble m_Xmin, m_Xmax, m_Ymin, m_Ymax;//显示范围\n\tFuncData *m_FD;//临时变量\n\tCObList m_List;//记录所有函数信息\npublic:\n\tafx_msg void OnAxisMenu();//坐标轴\n\tafx_msg void OnGridMenu();//网格\n\tafx_msg void OnEdgeMenu();//边框\n\tafx_msg void OnSmallerMenu();//显示范围缩小 0.8\n\tafx_msg void OnBiggerMenu();//显示范围放大 1.25\n\tafx_msg void OnNormalFuncMenu();//增加普通函数\n\tafx_msg void OnMenuSetXyrange();//设置显示范围\n\tafx_msg void OnFuncMode();//单/多函数模式\n\tafx_msg void OnPolarFuncMenu();//增加极坐标函数\n\tafx_msg void OnTwoFuncMenu();//增加参数方程函数\n\tafx_msg void OnDataFuncMenu();//增加数据点型函数\n\tafx_msg void OnFroceXrang();//普通函数x范围是否固定\n\tafx_msg void OnNearpointMenu();//是否显示最近点\n\tafx_msg void OnAutorangeMenu();//自动调整显示范围，正好显示完整函数图像\n\tafx_msg void OnDelfunconeMenu();//删除一个函数\n\tafx_msg void OnDelallMenu();//删除所有函数\n```\n##### mfcplotView.cpp介绍\n\u0026emsp;绘图逻辑是在这里实现的，主要内容如下\n```cpp\npublic:\n\tdouble m_Xmin, m_Xmax, m_Ymin, m_Ymax;//函数显示范围\n\tint nTop, nButton, nLeft, nRight;//对应的逻辑坐标范围\n\tint isMoving;//拖动状态 0不拖动 1拖动模式 2正在拖动\n\tdouble tmp_Xmin, tmp_Xmax, tmp_Ymin, tmp_Ymax;\n\t//拖动模式下，单击鼠标左键，记录起点的显示范围\n\tCPoint m_posStart;\n\t//拖动模式下，单击鼠标左键，记录起点的鼠标坐标\n\t//根据鼠标坐标偏移量可以计算显示范围变化量\n```\n\n\u0026emsp;函数中LPxtoFPx表示把函数坐标x变成pDC可以用的逻辑坐标_x，原理函数坐标范围m_Xmin，m_Xmax到逻辑坐标范围nLeft，nRight（下面函数会给出）等比例的映射。\n\n```cpp\ndouble CmfcplotView::LPxtoFPx(int x) {\n\treturn m_Xmin + (1.0 * x - nLeft) * (m_Xmax - m_Xmin) / (1.0 * nRight - nLeft);\n}\n```\n\u0026emsp;实现坐标转换后就可以进行绘图工作了。\n\n```cpp\nvoid CmfcplotView::OnDraw(CDC* pDC)\n{\n\tCmfcplotDoc* pDoc = GetDocument();\n\tASSERT_VALID(pDoc);\n\tif (!pDoc)\n\t\treturn;\n\tm_Xmin = pDoc-\u003em_Xmin;//极值保存在Doc中\n\tm_Xmax = pDoc-\u003em_Xmax;\n\tm_Ymin = pDoc-\u003em_Ymin;\n\tm_Ymax = pDoc-\u003em_Ymax;\n\t\n\tCRect rect;\n\tGetClientRect(\u0026rect);//获得视图区\n\n\tnTop = (int)round(rect.bottom * 0.1);  //函数图像不会占据整个视图区\n\tnButton = (int)round(rect.bottom * 0.9);\n\tnLeft = (int)round(rect.right * 0.1);\n\tnRight = (int)round(rect.right * 0.9);\n\n\tif (pDoc-\u003em_WillShowEdge) {//画边框\n\t\tpDC-\u003eMoveTo(nLeft, nTop);\n\t\tpDC-\u003eLineTo(nLeft, nButton);\n\t\tpDC-\u003eLineTo(nRight, nButton);\n\t\tpDC-\u003eLineTo(nRight, nTop);\n\t\tpDC-\u003eLineTo(nLeft, nTop);\n\t}\n\n\t//画x坐标信息\n\tint nX,nY;\n\tbool BIGX = abs(m_Xmin) \u003e 100 || abs(m_Xmax) \u003e 100;//x坐标值比较大时，标注更稀\n\tfor (nX = nLeft; nX \u003c nRight; nX += (BIGX ? 100 : 50)) { //每隔100/50像素一个标注\n\t\tCRect textRect(nX - (BIGX ? 50 : 25), nButton + 1, nX + (BIGX ? 50 : 25), nButton + 20);//显示区域\n\t\tCString xInfo;\n\t\txInfo.Format(_T(\"%.2f\"),LPxtoFPx(nX));\n\t\tpDC-\u003eDrawText(xInfo, \u0026textRect, DT_SINGLELINE | DT_CENTER);\n\t\t                                    //单行,上下左右居中显示\n\t}\n\tif (nX - nRight \u003c= (BIGX ? 50 : 25)) {//最后一个x坐标，与前一个标注距离太近则不显示\n\t\tCRect textRect(nRight, nButton + 1, nRight + 50, nButton + 20);\n\t\tCString xInfo;\n\t\txInfo.Format(_T(\"%.2f\"),m_Xmax);\n\t\tpDC-\u003eDrawText(xInfo, \u0026textRect, DT_SINGLELINE | DT_LEFT | DT_TOP);\n\t}\n\n\t//y坐标\n\tfor (nY = nButton - 50; nY \u003e nTop; nY -= 50) {\n\t\tCRect textRect(nLeft - 200, nY-10, nLeft - 3, nY + 10);\n\t\tCString yInfo;\n\t\tyInfo.Format(_T(\"%.2f\"), LPytoFPy(nY));\n\t\tpDC-\u003eDrawText(yInfo, \u0026textRect, DT_SINGLELINE | DT_RIGHT);\n\t}\n\tif (nTop - nY \u003c= 25) {\n\t\tCRect textRect(nLeft - 200, nTop - 10, nLeft - 3, nTop + 10);\n\t\tCString yInfo;\n\t\tyInfo.Format(_T(\"%.2f\"),m_Ymax);\n\t\tpDC-\u003eDrawText(yInfo, \u0026textRect, DT_SINGLELINE | DT_BOTTOM | DT_RIGHT);\n\t}\n\n\n\t//  显示网格\n\tif (pDoc-\u003em_WillShowGrid) {\n\t\tCPen pen(PS_DOT, 1, RGB(100, 100, 100));           //创建笔，虚线，并调整坐标颜色灰色\n\t\tCPen *pOldPen = (CPen *)pDC-\u003eSelectObject(\u0026pen);\n\t\tfor (nX = nLeft+50; nX \u003c nRight; nX += 50) {\n\t\t\tpDC-\u003eMoveTo(nX, nTop);\n\t\t\tpDC-\u003eLineTo(nX, nButton);\n\t\t}\n\t\tfor (nY = nButton - 50; nY \u003e nTop; nY -= 50) {\n\t\t\tpDC-\u003eMoveTo(nLeft, nY);\n\t\t\tpDC-\u003eLineTo(nRight, nY);\n\t\t}\n\t\tpDC-\u003eSelectObject(pOldPen);\n\t}\n\n\t// 显示坐标轴\n\tif (pDoc-\u003em_WillShowAxis) {\n\t\tCPen pen(PS_SOLID, 2, RGB(0, 0, 0));\n\t\tCPen* pOldPen = (CPen*)pDC-\u003eSelectObject(\u0026pen);\n\t\tint oX = FPxtoLPx(0);\n\t\tint oY = FPytoLPy(0);\n\t\tbool showY = oX \u003e= nLeft \u0026\u0026 oX \u003c= nRight;\n\t\tbool showX = oY \u003e= nTop \u0026\u0026 oY \u003c= nButton;//判断x,y轴是否在范围内\n\t\tif (showX) {\n\t\t\tpDC-\u003eMoveTo(nLeft - 10, oY);\n\t\t\tpDC-\u003eLineTo(nRight + 10, oY);\n\t\t}\n\t\tif (showY) {\n\t\t\tpDC-\u003eMoveTo(oX, nButton + 10);\n\t\t\tpDC-\u003eLineTo(oX, nTop - 10);\n\t\t}\n\t\tif (showX \u0026\u0026 showY) {\n\t\t\tpDC-\u003eTextOutW(oX + 1, oY + 1, _T(\"O\"));\n\t\t}\n\t\tif (showX) {\n\t\t\tpDC-\u003eMoveTo(nRight + 10, oY);\n\t\t\tpDC-\u003eLineTo(nRight + 5, oY + 5);\n\t\t\tpDC-\u003eMoveTo(nRight + 10, oY);\n\t\t\tpDC-\u003eLineTo(nRight + 5, oY - 5);\n\t\t\tpDC-\u003eTextOutW(nRight + 10, oY, _T(\"X轴\"));\n\t\t}\n\t\tif (showY) {\n\t\t\tpDC-\u003eMoveTo(oX, nTop - 10);\n\t\t\tpDC-\u003eLineTo(oX - 5, nTop - 5);\n\t\t\tpDC-\u003eMoveTo(oX, nTop - 10);\n\t\t\tpDC-\u003eLineTo(oX + 5, nTop - 5);\n\t\t\tpDC-\u003eTextOutW(oX + 5, nTop - 10, _T(\"Y轴\"));\n\t\t}\n\t\tpDC-\u003eSelectObject(pOldPen);\n\t}\n\n\t\n\tPOSITION p = pDoc-\u003em_List.GetHeadPosition();\n\n\tint showTop = nTop;\n\twhile (p != nullptr) {\n\t\tbool shouldMov = true;//一段曲线第一个点MoveTo，其他都是LineTo\n\t\tFuncData* tmpFD = (FuncData*)pDoc-\u003em_List.GetNext(p);\n\t\tCPen pen(tmpFD-\u003em_penType, tmpFD-\u003em_penWidth, tmpFD-\u003em_color);\n\t\tCPen* pOldPen = (CPen*)pDC-\u003eSelectObject(\u0026pen);\n\n\t\tif (tmpFD-\u003eFuncCas == CAS_NORMAL) {//动态X坐标模式下，普通函数x范围与视图不同时自动同步\n\t\t\tif (pDoc-\u003em_ForceXrange \u0026\u0026 isMoving!=2)\n\t\t\t\tif (tmpFD-\u003eminX != m_Xmin || tmpFD-\u003emaxX != m_Xmax) {\n\t\t\t\t\ttmpFD-\u003eminX = m_Xmin;\n\t\t\t\t\ttmpFD-\u003emaxX = m_Xmax;\n\t\t\t\t\ttmpFD-\u003eCalcList();\n\t\t\t\t}\n\t\t}\n\n\t\tfor (auto dot : tmpFD-\u003evetPoint) {\n\t\t\tif (dot.first \u003c m_Xmin || dot.first \u003e m_Xmax || dot.second \u003c m_Ymin || dot.second \u003e m_Ymax || dot.second != dot.second) {\n\t\t\t\tshouldMov = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (shouldMov) {\n\t\t\t\tpDC-\u003eMoveTo(FPxtoLPx(dot.first), FPytoLPy(dot.second));\n\t\t\t\tshouldMov = false;\n\t\t\t}\n\t\t\telse\n\t\t\t\tpDC-\u003eLineTo(FPxtoLPx(dot.first), FPytoLPy(dot.second));\n\t\t}\n\n\t\tpDC-\u003eMoveTo(nRight+5, showTop);//显示图例\n\t\tpDC-\u003eLineTo(rect.right, showTop);\n\t\tshowTop += 5;\n\t\tif (tmpFD-\u003eFuncCas == CAS_NORMAL)\n\t\t    pDC-\u003eTextOutW(nRight + 5, showTop, _T(\"f(x)=\")+tmpFD-\u003em_Equation);\n\t\telse if (tmpFD-\u003eFuncCas == CAS_POLAR)\n\t\t\tpDC-\u003eTextOutW(nRight + 5, showTop, _T(\"r(t)=\") + tmpFD-\u003em_Equation);\n\t\telse if (tmpFD-\u003eFuncCas == CAS_TWO) {\n\t\t\tpDC-\u003eTextOutW(nRight + 5, showTop, _T(\"x(t)=\") + tmpFD-\u003em_Equation);\n\t\t\tshowTop += 20;\n\t\t\tpDC-\u003eTextOutW(nRight + 5, showTop, _T(\"y(t)=\") + tmpFD-\u003eGetEquation2());\n\t\t} else if (tmpFD-\u003eFuncCas == CAS_DATA)\n\t\t\tpDC-\u003eTextOutW(nRight + 5, showTop, _T(\"y(t)=\") + tmpFD-\u003em_Equation);\n\t\tshowTop += 25;\n\t\tpDC-\u003eSelectObject(pOldPen);\n\t}\n}\n```\n\u0026emsp;值得一提的是OnMouseMove的代码，拖动模式下，起点信息已经在OnLButtonDown更新，拖动过程使用了双缓冲绘图防止闪烁。具体原理可参看文末参考资料。\n```cpp\nvoid CmfcplotView::OnMouseMove(UINT nFlags, CPoint point)\n{\n\t// TODO: 在此添加消息处理程序代码和/或调用默认值\n\t更新状态栏，此处省略\n\tif (isMoving==2) {\n\t\t::SetCursor(LoadCursor(NULL, IDC_SIZEALL));\n\t\tCmfcplotDoc* pDoc = GetDocument();\n\t\tdouble detx = LPxtoFPx(point.x) - LPxtoFPx(m_posStart.x);\n\t\tpDoc-\u003em_Xmin = tmp_Xmin - detx;\n\t\tpDoc-\u003em_Xmax = tmp_Xmax - detx;\n\t\tdouble dety = LPytoFPy(point.y) - LPytoFPy(m_posStart.y);\n\t\tpDoc-\u003em_Ymin = tmp_Ymin - dety;\n\t\tpDoc-\u003em_Ymax = tmp_Ymax - dety;\n\t\tCDC* pDC = GetDC();\n\t\t//创建一个内存中的显示设备\n\t\tCDC MemDC;\n\t\tMemDC.CreateCompatibleDC(NULL);\n\t\t//创建一个内存中的图像\n\t\tCBitmap MemBitmap;\n\t\tCRect rect;\n\t\tGetClientRect(\u0026rect);\n\t\tMemBitmap.CreateCompatibleBitmap(pDC, rect.right, rect.bottom);\n\t\t//指定内存显示设备在内存中的图像上画图\n\t\tMemDC.SelectObject(\u0026MemBitmap);\n\t\t//先用一种颜色作为内存显示设备的背景色\n\t\tMemDC.FillSolidRect(rect.left, rect.top, rect.right, rect.bottom, RGB(144, 144, 144));\n\t\tthis-\u003eOnDraw(\u0026MemDC);\n\t\t//将内存中画好的图像直接拷贝到屏幕指定区域上\n\t\tpDC-\u003eBitBlt(rect.left, rect.top, rect.right, rect.bottom, \u0026MemDC, 0, 0, SRCCOPY);\n\t\t//释放相关资源\n\t\tReleaseDC(pDC);\n\t}\n\telse if (isMoving == 1) {\n\t\t::SetCursor(LoadCursor(NULL, IDC_HAND));\n\t}\n\t显示函数最近点部分，此处省略\n\tCView::OnMouseMove(nFlags, point);\n}\n\n```\n\n\n### 完整代码\n[github](https://github.com/wineee/mfcplot)\n[gitee](https://gitee.com/rewine/mfcplot)\n[csdn下载](https://download.csdn.net/download/qq_33831360/12636165)\n### 参考资料\n- [DrawText函数的讲解](https://blog.csdn.net/by_mxy/article/details/9932967)\n- [VC双缓冲绘图技术介绍](https://blog.csdn.net/oceanlucy/article/details/46827809?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.nonecase\u0026depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-7.nonecase)\n - 阎光伟，彭文，徐琳茜. 基于案例的Visual C++程序设计教程[M].北京：清华大学出版社，2012\n - 张晓民. VC++2010应用开发技术[M].北京：机械工业出版社，2013\n\n\n## License\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwineee%2Fmfcplot?ref=badge_large)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwineee%2Fmfcplot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwineee%2Fmfcplot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwineee%2Fmfcplot/lists"}