功能设计:

实现画出函数图像(散点图,连线很简单,有最多8个图例),同时可以将图表保存下来。

头文件

/*********************************************************************************
*FileName:  GraphControl
*Author: FMX
*Version:  1.0
*Date:  2014-8-22
*Description:
*Others:  //其他内容说明
*Function List: void drawBK();  //绘制背景和坐标系void setGraphTitle(CString str);  //设置图表文件的标题void addLine(CString str);   //添加曲线的图例void addLine(CString* arr, int n); //一次添加多个图例,最大图例数量为8void setRange(int ixl, int ixr, int iyl, int iyt);    //设定逻辑坐标的范围void addLineData(std::vector<CPoint> arr); //输入绘制点的逻辑数据void transPos(CPoint *point, bool bIn); //逻辑坐标,物理坐标转换void add(CString legName, std::vector<CPoint> line);//该方法可以添加完一个线条void getBitmap();  //获取可以保存的位图文件
*History:  //修改历史记录列表,每条修改记录应包含修改日期、修改者及修改内容简介
1.Date:
Author:
Modification:
2.…………
**********************************************************************************/
#pragma once#include <vector>// CGraphControlclass CGraphControl : public CStatic
{DECLARE_DYNAMIC(CGraphControl)public:CGraphControl();virtual ~CGraphControl();添加的方法/绘图所使用的方法void drawBK(); //绘制背景和坐标系void setGraphTitle(CString str);  //void addLine(CString str);    //添加曲线的图例void addLine(CString* arr, int n); //一次添加多个图例,最大图例数量为8void setRange(int ixl, int ixr, int iyl, int iyt);    //设定逻辑坐标的值void addLineData(std::vector<CPoint> arr);  //输入绘制点的逻辑数据void transPos(CPoint *point, bool bIn); //逻辑坐标,物理坐标转换void transPos(std::vector<CPoint> *arr, bool bIn);//批量转换坐标void add(CString legName, std::vector<CPoint> line);//对于添加线条,整理逻辑,一个方法即可完成一次对线条的添加void getBitmap();    //获取可以保存的位图文件
private:CRect m_rect;   //控件的大小int marginL, marginR, marginT, marginB, marginInter; //分别对应于图和空间边缘的距离,最后的一个变量指的是图表的主体和图例区域间的距离。int xl, xr, yb, yt;    //坐标范围,从X轴到Y轴的所有范围double ratioX; //该比值表示的是X轴上逻辑坐标单位和物理坐标单位的比值,若该值为20则表示20个逻辑坐标对应屏幕上的物理坐标。double ratioY;   //该比值表示的是X轴上逻辑坐标单位和物理坐标单位的比值,若该值为20则表示20个逻辑坐标对应屏幕上的物理坐标。CString graphTitle;  //图表的标题int legendAreaWidth = 120;  //图例区域的宽度CBitmap m_axis;    //该位图上包含了主要图表CDC *axisDC;   //和轴位图搭配起来的绘图上下文//CBitmap m_graph;  //该位图上包含了主要图表,以及最后将整张图片合成后的结果//CDC *graphDC; //对上一张位图绘图的设备上下文CRect graphRc;  //记录下图表区域的坐标信息CRect legRc;  //图例区域所在的位置CPoint origin;   //物理坐标系原点对应的物理坐标信息CPoint logOri;    //物理坐标系原点处逻辑坐标CString Title;    //图表的标题//图例的字符串已经颜色CString legs[8];COLORREF colors[8];int lineNum = 0; //标记图表中有几条曲线std::vector<CPoint> lineData[8];
protected:DECLARE_MESSAGE_MAP()public:afx_msg void OnPaint();afx_msg BOOL OnEraseBkgnd(CDC* pDC);afx_msg void OnSize(UINT nType, int cx, int cy);// afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
};

实现文件

// GraphControl.cpp : 实现文件
//#include "stdafx.h"
#include "GraphControl.h"// CGraphControlIMPLEMENT_DYNAMIC(CGraphControl, CStatic)CGraphControl::CGraphControl()
{marginL = marginB = 10;marginB = 20;marginT = 20;marginInter = 10;graphTitle = L"TEST GRAPH";//初始化所有图例文字for (int i = 0; i < 8; i++){legs[i] = L"TEST";}//初始化所有图例色彩colors[0] = RGB(18, 35, 65);colors[1] = RGB(22, 138, 154);colors[2] = RGB(37, 19, 20);colors[3] = RGB(117, 34, 87);colors[4] = RGB(83, 98, 128);colors[5] = RGB(40, 54, 160);colors[6] = RGB(51, 124, 243);colors[7] = RGB(180, 53, 16);//初始化线条数据}CGraphControl::~CGraphControl()
{m_axis.DeleteObject();axisDC->DeleteDC();
}BEGIN_MESSAGE_MAP(CGraphControl, CStatic)ON_WM_PAINT()ON_WM_ERASEBKGND()ON_WM_SIZE()// ON_WM_LBUTTONDBLCLK()ON_WM_LBUTTONDOWN()//  ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()// CGraphControl 消息处理程序void CGraphControl::OnPaint()
{CPaintDC dc(this); // device context for painting// TODO:  在此处添加消息处理程序代码// 不为绘图消息调用 CStatic::OnPaint()//确定屏幕比例ratioX = (double)(xr - xl) / graphRc.Width();ratioY = (double)(yt - yb) / graphRc.Height();//开始绘图GetClientRect(m_rect);drawBK();dc.BitBlt(0, 0, m_rect.Width(), m_rect.Height(), axisDC, 0, 0, SRCCOPY);m_axis.DeleteObject();axisDC->DeleteDC();
}BOOL CGraphControl::OnEraseBkgnd(CDC* pDC)
{//可以设置不自动擦除背景return CStatic::OnEraseBkgnd(pDC);
}void CGraphControl::OnSize(UINT nType, int cx, int cy)
{//修改这里使得空间可以自适应大小变化return CWnd::OnSize(nType, cx, cy);}void CGraphControl::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO:  在此添加消息处理程序代码和/或调用默认值CStatic::OnLButtonDown(nFlags, point);if (point.x > graphRc.left&&point.x < graphRc.right&&point.y<graphRc.bottom&&point.y > graphRc.top){CString str;str.Format(L"%d,%d", point.x, point.y);MessageBox(str);}
}void CGraphControl::drawBK()
{axisDC = new CDC();axisDC->CreateCompatibleDC(NULL);m_axis.CreateCompatibleBitmap(axisDC, m_rect.Width(), m_rect.Height());axisDC->SelectObject(&m_axis);axisDC->FillSolidRect(m_rect, RGB(255, 255, 255));//axisDC->Rectangle(marginL, marginR, m_rect.right - marginR, m_rect.bottom - marginB);axisDC->TextOutW(m_rect.CenterPoint().x - 45, 1, graphTitle);//确定下图表的区域以及图例的区域legRc.left = m_rect.right - marginR - 120;legRc.top = marginT;legRc.right = m_rect.right - marginR;legRc.bottom = m_rect.bottom - marginB;axisDC->Rectangle(legRc);//日期文字输出//图例文字输出int legsVerticalDif = 25;//int fontHeight = 15;int legsTop = legRc.top + legsVerticalDif;int legsLeft = legRc.CenterPoint().x - 20;axisDC->TextOutW(legRc.CenterPoint().x - 15, legRc.top + 1, L"图例");for (int i = 0; i < 8; i++){//axisDC->SetTextColor(colors[i]); //为文字设置色彩,没有成功,还在思考中。axisDC->SetTextColor(colors[i]);axisDC->TextOutW(legsLeft, legsTop, legs[i]);//axisDC->drawtelegsTop += 35;if (legsTop + 9 >= legRc.bottom){break;}}axisDC->SetTextColor(RGB(0, 0, 0));   //恢复字体色彩为黑色//确定主要图表区域的方块graphRc.left = m_rect.left + marginL;graphRc.top = m_rect.top + marginT;graphRc.right = m_rect.right - marginR - 120 - marginInter;graphRc.bottom = m_rect.bottom - marginB;axisDC->Rectangle(graphRc);//坐标轴int dif = 30;//X 方向CPen pen;pen.CreatePen(PS_DOT, 1, RGB(0, 0, 255));axisDC->SelectObject(pen);int m = graphRc.bottom;int linesCount = 0;for (int i = 1; m > graphRc.top + dif; i++){axisDC->MoveTo(graphRc.left, graphRc.bottom - i * dif);axisDC->LineTo(graphRc.right, graphRc.bottom - i * dif);m = graphRc.bottom - i * dif;linesCount++;}//Y 方向int n = graphRc.left;for (int i = 1; n < graphRc.right - dif; i++){axisDC->MoveTo(graphRc.left + i*dif, graphRc.bottom);axisDC->LineTo(graphRc.left + i*dif, graphRc.top);n = graphRc.left + i*dif;}//初始化坐标原点origin.x = graphRc.left;origin.y = graphRc.bottom;//初始化逻辑坐标远点logOri = xl, yb;//开始绘制点的数据for (int i = 0; i < 8; i++){if (lineData[i].size() == 0){break;}for (int j = 0; j < lineData[i].size(); j++){axisDC->SetPixel(lineData[i][j], colors[i]);  //画的是散点图}}}void  CGraphControl::setGraphTitle(CString str)
{graphTitle = L"TEST GRAPH";
}void CGraphControl::addLine(CString str)
{if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}legs[lineNum++] = str;}void CGraphControl::addLine(CString* arr, int n)
{if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}for (int i = 0; i < n; i++){if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}legs[lineNum++] = arr[i];}
}void CGraphControl::setRange(int ixl, int ixr, int iyl, int iyt)
{xl = ixl;xr = ixr;yb = iyl;yt = iyt;Invalidate();
}void CGraphControl::addLineData(std::vector<CPoint> arr)
{if (lineNum >= 8){MessageBox(L"已达线条最大数量");return;}}
void CGraphControl::getBitmap() //获取可以保存的位图文件
{CFileDialog* fileDlg = new CFileDialog(false);CString str;if (fileDlg->DoModal() == IDH_OK){str = fileDlg->GetFileName();}CImage image;image.Attach(m_axis.operator HBITMAP());image.Save(str);delete fileDlg;
}void CGraphControl::add(CString legName, std::vector<CPoint> line)
{addLine(legName);addLineData(line);transPos(&line, true);
}void CGraphControl::transPos(CPoint *point, bool bIn)  //逻辑坐标,物理坐标转换
{CPoint tmpPoint;memcpy_s(&tmpPoint, sizeof(CPoint), point, sizeof(CPoint));if (bIn)    //逻辑坐标->物理坐标{point->x = (tmpPoint.x - logOri.x) / ratioX + origin.x;point->y = (tmpPoint.y - logOri.y) / ratioY + origin.y;}else   //物理坐标->逻辑坐标{point->x = (tmpPoint.x - logOri.x) * ratioX + logOri.x;point->y = (logOri.y - tmpPoint.y) * ratioY + logOri.y;}}void CGraphControl::transPos(std::vector<CPoint> *arr, bool bIn)//批量转换坐标
{for (int i = 0; i < arr->size(); i++){transPos(&arr[i], bIn);}}

MFC Static控件派生类,实现对函数图像的绘制。相关推荐

  1. 使用CvvImage类在MFC的static控件显示图片

    使用OpenCV的库,可以非常便捷地实现对图像的各种操作.在CTestDlg对话框中放置一个picture static控件,ID为IDC_STATIC,如下函数即可实现显示图片的功能.根据此方法,可 ...

  2. MFC的Button和Static控件

    最近要写一个MFC的对话框程序,发现要把MFC的对话框写的有色彩点并不容易,不像在C#里设置属性指就好,而是要自己去写一些代码完成对话框的绘画操作.比如一个简单的鼠标移入.移出操作,都要自己去写代码. ...

  3. MFC常见控件:滚动条控件

    MFC常见控件:滚动条控件 1. 滚动条控件简介 滚动条大家也很熟悉了,Windows窗口中很多都有滚动条.列表框和组合框设置了相应属性后,如果列表项显示不下也会出现滚动条.滚动条分为水平滚动条(Ho ...

  4. MFC ListBox控件设置字体颜色

    文章目录 描述 需要解决的问题 方案 设置 Item 颜色 鼠标双击事件 调用 Static 控件的背景颜色设置 描述 最近的项目中需要用到 MFC 的列表控件,列表控件中需要动态插入产品不同的测试状 ...

  5. MFC工具箱控件的一些用法

    转自https://blog.csdn.net/qq_34174814/article/details/51419967 控件工具箱: 2 图形控件(picture):常用于显示位图(Bitmap)和 ...

  6. MFC对话框控件成员变量编程熟悉 - 开发一个简单天线长度计算器

    新建一个对话框工程:VC6:VC2010类似:版本不同略有些差别: 新建完如下:对话框默认有三个控件,自己添加的: 右击 确定 按钮,建立类向导:进入类向导: Class name下拉选中对话框类:类 ...

  7. MFC列表控件ListControl和树控件TreeControl

    列表控件 列表相关的类:CListCtrl-父类是CWnd,本质是一个控件: CListView-父类是CView,本质是一个视图.相当于在视图中嵌入了一个CListCtrl控件 列表控件的使用 1. ...

  8. MFC high-speed-charting控件使用(添加垂直游标,两个控件的联动)

    MFC high-speed-charting控件使用(添加垂直游标,两个控件的联动) 应用场景 最近参与的一个项目中涉及到在一个对话框中添加两个high-speed-charting控件,在两个控件 ...

  9. mfc随记:基于vs2010创建MFC ActiveX控件并测试

    一.新建一个空项目 以管理员打开vs2010,选择新建一个mfc activeX控件,填写项目名称和路径,其他无需修改,直接默认一直下一步即可 二. 添加测试方法 在底部tab栏切换到类视图,右键添加 ...

最新文章

  1. 前端必备,JavaScript面试问题及答案
  2. 谷歌浏览器mac_Mac用户浏览网页不可少的浏览器-谷歌Chrome
  3. java面试常见问题
  4. sh: lmstat: 没有那个文件或目录_没有天生的合适,只有磨合出来的感情
  5. 数字统计2(依然是数组下标法)
  6. 蚂蚁金服王旭:开源的意义是把社区往前推进一步
  7. 本地项目怎么推送到码云_【重谈npm】当下载一个项目到本地执行npm install报错时应该怎么办...
  8. C/C++排序算法(2)希尔排序
  9. ASP.NET- 执行SQL超时的解决方案
  10. C#实现文件二进制存储
  11. 9-21 调试javaweb 数据库连接感想
  12. 小米路由器的linux命令,小米路由器pro安装mt工具箱
  13. macOS镜像下载(ISO、DMG)
  14. 云原生日志管理瑞士军刀 Fluent Operator 中文入门教程
  15. DSP 6678 多核CACHE一致性操作
  16. 阵列卡在服务器什么位置,阵列卡是什么
  17. 公司银行考试有C语言程序吗,银行春季校园招聘计算机岗笔试考什么?会考编程吗?...
  18. 关于学习Android的三个终极问题
  19. 高分辨透射电镜(HRTEM)样品怎么制?看这一篇就够了
  20. 人工智能写歌词?看我是如何用Python来C位出道的……

热门文章

  1. 单例模式:静态内部类实现的单例模式是懒加载且线程安全的
  2. Vue绑定Class样式
  3. CentOS如何删除文件夹
  4. PS做球面效果的简单方法
  5. CVE-2020-0108 安卓前台服务特权提升漏洞
  6. 一个蓝牙,一个摄像头,加个震动尾巴,再加点控制模块,可以做个微型机器人了...
  7. CAD对齐的两种方式、AUTOCAD——修改坐标轴方向
  8. iOS性能优化实践:头条抖音如何实现OOM崩溃率下降50%+
  9. IDEA中使用Java语言连接MySQL,实现增、删、查操作
  10. 刀塔传奇火爆简要分析